# Frontend Test Coverage

## Purpose

Frontend tests protect the three-layer architecture by testing API/data-access and business logic directly, without rendering full product modules when rendering is not needed.

## Test Runner

- `npm run test` runs `vitest run`.
- `npm run test:e2e` runs backend-free Playwright smoke tests against a production build served by Vite preview.
- `npm run test:e2e:content` runs backend-seeded content catalog Playwright tests against a production build served by Vite preview.
- `npm run typecheck` remains the TypeScript gate.
- `npm run build` runs typecheck before Vite.

## Current Coverage

Current coverage includes architecture guardrails, API/data-access behavior, and pure business-layer behavior in these files:

- `frontend/src/app/appRoutes.test.ts`
- `frontend/src/business/app-shell/selectors.test.ts`
- `frontend/src/business/auth/hooks.test.tsx`
- `frontend/src/business/auth/mappers.test.ts`
- `frontend/src/business/auth/permissions.test.ts`
- `frontend/src/business/auth/selectors.test.ts`
- `frontend/src/business/campus-attendance/mappers.test.ts`
- `frontend/src/business/campus-attendance/printReport.test.ts`
- `frontend/src/business/campus-attendance/selectors.test.ts`
- `frontend/src/business/campuses/mappers.test.ts`
- `frontend/src/business/classroom-support/selectors.test.ts`
- `frontend/src/business/classroom-timer/selectors.test.ts`
- `frontend/src/business/communications/selectors.test.ts`
- `frontend/src/business/community/selectors.test.ts`
- `frontend/src/business/dashboard/selectors.test.ts`
- `frontend/src/business/director-dashboard/selectors.test.ts`
- `frontend/src/business/esa-funding/selectors.test.ts`
- `frontend/src/business/frame/mappers.test.ts`
- `frontend/src/business/frame/selectors.test.ts`
- `frontend/src/business/audio-files/selectors.test.ts`
- `frontend/src/business/audio-files/generate.test.ts`
- `frontend/src/business/zone-checkin/selectors.test.ts`
- `frontend/src/business/personality/mappers.test.ts`
- `frontend/src/business/personality/selectors.test.ts`
- `frontend/src/business/policies/mappers.test.ts`
- `frontend/src/business/policies/selectors.test.ts`
- `frontend/src/business/safety-protocols/mappers.test.ts`
- `frontend/src/business/safety-protocols/selectors.test.ts`
- `frontend/src/business/safety-quiz/mappers.test.ts`
- `frontend/src/business/safety-quiz/selectors.test.ts`
- `frontend/src/business/sign-language/selectors.test.ts`
- `frontend/src/business/staff-attendance/mappers.test.ts`
- `frontend/src/business/staff-attendance/selectors.test.ts`
- `frontend/src/business/top-bar/selectors.test.ts`
- `frontend/src/business/top-bar/search.test.ts`
- `frontend/src/hooks/useOnClickOutside.test.tsx`
- `frontend/src/shared/business/week.test.ts`
- `frontend/src/business/user-progress/mappers.test.ts`
- `frontend/src/business/vocational/selectors.test.ts`
- `frontend/src/business/walkthrough/mappers.test.ts`
- `frontend/src/business/walkthrough/selectors.test.ts`
- `frontend/src/business/walkthrough/validators.test.ts`
- `frontend/src/business/zones/selectors.test.ts`
- `frontend/src/shared/api/auth.test.ts`
- `frontend/src/shared/api/campusAttendance.test.ts`
- `frontend/src/shared/api/campuses.test.ts`
- `frontend/src/shared/api/communications.test.ts`
- `frontend/src/shared/api/contentCatalog.test.ts`
- `frontend/src/shared/api/frame.test.ts`
- `frontend/src/shared/api/httpClient.test.ts`
- `frontend/src/shared/api/personality.test.ts`
- `frontend/src/shared/api/safetyQuizResults.test.ts`
- `frontend/src/shared/api/staffAttendance.test.ts`
- `frontend/src/shared/api/userProgress.test.ts`
- `frontend/src/shared/api/walkthrough.test.ts`
- `frontend/src/shared/architecture/import-boundaries.test.ts`
- `frontend/src/shared/business/apiListRows.test.ts`
- `frontend/src/shared/business/queryState.test.ts`
- `frontend/src/shared/constants/moduleRoutes.test.ts`
- `frontend/src/shared/errors/errorMessages.test.ts`
- `frontend/src/hooks/usePermissions.test.tsx`
- `frontend/src/components/sign-in-modal/SignInForm.test.tsx`

These tests verify import-boundary enforcement, centralized network access through `shared/api/httpClient`, alias-only source imports, required API contract-test coverage, HTTP client request normalization, cookie-backed auth refresh behavior, JSON body serialization, empty response handling, backend error propagation, API wrapper endpoint/query/body contracts, shared list/query/error helpers, route config, module route metadata, module access correction, sidebar navigation selectors, mobile sidebar overlay visibility, auth display/profile mapping, signup validation, campus mapping, dashboard and director dashboard selectors, classroom support selectors, timer formatting/progress/threshold parsing, DTO mapping, FRAME edit access, campus attendance mapping, calculations, and printable report output, staff attendance mapping and rollups, walkthrough create DTO mapping, walkthrough filtering, walkthrough check-in stats/history mapping, walkthrough scoring, generated summaries, repeated low-rating flags, communication role visibility, community catalog filtering and stats, ESA funding selectors, policy mapping/filtering/validation, safety-protocol mapping and authoring (steps/considerations) validation, audio-library management gating and the local recipe-generation stub, daily Zone check-in eligibility/nudge, header search over accessible modules + their content, outside-click dismissal, the shared American (Sunday-start) week canonicalization, F.R.A.M.E. week/label mapping, safety quiz compliance mapping and editable payload validation, sign language selectors, top bar display selectors, user progress normalization, vocational zip/category/search/stat calculations, zones selectors, personality DTO mapping, personality distribution grouping, EI thresholds, personality quiz progress, and MBTI-derived communication guidance.

The component and hook tests verify SignInForm rendering, loading states, user interactions, form submission, password visibility toggling, auth session initialization, sign-in/sign-out flows, AuthExpiredError handling, modal workflow state management, and permissions hook behavior including has(), hasAny(), hasAll() methods with globalAccess support and explicit personal-workflow exclusions.

The personality selector tests caught and now guard against a grouping defect where S/J and S/P types were classified from the third code character instead of the fourth code character.

The import-boundary tests enforce the three-layer dependency direction:

- API modules must not import business or view modules.
- Business modules must not import view modules.
- View modules must not call `frontend/src/shared/api/` directly.
- Source imports must use the configured `@` alias instead of relative paths.
- Direct `fetch` calls must stay centralized in `frontend/src/shared/api/httpClient.ts`.
- Runtime data access must stay centralized in the shared API layer.
- Every runtime module in `frontend/src/shared/api/` must have a colocated `.test.ts` contract test.

## Backend-Seeded E2E Coverage

Backend-seeded E2E tests live under:

- `frontend/tests/e2e/content-catalog.seeded.e2e.ts`
- `frontend/tests/e2e/accessibility.seeded.e2e.ts`
- `frontend/tests/e2e/rbac-access.seeded.e2e.ts`
- `frontend/tests/e2e/tenant-isolation.seeded.e2e.ts`
- `frontend/tests/e2e/provisioning.seeded.e2e.ts`
- `frontend/tests/e2e/product-workflow.seeded.e2e.ts`
- `frontend/tests/e2e/policy-acknowledgments.seeded.e2e.ts`
- `frontend/tests/e2e/audio-files.seeded.e2e.ts`
- `frontend/tests/e2e/zone-checkins.seeded.e2e.ts`

The seeded suite is intentionally excluded from default `npm run test:e2e` through `frontend/playwright.config.ts`. Run it with:

```bash
npm run test:e2e:content
```

Prerequisites:

- backend database migrations have run;
- backend database seeders have run;
- backend server is running at `VITE_BACKEND_API_URL`.

Test credentials are hardcoded (see `AGENTS.md` for the full list):
- Admin: `admin@flatlogic.com` / `flatlogicAdmin123!`
- Users: `<role>@flatlogic.com` / `flatlogicUser123!`
- Secondary tenant users: `<role>2@flatlogic.com` / `flatlogicUser123!`

The seeded suite verifies:
- Minimum content catalog seed set through the public backend API
- Classroom timer, classroom support, sign language, and zones routes with UI assertions based on live backend response
- RBAC access control for different user roles (teacher, director, superintendent access to appropriate routes)
- **Tenant isolation**: Users from one organization cannot read, list, update, or delete records from another organization
- **Scoped provisioning**: Creating an owner auto-creates and links a new company
- **Product workflows**: Director FRAME entries and staff progress tracking persist correctly (incl. server-side Sunday normalization of the FRAME `week_of`)
- **Policy acknowledgments**: document create/persist, manage-vs-read RBAC, per-version (idempotent) acknowledgment, and external-role lockout
- **Audio library**: `file`/`url`/`recipe` create/persist, same-campus read, kind/content validation, `support_staff` read-only, and external-role lockout
- **Daily Zone check-in**: explicit-permission record/read-back/clear of today's zone (campus-timezone date), invalid-zone rejection, and external-role lockout

## Accessibility E2E Coverage

Accessibility tests use `@axe-core/playwright` to verify WCAG 2 AA compliance across all 19 application pages. Run them with:

```bash
npm run test:e2e:content -- --grep "accessibility"
```

The accessibility suite covers:

- Login page (unauthenticated)
- Dashboard
- Classroom Timer
- Classroom Support
- Sign Language
- Zones of Regulation
- F.R.A.M.E. Weekly
- Behavior Management
- Emotional Intelligence
- Attendance
- Parent Communication
- Internal Alerts
- Safety Protocols
- Handbook & Policies
- Community & Partnerships
- Vocational Opportunities
- ESA Funding Info
- Walk-Through Check-In
- Director Dashboard

Each test runs axe-core with WCAG 2 A and AA tags (`wcag2a`, `wcag2aa`, `wcag21a`, `wcag21aa`) and fails on any violation. This ensures:

- Sufficient color contrast ratios (4.5:1 for normal text, 3:1 for large text)
- No nested interactive elements (buttons inside buttons)
- Proper ARIA labels and roles
- Keyboard accessibility
- Screen reader compatibility

## Rules For New Tests

- Prefer testing selectors, mappers, validators, and calculations before rendering full components.
- Cover shared API/client behavior with mocked `fetch`; do not call a live backend from unit tests.
- Keep import-boundary tests updated when adding a new top-level layer directory.
- Keep tests deterministic: no live backend, no network, and no current-time dependency unless the current date is injected.
- Use typed fixtures instead of `any` or unsafe casts.
- Add React/hook tests only when a workflow cannot be verified through pure functions.
- Use `renderHook` from `@testing-library/react` for hook tests; mock `useAuth` context when testing permission hooks.
- Use `render` from `@testing-library/react` and `userEvent` for component interaction tests.
- Keep backend-free Playwright smoke tests focused on high-value role/navigation workflows.
- Put live backend/database assertions only in explicit seeded suites such as `test:e2e:content`.
