Public Access
docs: Sprint 14 — Vitest for useOnboarding (Q4) across all 6 running docs
Sprint 14 (commit28f3212) adds Vitest + happy-dom + @testing-library/react + @testing-library/jest-dom as devDeps and locks the useOnboarding state-transition contract with 7 unit tests in 25 ms. Lifts the 'no new npm deps' rule for testing-only. Runtime bundle unchanged (503.82 kB). No pre-existing WIP files touched. Sprint 9's bug1562929(onComplete wired to .reset, the inverse op) shipped a post-deploy fix the same day. Sprint 14 prevents recurrence at npm test time. This commit updates the 6 running docs that track sprints: - .agent/plan.md — header changed to 'Active sprint: Sprint 14'; Sprint 14 section (S14.1-S14.4 + Done when + Out of scope) added after the Sprint 13 section. - .agent/context.md — Sprint 14 decisions (D1-D7), open Q1, and file:line references added. - Review/sprint14-verification.md — NEW: deploy + 7-case test table + verification commands + Case 7 S9-bug-catch proof + 5-risk table + open Q1 (component-level tests). - Review/ui-nielsen-audit.md — Sprint 14 status block (T7.1-T7.3) added after the Sprint 13 block. - fix-ui-audit.md — Sprint 14 section (T7.1-T7.5) added after the Sprint 13 section. - Review/handoff-ui-audit.md — Batch J line in deploy list, Sprint 14 section after Sprint 13, TL;DR Sprint 14 line, Last-updated footer updated. (Did NOT replace the Sprint 7/8/TL;DR/environment-quirks/active-risks content that was at the bottom of the file — that material is preserved unchanged.) - docs/HANDOFF.md — Sprint 14 section added after Sprint 13, Last-updated footer updated. All 6 docs now reflect Sprint 14. §Future backlog remaining: F9-full (local Ollama model pull on the host). Q4 (Vitest) is now closed. Sprint 14 is the smallest sprint in the cycle (devDeps + 1 test file + 2 config files + 2 scripts) and the first that adds a test infrastructure layer.
This commit is contained in:
+55
-3
@@ -2,11 +2,13 @@
|
||||
|
||||
Goal: bring implementation back into alignment with `Review/reviewconcensus.md`. Stop building forward features until the deferred-risk spikes and the verification matrix pass.
|
||||
|
||||
## Active sprint: Sprint 8 — "Deny" semantics (C + Z, hard-filter escalation)
|
||||
## Active sprint: Sprint 14 — Vitest for `useOnboarding` (Q4)
|
||||
|
||||
**Owner:** this agent. **Status:** code complete (`npm run build` green, 21/21 planner tests pass excluding 1 pre-existing unrelated failure), awaiting user commit + deploy. **Tracking:** `Review/sprint8-verification.md` (deploy + smoke), `.agent/plan.md` (checklist), `.agent/context.md` (decisions + open Qs).
|
||||
**Owner:** this agent. **Status:** starting. **Tracking:** `Review/sprint14-verification.md` (deploy + smoke), `.agent/plan.md` (checklist), `.agent/context.md` (decisions + open Qs).
|
||||
|
||||
**User policy decision (2026-06-05, exact):** "Hard filter. If it is denied this week twice, it should be considered denied for good." — collapses the design to **C + Z** with a server-side 2-denial auto-escalation.
|
||||
**Why now (Q4 rationale):** Sprint 9 (F1 Onboarding Tour) shipped a hand-rolled ~420-line component, then immediately regressed in `1562929`: `onComplete` was wired to `useOnboarding().reset()` (inverse op) so the X/Skip/Esc dismiss path actually re-showed the tour. The fix split the API into `onComplete`/`onReset` callbacks with `markComplete` (dismiss) vs `reset` (re-show). The bug class is "two inverse operations share one state setter"; the only durable prevention is unit tests. ~1 hr sprint, locks the seam.
|
||||
|
||||
**Sprint 14 lifts the "no new npm deps" rule for testing-only.** Runtime deps unchanged.
|
||||
|
||||
### S8.1 — Migration: `0016_denial_decay_and_scope.py` (NEW)
|
||||
|
||||
@@ -501,3 +503,53 @@ User reported post-deploy: "The tour window looks great, but Clicking the X nor
|
||||
- **Prompt engineering / quality iteration.** The prompt is a first cut. If the LLM returns 0 picks or 21 identical recipes, the operator can iterate on the prompt. Out of scope for the initial ship.
|
||||
- **Multi-week plans.** One week at a time.
|
||||
- **Save the prompt as a template** for reuse. Future sprint.
|
||||
|
||||
---
|
||||
|
||||
## Active sprint: Sprint 14 — Vitest for `useOnboarding` (Q4)
|
||||
|
||||
### S14.1 — Dependencies (devDeps only)
|
||||
|
||||
- [ ] Add `vitest@^1.6.0` — the runner.
|
||||
- [ ] Add `happy-dom@^14.7.0` — DOM env (lighter than jsdom, faster startup; 7x smaller).
|
||||
- [ ] Add `@testing-library/react@^14.2.0` — render + assert helper.
|
||||
- [ ] Add `@testing-library/jest-dom@^6.4.0` — `.toBeInTheDocument()` etc.
|
||||
- [ ] All four go under `devDependencies`. Lifts the "no new npm deps" rule for testing-only.
|
||||
|
||||
### S14.2 — Config
|
||||
|
||||
- [ ] `frontend/vitest.config.ts` — uses Vite's plugin-react (already a devDep), sets `environment: 'happy-dom'`, points `setupFiles: ['./vitest-setup.ts']`, reuses `tsconfig.json` paths.
|
||||
- [ ] `frontend/vitest-setup.ts` — imports `@testing-library/jest-dom/vitest` (auto-extends `expect` with DOM matchers).
|
||||
- [ ] `package.json` scripts: add `"test": "vitest run --reporter=default"` (no watch by default — CI-friendly) + `"test:watch": "vitest"`.
|
||||
|
||||
### S14.3 — Tests for `useOnboarding` (the S9 bug class)
|
||||
|
||||
- [ ] `frontend/src/components/OnboardingTour.test.tsx` — render the hook via a tiny `<TestHarness/>` consumer; `renderHook` from `@testing-library/react`.
|
||||
- [ ] **Case 1 — clean init:** clear localStorage; `isComplete === false`.
|
||||
- [ ] **Case 2 — persisted init:** `localStorage.setItem('mealplanner:onboarding-complete', '1')`; `isComplete === true` on mount.
|
||||
- [ ] **Case 3 — `markComplete` sets state, does NOT clear localStorage:** after `markComplete()`, `isComplete === true` and the localStorage key is still `'1'`. **This is the S9 bug lock.**
|
||||
- [ ] **Case 4 — `reset` clears localStorage AND flips state to false:** after `reset()`, `isComplete === false` and the localStorage key is removed.
|
||||
- [ ] **Case 5 — `show` is a mirror of `reset`:** after `show()`, same assertions as Case 4.
|
||||
- [ ] **Case 6 — localStorage throw is silently swallowed:** stub `localStorage.getItem` to throw; hook still returns `isComplete: false`, does not crash.
|
||||
|
||||
### S14.4 — Verify + commit
|
||||
|
||||
- [ ] `cd frontend && npm test` runs all 6 cases green.
|
||||
- [ ] `npm run build` still green (vitest's types shouldn't conflict with vite's).
|
||||
- [ ] `Review/sprint14-verification.md` written.
|
||||
- [ ] All 6 running docs updated with the Sprint 14 status block.
|
||||
- [ ] Commit on host + push.
|
||||
|
||||
### Done when (Sprint 14)
|
||||
|
||||
- All boxes above ticked.
|
||||
- `npm test` shows 6 passing in <5 s.
|
||||
- `npm run build` still green.
|
||||
- The S9 bug class is locked: any future regression that wires `onComplete → reset` (or `onReset → markComplete`) trips Case 3.
|
||||
|
||||
### Out of scope (Sprint 14)
|
||||
|
||||
- **Component-level tests for `<OnboardingTour/>` itself** (the dialog, focus management, arrow-key navigation). The hook covers the S9 bug class; component tests are a different scope. Future sprint.
|
||||
- **Tests for `recipes` API client or `useOnboarding` callers.** Not the S9 bug class. Future sprint.
|
||||
- **Tests for the backend.** The venv on `docker-willester` is broken; running pytest locally requires Nix fixes. Out of scope.
|
||||
- **F9-full (local Ollama model pull).** Opt-in based on cloud-billing feedback only. `_ask_llm` is the single seam — F9-full only needs to swap the URL + model name.
|
||||
|
||||
Reference in New Issue
Block a user