koala73 / koala73/worldmonitor
test(panel-layout): no DOM harness for PanelLayoutManager — tab-cap wiring is still guarded by source greps
- Dominant language
- TypeScript
- Stars
- 86.6k
- Forks
- 13.1k
- Avg merge
- 8h 4m
- Merged PRs (30d)
- 825
Description
Surfaced during the #5813 review. Non-blocking — nothing here is a defect.
## What
`tests/tab-cap.test.mts`'s `tab-cap wiring` block guards three real guarantees with `assert.match` over `src/app/panel-layout.ts` SOURCE TEXT:
- `addTab` resolves the cap and returns before creating anything (greps for `updateTabCapLock()`, `if (!verdict.allowed)`, `showAddLockNotice()`, `trackGateHit('dashboard-tab')`)
- `addTab` never prunes or trims existing tabs (asserts `splice(` / `.slice(0,` / `.pop()` / `.shift()` are absent from the body)
- the cap re-evaluates on BOTH auth and entitlement emissions (greps the `subscribeAuthState` / `onSnapshot` / `onEntitlementChange` wiring)
This is the source-regex wiring-guard shape the repo has been burned by before — see `docs/solutions/logic-errors/playback-control-gated-on-a-clerk-role-field-with-no-writer.md`, where a grep for `evaluatePlaybackGate` would have gone green with the original bug fully in place. A grep proves a name exists in a file; it never drives the decision.
## Why it wasn't fixed in #5813
Replacing them needs a live `PanelLayoutManager`. Nothing mounts one today — the four tests that reference the class all read its source as text. The constructor pulls 49 imports and runs `handleCheckoutReturn()` plus `ProActivationController` on the way up, so standing one up in happy-dom is a harness project in its own right, not a line-item inside a module-move PR.
#5813 did remove the greps it could legitimately remove: the allowance-forwarding pair (replaced by the behavioural `tests/dom/gate-reader-forwarding.test.mts`) and two `PanelTabBar` greps that `tests/dom/panel-tab-bar-lock-notice.test.mts` already covered more strongly.
## Proposed shape
Build a `tests/dom/` harness that constructs `PanelLayoutManager` against a minimal `AppContext` with the boot-time side effects stubbed (`handleCheckoutReturn`, `ProActivationController`, `saveTabsState`, `showToast`), then assert behaviourally:
- a blocked `addTab()` leaves `tabsState.tabs` byte-identical and fires `trackGateHit('dashboard-tab')` exactly once
- an allowed `addTab()` appends exactly one tab and never reorders or drops an existing one
- emitting auth-only, then entitlement-only, each re-runs the cap (the auth-only-subscription bug this guard was written for)
Delete the three greps once the harness covers them. Do not re-point them at a new path if the code moves.
## Trigger
Worth doing when `panel-layout.ts` next needs real behavioural coverage for another reason — the harness is the expensive part and should be amortised, not built for these three assertions alone.
Contributor guide
Research direction
Start with src/app/panel-layout.ts and the tab-cap wiring block in tests/tab-cap.test.mts; compare the existing DOM tests in tests/dom/ for harness patterns. Build the minimal PanelLayoutManager harness with the listed side effects stubbed, then verify blocked, allowed, auth-only, and entitlement-only behaviors. Done means the three source greps are deleted and these behavioral assertions pass.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, testing-qa
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100