MemberJunction / MemberJunction/MJ

Records preview tabs: the edit-mode guard that prevents silent edit loss has no test

Open
#4,344 0 comments 0 reactions 1 assignee Claimed by @MattC-BC View on GitHub
chore priority: medium
Dominant language
TSQL
Stars
29
Forks
6
Avg merge
2d 1h
Merged PRs (30d)
323

Description

## What

The records-region preview-tab model added in #4154 guarantees that **a record whose form is in edit mode is never silently replaced**. That guarantee is implemented and works, but it is the only major behavior in that PR without a test.

## Why it matters

The failure mode is silent and destructive: replacement destroys the pane, so if the guard stops working a user's in-progress edit disappears with no error and no prompt.

The guard is a lambda composed in the shell:

```ts
// packages/Angular/Explorer/explorer-core/src/lib/shell/shell.component.ts (resolveRecordOpenStyle)
this.workspaceManager.RecordsRegionTabFilter = this.resolvedRecordOpenStyle === 'records'
? (tab) => IsRecordsRegionTab(tab.configuration) && !this.tabContainerRef?.IsRecordTabEditing(tab.id)
: null;
```

The `base-application` pool tests inject their own filter, so they cover the manager generically and never exercise this composition. Drop the `&& !this.tabContainerRef?.IsRecordTabEditing(tab.id)` clause in a future refactor and **every existing test still passes** while edits start vanishing.

## The chain a test should pin

Verified working end to end today:

1. `componentRefs` is one map keyed by tab id, populated in `loadTabContent`, which the records path calls too — so record tabs are in it.
2. The instance is `EntityRecordResource`, which overrides `IsEditing()` and holds `@ViewChild(SingleRecordComponent)`.
3. `SingleRecordComponent` holds `@ViewChild(MjEntityFormHostComponent)` and reads `Form.EditMode`.
4. `MjEntityFormHostComponent` renders unconditionally in the template, so both view children resolve.

## Suggested coverage

- An editing record tab is **not** in the records consumption pool, so the next plain open creates a new tab rather than replacing it.
- The same tab **is** in the pool once editing ends.
- `IsRecordTabEditing` returns `false` for an unknown or unloaded tab id — the documented fail-safe ("nothing is rendered, so there is nothing to lose").

Found while reviewing #4154. Not a defect in that PR; the behavior is correct as shipped.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.