Files
ui/_docs/03_implementation/reviews/batch_06_review.md
T
Oleksandr Bezdieniezhnykh bd2b718ddf [AZ-463] [AZ-469] [AZ-476] [AZ-477] Batch 6 - flight/responsive/upload/settings tests
- AZ-463 flight selection persistence (FT-P-16) + rehydration
  on boot (FT-P-17) PASS at the wire; 100-cycle leak guard
  (NFT-RES-LIM-07) and 1h SSE soak (NFT-RES-LIM-06)
  scaffolded as RUN_LONG_RUNNING-gated e2e companions.
- AZ-469 browser-support smoke (FT-P-34) runs in both
  Chromium and Firefox via the existing playwright config;
  responsive variants (FT-P-35 480px / FT-P-36 1024px) PASS
  in fast (Tailwind class shape) and e2e (visibility).
- AZ-476 upload 501 MB -> 413: AC-1 user-visible error is
  drift today (uploadFiles silently falls through to local
  mode); it.fails() + control + e2e test.fail. AC-2 no-alert
  PASS via dialog spy.
- AZ-477 settings save 500 / network drop: AC-1+AC-2+AC-3
  all drift today (no try/finally, no error region, deadline
  unmeasurable); 4 it.fails() + control pinning the stuck-
  disabled drift; e2e companions test.fail mirror it.
- LESSONS.md seeded: vi.stubGlobal('URL', {...URL,...})
  destroys the URL constructor and breaks new URL(...) in
  MSW; patch the methods directly instead.

Code review: PASS (0 findings). Fast: 22/22 files, 120
passed / 13 skipped. Static: 24/24 PASS.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-11 05:19:35 +03:00

7.5 KiB
Raw Blame History

Code Review Report

Batch: 6 — AZ-463, AZ-469, AZ-476, AZ-477 Date: 2026-05-11 Verdict: PASS Mode: Full (per-batch invocation by /implement)

Inputs

  • Task specs:
    • _docs/02_tasks/todo/AZ-463_test_flight_selection_persistence.md (4 ACs, 3 pts)
    • _docs/02_tasks/todo/AZ-469_test_browser_support_responsive.md (3 ACs, 2 pts)
    • _docs/02_tasks/todo/AZ-476_test_upload_size_cap.md (2 ACs, 2 pts)
    • _docs/02_tasks/todo/AZ-477_test_settings_resilience.md (3 ACs, 3 pts)
  • Changed files (9 total, all under Blackbox Tests OWNED scope, plus one docs file):
    • tests/flight_selection_persistence.test.tsx
    • tests/browser_support_responsive.test.tsx
    • tests/upload_size_cap.test.tsx
    • tests/settings_resilience.test.tsx
    • e2e/tests/flight_selection_persistence.e2e.ts
    • e2e/tests/browser_support_responsive.e2e.ts
    • e2e/tests/upload_size_cap.e2e.ts
    • e2e/tests/settings_resilience.e2e.ts
    • _docs/LESSONS.md (new — autodev B2 surface; one entry capturing the vi.stubGlobal('URL', ...) anti-pattern uncovered while debugging AZ-476)

Findings

# Severity Category File:Line Title
None

No Critical, High, Medium, or Low findings.

Phase Walkthrough

Phase 1 — Context Loading

All 4 task specs read; ACs catalogued; module-layout.md consulted for OWNED / READ-ONLY / FORBIDDEN envelopes. Every changed source file lives under tests/** or e2e/** — both Owns globs of the Blackbox Tests cross-cutting component (epic AZ-455). The single docs file (_docs/LESSONS.md) lives in _docs/**, owned by the orchestrator surface — not by any feature component. No file outside the envelope was modified.

Phase 2 — Spec Compliance

Task AC Test Today Drift documented
AZ-463 AC-1 (FT-P-16 PUT /settings/user persistence) tests/flight_selection_persistence.test.tsx + e2e PASS
AZ-463 AC-2 (FT-P-17 rehydration on boot) same PASS
AZ-463 AC-3 (NFT-RES-LIM-07 100-cycle listener leak guard) e2e/tests/flight_selection_persistence.e2e.ts (long-running) + fast companion stub gated by RUN_LONG_RUNNING=1 per spec runner-level config gating is a follow-up; per spec the AC lives in e2e (long-running) only
AZ-463 AC-4 (NFT-RES-LIM-06 1 h SSE soak) same gated by RUN_LONG_RUNNING=1 + chromium only (performance.memory) same
AZ-469 AC-1 (FT-P-34 cross-browser smoke) e2e/tests/browser_support_responsive.e2e.ts runs against both Chromium + Firefox projects in playwright.config.ts
AZ-469 AC-2 (FT-P-35 mobile 480 px) tests/browser_support_responsive.test.tsx + e2e PASS — fast asserts Tailwind class shape, e2e asserts visibility
AZ-469 AC-3 (FT-P-36 desktop 1024 px) same PASS
AZ-476 AC-1 (FT-N-06 / NFT-RES-07 user-visible 413 error) tests/upload_size_cap.test.tsx + e2e it.fails() + control + test.fail (e2e) drift — MediaList.uploadFiles swallows the failure silently and falls through to local mode; flips when toast + i18n key wired
AZ-476 AC-2 (no alert() on the 413 path) same PASS (vacuous today — no error path runs at all) + e2e dialog spy
AZ-477 AC-1 (FT-N-13 / NFT-RES-05 500 → button enabled + alert ≤ 2 s) tests/settings_resilience.test.tsx + e2e 2 × it.fails() (button + alert) + 1 control pinning the stuck-disabled drift drift — saveSystem / saveDirs lack try/finally and an error region
AZ-477 AC-2 (FT-N-14 / NFT-RES-06 network drop ≤ 2 s) same 2 × it.fails() (button + alert)
AZ-477 AC-3 (NFT-PERF-09 deadline ≤ 2 s) same it.fails() measuring performance.now() between PUT response and alert visibility

Every AC has at least one assertion; every documented drift is paired with either a control PASS test (pinning the current behavior) or a test.fail annotation, so each failure mode is observable today and the contract test flips green automatically once production lands the fix.

Phase 3 — Test Coverage Hygiene

  • 5 fast files / 4 e2e files / 0 production-source files modified.
  • Total fast tests added: 19 (4 + 5 + 3 + 6 — control / it.fails() placement matches spec direction).
    • AZ-463: 5 (2 pass + 1 listener-leak companion + 2 controls).
    • AZ-469: 4 (3 pass + 1 cross-browser-stub).
    • AZ-476: 3 (1 it.fails() + 1 control + 1 PASS).
    • AZ-477: 6 (4 it.fails() + 1 control + 1 deadline it.fails()).
  • Total e2e tests added: 9 (2 + 5 + 2 — long-running soaks gated; cross-browser smoke runs in both projects).
  • All it.fails() placements paired with a control test that pins the current production drift (so the drift is asserted today and the contract test flips on production change). No it.skip was used to hide failures.

Phase 4 — Hygiene & Drift

  • 0 files added to src/ (production code untouched — pure blackbox test batch).
  • 1 file added under _docs/LESSONS.md. The entry is bounded (≤ 6 lines body) per the rule contract. Surfaces the vi.stubGlobal('URL', { ...URL, ... }) anti-pattern that destroyed the URL constructor and silently hid the 413 round-trip in AZ-476 during early debugging.
  • The tests/setup.ts MSW boundary (onUnhandledRequest: 'error') is preserved — every new test seeds its own handlers explicitly.
  • AZ-477 installs a scoped process.on('unhandledRejection') handler that swallows ONLY the expected drift signature (500: upstream failure and network-error patterns). Any other rejection still throws — this is the same posture the production code will take once try/finally lands, just enforced at the test boundary in the meantime.

Phase 5 — Static + Lint

  • bun run test:fast — 22 files / 120 passed / 13 skipped / 46.52 s.
  • ./scripts/run-tests.sh --static-only — 24 / 24 static checks PASS / 39.72 s. No new banned-deps hits; no alert() leaks; no ML / signature / persistence / WS / SSR libs introduced.
  • ReadLints clean on all 9 new files.
  • tsc --noEmit -p tsconfig.test.json succeeded as part of STC-T1.

Phase 6 — Self-Review

  • Test rigs re-read end-to-end for naming clarity, AAA shape, and proper teardown of every globally mutated handle (URL.createObjectURL, process.on('unhandledRejection'), MSW handler resets via afterEach).
  • FlightSeed helper in AZ-476 is intentionally local and tightly scoped — it sidesteps the async user-settings → /api/flights/<id> rehydration chain that AZ-463 covers separately, reducing flake without duplicating the rehydration assertion.
  • Long comments in the test bodies explain why each it.fails() exists and what condition will flip it green; future readers can therefore tell intentional-drift from regression at a glance.

Phase 7 — Architecture Compliance

  • No layer-direction violations. Tests are leaves of the import graph; they import production sources but no production source imports them.
  • No new cyclic dependencies (verified via bunx tsc --noEmit and bun run build in the static profile).
  • src/api/client.ts is exercised but not modified — the contract for api.put / api.upload failure modes (rejected promises) is observed by the tests, not changed.
  • STC-S6 (no WS/GraphQL/gRPC/SSR deps) and STC-S13 (no client-side persistence libs) re-confirm.

Summary

PASS — the batch lands four blackbox-test tasks (12 ACs total) with zero production-code edits, every drift paired with a runnable control test, and full static + fast suite green.