From d481fc8126bfcea34cd10ff3a8d74e6435bb51be Mon Sep 17 00:00:00 2001 From: Daniel Bedeleanu Date: Sat, 18 Apr 2026 17:24:58 +0000 Subject: [PATCH] docs: create phase 2 frontend tests design specification --- ...026-04-18-phase-2-frontend-tests-design.md | 536 ++++++++++++++++++ 1 file changed, 536 insertions(+) create mode 100644 docs/superpowers/specs/2026-04-18-phase-2-frontend-tests-design.md diff --git a/docs/superpowers/specs/2026-04-18-phase-2-frontend-tests-design.md b/docs/superpowers/specs/2026-04-18-phase-2-frontend-tests-design.md new file mode 100644 index 00000000..3ab8fec1 --- /dev/null +++ b/docs/superpowers/specs/2026-04-18-phase-2-frontend-tests-design.md @@ -0,0 +1,536 @@ +# Phase 2 Frontend Tests Design Specification + +**Date:** 2026-04-18 +**Status:** APPROVED +**Target:** 80%+ coverage for frontend components, hooks, utilities +**Branch:** `refactor/ai-friendly` +**Reference:** Phase 1 Backend Tests (TDD pattern, subagent-driven execution) + +--- + +## 1. Overview + +Phase 2 creates a comprehensive Vitest test suite for the aInventory frontend, mirroring the TDD approach and execution patterns from Phase 1 (backend tests). The goal is to establish 80%+ coverage across 9 test files: 4 component suites, 3 utility/hook suites, and 2 integration workflows. + +**Key Alignment with Phase 1:** +- Test infrastructure first (setup.ts ≈ conftest.py) +- Balanced unit + integration testing +- Shared fixtures to avoid duplication +- Subagent-driven execution (batches of 2-3 files) +- Git tags for phase completion & rollback + +--- + +## 2. Test Architecture & Setup + +### 2.1 File Structure + +``` +frontend/tests/ +├── setup.ts # Vitest config, shared mocks, fixtures +├── components/ +│ ├── Scanner.test.tsx # QR scan + OCR matching +│ ├── AIOnboarding.test.tsx # AI extraction wizard +│ ├── AdminOverlay.test.tsx # Admin config UI +│ └── IdentityCheckOverlay.test.tsx # Login form +├── hooks/ +│ └── useAdmin.test.ts # Admin state hook +├── lib/ +│ ├── api.test.ts # Axios + retry logic +│ └── labels.test.ts # SVG/QR generation +└── integration/ + ├── scanner-workflow.test.tsx # Scan → match → adjust + └── inventory-workflow.test.tsx # View → filter → create → sync +``` + +### 2.2 Setup.ts (Shared Fixtures & Mocks) + +**Purpose:** Centralized Vitest configuration and reusable mock fixtures (analogous to Phase 1's conftest.py) + +**Contents:** +1. **Vitest globals** — enable `describe`, `it`, `expect` without imports +2. **vi.mock() calls** for: + - `axios` — stub GET/POST/PUT with fixed responses + - `dexie` — in-memory IndexedDB replacement + - `html5-qrcode` — stub camera access (requestPermission, scan) + - `next/router` — stub Next.js routing +3. **Shared fixtures:** + - Mock user token (valid + invalid variants) + - Mock item list response (5 items with various states) + - Mock AI extraction response (Gemini + Claude formats) + - Mock offline sync queue +4. **Cleanup:** Reset mocks before each test + +**Philosophy:** +- Same fixtures reused across all 9 test files +- Test-specific overrides allowed (e.g., `vi.spyOn(axios, 'post').mockReturnValue(...)`) +- Reduces boilerplate, ensures consistency + +### 2.3 Vitest Configuration (vitest.config.ts) + +**Setup:** +```typescript +import { defineConfig } from 'vitest/config' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + test: { + globals: true, + environment: 'jsdom', + setupFiles: ['./tests/setup.ts'], + coverage: { + provider: 'v8', + reporter: ['text', 'html'], + all: true, + lines: 80, + functions: 80, + branches: 80, + statements: 80, + }, + }, +}) +``` + +**Key Settings:** +- `environment: 'jsdom'` — simulate browser for React components +- `setupFiles` — load shared mocks before tests +- Coverage thresholds: **80%+ across all metrics** (lines, functions, branches, statements) + +### 2.4 Package.json Updates + +**Add dependencies:** +```json +{ + "devDependencies": { + "vitest": "^1.0.0", + "@vitest/ui": "^1.0.0", + "@testing-library/react": "^14.0.0", + "@testing-library/user-event": "^14.0.0", + "@testing-library/jest-dom": "^6.0.0", + "@vitejs/plugin-react": "^4.0.0", + "jsdom": "^23.0.0" + } +} +``` + +**Test scripts:** +```json +{ + "scripts": { + "test": "vitest", + "test:ui": "vitest --ui", + "test:coverage": "vitest run --coverage" + } +} +``` + +--- + +## 3. Component Tests (4 Files) + +### 3.1 Scanner.test.tsx + +**What it tests:** +- Viewport rendering (video element, canvas overlay) +- Zoom controls (1x → 2x → max cycle) +- OCR matching engine (scoring, threshold logic) +- Camera permission flows +- State updates on scan result + +**Test Types:** +- **Unit:** Zoom logic, matching score calculation, error handling +- **Integration:** Real component tree, mocked camera, verify state callbacks + +**Coverage Targets:** +- Render paths: initial + error states +- Zoom cycle: all 4 states (1x, 2x, max/2, max) +- Matching: exact match (500pts), partial (200pts), token (50pts), category (20pts), threshold (40pts) +- Callbacks: onScanResult, onError + +**Key Mocks:** +- `html5-qrcode` — stub camera access, return fixed QR/barcode string +- Component props — onScanResult callback verification + +--- + +### 3.2 AIOnboarding.test.tsx + +**What it tests:** +- Step progression (image capture → extraction → confirmation) +- Image preprocessing (validation, resize, crop, filter) +- AI response formatting (Gemini vs Claude) +- User validation of extracted data +- Form submission + +**Test Types:** +- **Unit:** Step validation, data transformation, error messages +- **Integration:** Full wizard flow, mocked AI response, verify final submit + +**Coverage Targets:** +- Step transitions: capture → extraction → confirm → done +- Image validation: size, format, EXIF handling +- AI response parsing: field mapping, confidence scores +- User override: edited fields on confirmation step +- Submit: API call with validated data + +**Key Mocks:** +- `axios.post('/ai/extract')` — return mock Gemini/Claude response +- Canvas API — image preprocessing simulation + +--- + +### 3.3 AdminOverlay.test.tsx + +**What it tests:** +- Tab rendering (Identity, Database, LDAP, AI, Categories) +- Form field validation (required, format, length) +- Form submission with mocked API +- Error message display +- Loading states + +**Test Types:** +- **Unit:** Field validation, error rendering, tab switching +- **Integration:** Full form submission, mock API response, state update + +**Coverage Targets:** +- Tab rendering: all 5 tabs present and switchable +- Form validation: required fields, format validation, error messages +- Submission: API call with payload, success/error handling +- Loading state: button disabled, spinner visible during submission + +**Key Mocks:** +- `axios.put('/admin/config')` — mock successful + error responses +- Form fields — controlled component rendering + +--- + +### 3.4 IdentityCheckOverlay.test.tsx + +**What it tests:** +- Login form rendering (username, password, login button) +- Form validation (required fields) +- LDAP authentication flow +- Local password authentication fallback +- Token storage and success callback + +**Test Types:** +- **Unit:** Form validation, error handling +- **Integration:** Login flow, mocked auth endpoint, token storage + +**Coverage Targets:** +- Form fields: username + password required +- Validation: empty field errors +- LDAP login: POST to `/auth/login` with credentials +- Success: token stored, onLoginSuccess callback fired +- Error: error message displayed, form remains editable + +**Key Mocks:** +- `axios.post('/auth/login')` — mock LDAP response with JWT token +- localStorage — in-memory token storage + +--- + +## 4. Hook & Utility Tests (3 Files) + +### 4.1 useAdmin.test.ts + +**What it tests:** +- Hook initialization (load config from API) +- State updates (identity, DB, LDAP, AI, categories) +- Validation before submission +- Error handling and retry logic + +**Test Types:** +- **Unit:** State mutations, validation logic +- **Integration:** API calls (mocked), state persistence + +**Coverage Targets:** +- Initialization: load admin config on mount +- State updates: each config section (identity, LDAP, AI, etc.) +- Validation: required fields, format checks +- Submission: API call with validated payload +- Error states: network failure, validation error, server error + +**Key Mocks:** +- `axios.get('/admin/config')` — return mock config object +- `axios.put('/admin/config')` — mock success + error responses + +--- + +### 4.2 api.test.ts + +**What it tests:** +- Axios instance configuration (base URL, headers, auth) +- Request construction (query params, body, headers) +- Retry logic for network failures +- Response parsing and error mapping +- Token refresh on 401 + +**Test Types:** +- **Unit:** Request building, error mapping, retry logic +- **Integration:** Mocked axios, verify request/response flow + +**Coverage Targets:** +- Auth headers: JWT token in Authorization header +- Request types: GET, POST, PUT, DELETE +- Query params: proper URL encoding +- Retry: exponential backoff on network error +- Error mapping: HTTP status → human-readable error message +- Token refresh: 401 triggers new login flow + +**Key Mocks:** +- `axios` — intercept requests, mock responses + +--- + +### 4.3 labels.test.ts + +**What it tests:** +- SVG Code 128 barcode generation +- SVG QR code generation (no external library) +- Canvas-to-PNG rasterization (browser export) +- Label dimension validation (62mm x 29mm) + +**Test Types:** +- **Unit:** SVG encoding, QR structure validation +- **Integration:** Canvas API, image export + +**Coverage Targets:** +- Code 128 encoding: valid barcode structure +- QR generation: valid QR format +- SVG output: valid XML structure, correct dimensions +- Canvas export: PNG blob generation +- Error handling: invalid input, encoding errors + +**Key Mocks:** +- Canvas API — stub createImageData, getContext + +--- + +## 5. Integration Tests (2 Files) + +### 5.1 scanner-workflow.test.tsx + +**What it tests:** +- End-to-end: Scan QR/barcode → OCR match → select item → stock adjustment +- Real component tree: Scanner + ItemList + StockAdjustmentForm +- Mocked: html5-qrcode, axios (item API, stock update API) + +**User Journey:** +1. Scanner displays, user clicks "Scan" +2. html5-qrcode stub returns barcode string +3. Matching engine finds item (exact or partial match) +4. Item details displayed in form +5. User adjusts quantity, clicks "Check In" +6. API updates stock, success message shown + +**Coverage Targets:** +- Scan trigger → match → form population +- User interaction: quantity adjustment, submission +- API integration: stock update call +- Error handling: no match found, network error + +**Key Mocks:** +- `html5-qrcode` — return fixed barcode on scan +- `axios.get('/items')` — return mock item list +- `axios.post('/operations/checkin')` — mock success response + +--- + +### 5.2 inventory-workflow.test.tsx + +**What it tests:** +- End-to-end: View inventory → filter/sort → create new item → offline sync +- Real component tree: Dashboard + ItemTable + CreateItemModal + SyncStatus +- Mocked: axios (all API calls), Dexie (IndexedDB for offline queue) + +**User Journey:** +1. Dashboard loads, displays item list from API +2. User filters by category, sorts by quantity +3. User clicks "Create Item", fills form, submits +4. Network goes offline (axios fails) +5. Item queued in IndexedDB (offline sync) +6. Network comes back online +7. Sync button triggers, offline items sent to backend +8. Item list updates + +**Coverage Targets:** +- Data loading: initial list from API +- Filter/sort: UI updates, no API call +- Create item: form submission, success message +- Offline queue: Dexie stores pending items +- Sync: batch API call for offline items, success/error handling + +**Key Mocks:** +- `axios.get('/items')` — return mock inventory +- `axios.post('/items')` — handle create + batch sync +- `Dexie.table('pending_operations')` — in-memory queue + +--- + +## 6. Execution Plan (Subagent-Driven) + +### 6.1 Batch 1: Scanner Foundation (Tests 1-2) + +**Files:** `setup.ts`, `Scanner.test.tsx` + +**Tasks:** +1. Create `frontend/tests/setup.ts` with Vitest config, shared mocks (axios, html5-qrcode, Dexie, next/router) +2. Create `frontend/tests/components/Scanner.test.tsx` with unit + integration tests +3. Run `npm test -- --coverage` and verify 80%+ on Scanner module + +**Roles:** +- Implementer: Write setup + Scanner tests +- Reviewer 1: Validate mock fixtures align with Phase 1 patterns +- Reviewer 2: Verify test coverage (render, zoom, matching, callbacks) + +**Success Criteria:** +- setup.ts exports fixtures and vi.mock() setup +- Scanner tests cover all paths (unit + integration) +- `npm test -- --coverage` shows 80%+ on Scanner module +- All tests passing, no console errors + +**Commit:** `test: setup vitest and create Scanner test suite` + +--- + +### 6.2 Batch 2: AIOnboarding & Hooks (Tests 3-5) + +**Files:** `AIOnboarding.test.tsx`, `useAdmin.test.ts`, `api.test.ts` + +**Tasks:** +1. Create `frontend/tests/components/AIOnboarding.test.tsx` — step progression, AI response parsing +2. Create `frontend/tests/hooks/useAdmin.test.ts` — state management, form submission +3. Create `frontend/tests/lib/api.test.ts` — request building, retry logic, error mapping + +**Roles:** +- Implementer: Reuse Batch 1 fixtures, write 3 test files +- Reviewer 1: Ensure consistent mock usage across files +- Reviewer 2: Verify 80%+ coverage on all 3 modules + +**Success Criteria:** +- All 3 test files created +- Reuse setup.ts fixtures (no duplication) +- `npm test -- --coverage` shows 80%+ on AIOnboarding, useAdmin, api +- All tests passing + +**Commit:** `test: add AIOnboarding, useAdmin, api test suites` + +--- + +### 6.3 Batch 3: Admin & Utilities (Tests 6-7) + +**Files:** `AdminOverlay.test.tsx`, `labels.test.ts` + +**Tasks:** +1. Create `frontend/tests/components/AdminOverlay.test.tsx` — tab rendering, form validation, submission +2. Create `frontend/tests/lib/labels.test.ts` — barcode/QR generation, canvas export + +**Roles:** +- Implementer: Write 2 test files +- Reviewer 1: Validate form field coverage (5 tabs, validation logic) +- Reviewer 2: Verify SVG/canvas test patterns + +**Success Criteria:** +- Both test files created +- AdminOverlay covers all 5 tabs + form submission +- labels.ts covers Code 128, QR, canvas export +- `npm test -- --coverage` shows 80%+ on both modules + +**Commit:** `test: add AdminOverlay and labels test suites` + +--- + +### 6.4 Batch 4: Identity & Integration (Tests 8-9) + +**Files:** `IdentityCheckOverlay.test.tsx`, `scanner-workflow.test.tsx`, `inventory-workflow.test.tsx` + +**Tasks:** +1. Create `frontend/tests/components/IdentityCheckOverlay.test.tsx` — login form, LDAP flow, token storage +2. Create `frontend/tests/integration/scanner-workflow.test.tsx` — scan → match → adjust +3. Create `frontend/tests/integration/inventory-workflow.test.tsx` — view → filter → create → sync + +**Roles:** +- Implementer: Write 3 test files +- Reviewer 1: Validate login flow coverage (LDAP, error states) +- Reviewer 2: Verify integration test patterns (real component tree, mocked API) + +**Success Criteria:** +- All 3 test files created +- IdentityCheckOverlay covers login + error states +- scanner-workflow covers end-to-end scan flow +- inventory-workflow covers CRUD + offline sync +- `npm test -- --coverage` shows 80%+ on all modules + +**Commit:** `test: add IdentityCheckOverlay and integration test suites` + +--- + +### 6.5 Phase Completion + +**Tasks:** +1. Run full test suite: `npm test -- --coverage` +2. Verify 80%+ coverage across all files +3. Create git tag: `phase-2-complete` +4. Update `SESSION_STATE.md` with Phase 2 status +5. Update `REFACTORING_PROGRESS.md` (mark Phase 2 ✅) + +**Success Criteria:** +- All 9 test files created and passing +- Coverage report: 80%+ on all metrics (lines, functions, branches, statements) +- No console errors or warnings +- Git tag `phase-2-complete` created + +**Commit:** `docs: mark phase 2 complete - frontend test suite at 80%+ coverage` + +--- + +## 7. Success Metrics + +| Metric | Target | Status | +|--------|--------|--------| +| Test files created | 9 | ⏳ | +| Total test cases | 100+ | ⏳ | +| Coverage (lines) | 80%+ | ⏳ | +| Coverage (functions) | 80%+ | ⏳ | +| Coverage (branches) | 80%+ | ⏳ | +| All tests passing | Yes | ⏳ | +| No console errors | Yes | ⏳ | +| Git tag `phase-2-complete` | Yes | ⏳ | + +--- + +## 8. Dependencies & Pre-requisites + +- Phase 1 (Backend Tests) ✅ COMPLETE +- Vitest installed (v1.0.0+) +- @testing-library/react installed +- jsdom (React component testing environment) +- Git tag `phase-1-complete` available for rollback + +--- + +## 9. Rollback Plan + +If Phase 2 encounters critical issues: + +```bash +# Rollback to Phase 1 completion +git reset --hard phase-1-complete + +# Delete Phase 2 tags +git tag -d phase-2-complete + +# Resume when ready +git checkout refactor/ai-friendly +``` + +--- + +## 10. Next Phase (Phase 3) + +After Phase 2 completion: +- Create `docs/superpowers/plans/2026-04-18-phase-3-e2e-tests.md` +- Add Playwright E2E tests for critical workflows (login, scan, create item, offline sync, admin settings) +- Target: 5+ workflows automated, <30 min runtime