Files
fusion/packages/dashboard/app/components
gsxdsm aca25494a5 test(dashboard): App.test.tsx is fully green — an incomplete mock was crashing NewTaskModal (#2846)
Closes #2829. `App.test.tsx` has been red since **2026-07-25**; #2833
took it 10 failures → 2, and this takes it to **0**.

## The cause, and it was not what I guessed

`vi.mock("../../hooks/useViewportMode")` did not export
`isShortViewport`, which `NewTaskModal` imports.

An incomplete module mock **does not fail at the mock**. It throws
inside whichever component imports the missing export, and the nearest
`ErrorBoundary` swallows that into *"This section encountered an error"*
— so the test failed on a **missing heading** with a DOM that looks
perfectly healthy. Structurally the same presentation as the
workflow-skeleton bug in #2833: the real failure sits two layers below
what the assertion reports.

Both remaining tests had this one cause.

## Found by probing, not theorising

I had already been wrong twice on this file (`renders nothing`, then
i18n), and my standing note said the modal was "plausibly FN-8620's
FloatingWindow rework, **unverified**". That would have been a third
wrong guess. Instead I dumped what was actually in the DOM at the
assertion point:

```
headings: ["Fusion"] | dialogs: 0
newtask-ish: [..., "error-boundary error-boundary--modal"]
```

The `error-boundary--modal` class was the entire answer; reading its
text gave the exact missing export. Same technique that cracked #2833 in
one shot — the difference between the two halves of this investigation
is that I stopped guessing.

**App.test.tsx: 141 passed (141).**

## Also patched, and one deliberately not

- **`Header.mobile-project-favorites.test.tsx`** mocks the same module
with an inline factory and lacks the export. It is **latent, not
broken** — its component does not import `isShortViewport` yet, and the
day it does, the failure would be this same swallowed crash. One line.
- **`FloatingWindow.touch-geometry.test.tsx`** greps as missing but is
**not** — it uses `{ ...(await vi.importActual(...)) }`, so its surface
is complete by construction. My grep-based classification was a false
positive.

That spread is the pattern that prevents this class outright, and it is
the better fix **where it is available**. It is not available here:
App.test.tsx's mock exists precisely so tests need no
`window.matchMedia` in jsdom, and spreading the real module would
reintroduce that dependency for every unstubbed export. So the scoped
one-line stub is the right fix for this file, and the spread is the
recommendation for new mocks.

A guard asserting "a module mock exports everything the real module
does" would close this class repo-wide. I did not build it — 34 files
mock this module and only one was genuinely wrong, so the population
does not yet justify another instrument, by the same measure-first rule
that killed two other candidate gates this week.

## Verification

App.test.tsx 141/141 · the two touched siblings 9/9 · `tsc` 0 · lint 0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-30 15:07:45 -07:00
..
2026-06-27 23:37:24 -07:00