fix(test-harness): restore promisify(exec) + unblock CLI introspection probes

The vitest child-process guard wrapped exec/execFile without preserving the
`[util.promisify.custom]` symbol, so awaited `execAsync` resolved to a raw
stdout string instead of `{stdout, stderr}`. That single regression cascaded
through ~60 "failing" tests across cli, core, engine, and dashboard whose
production code was actually correct. Also relax the AI-CLI blocklist for
cheap introspection (--version/--help/which …), give SIGTERM'd subprocesses a
brief grace period before being flagged as "left running", fix a few real
test-side bugs uncovered along the way (executor mock step transitions, iOS
last-resort keyboard path, mission SSE replay tests racing with the real AI
agent), and convert dashboard route tests' dynamic `await import("../server.js")`
to static imports so first-test timings drop from 2–5s to <200ms.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-30 17:40:14 -07:00
parent 491097cd66
commit 21402a3c1a
18 changed files with 238 additions and 60 deletions

View File

@@ -0,0 +1,13 @@
---
"@runfusion/fusion": patch
---
Fix vitest test-harness regressions that masked correct production code as failing tests:
- Restore `util.promisify(exec)`/`util.promisify(execFile)` to resolve with `{stdout, stderr}` inside the test child-process guard. The previous wrapper dropped the `[util.promisify.custom]` symbol, so awaited `execAsync` resolved to a raw stdout string and broke any test or runtime path that destructured the result (cli `init` git commit flow, core git-remote project-name detection, engine cron-runner / restart / worktree-pool clusters, etc.).
- Allow cheap CLI introspection invocations (`--version`, `--help`, `which …`) through the AI-CLI block so the dashboard's claude availability probe can tell the truth about the local system. Session-launching invocations (e.g. `claude -p …`, `droid chat`) still throw.
- Give SIGTERM'd subprocesses a short grace period in the per-test guard's `afterEach` before flagging them as "left running", fixing a race where production code that correctly killed the child was reported as leaking it.
- Add a test-only `__registerMissionInterviewSessionForTest` helper so SSE replay/buffer tests can exercise the stream manager without spinning up a real AI agent.
- Fix executor mock to simulate real step-transition semantics (forward moves persist; in-progress regressions on done/skipped steps get rejected) so the new `persistedStatus`-aware response text in `fn_task_update` is exercised correctly.
- Fix the iOS last-resort path test in `useMobileKeyboard` to actually reach the `gap < 16 && viewportShrink ≥ 16` branch by setting `vv.offsetTop > 0`.
- Convert `await import("../server.js")` in 14 dashboard route tests to static imports so first-test latency in those files drops from ~25s to <200ms.