test(admin): Activities + app/nav — fill gaps + lifecycle test
Fill coverage gaps and lock in behavior for the Activities screen and app/nav (Sidebar) domain (plan task B-D6). All four domain src files (screens/Activities.tsx, api/activities.ts, App.tsx, components/Sidebar.tsx) now at 100% stmts/branch/funcs/lines. - Activities.test.tsx: insole-type toggle select/deselect (both branches), reduced-subset create, add disabled when no types, edit insole types, cancel-without-save, empty-types-defaults-all editor, empty state, error-falls-back-to-empty, and the create->edit types->reorder->delete lifecycle test. - Sidebar.test.tsx (new): brand + nav links + email, active-route highlight, end-match keeps Live inactive off-root, nav click switches screen + moves highlight, Uitloggen calls signOut, email hidden without useMe data. - Activities.tsx: three /* c8 ignore next */ annotations on the defensive early-return guards in handleAdd/handleSave/handleMove (each mirrored by a disabled button, so unreachable via the UI). Comment-only, no behavior change. No bugs found — the domain code was already correct; the tests lock it in.
This commit is contained in:
@@ -516,3 +516,45 @@ Guaranteed behaviors:
|
||||
- Lifecycle (`src/screens/Users.test.tsx`): create a worker via the form → it appears in the refreshed
|
||||
list as `Werker` → promote it via `Maak admin` → the pill flips to `Beheerder` after the refetch →
|
||||
reset its password inline (`Opslaan`) → the POST fires and the inline field closes.
|
||||
|
||||
## Activities + app/nav — admin client
|
||||
|
||||
Src covered (admin `apps/admin`): `src/screens/Activities.tsx`, `src/api/activities.ts`,
|
||||
`src/App.tsx`, and `src/components/Sidebar.tsx` — all at 100% stmts/branch/funcs/lines. Three
|
||||
`c8 ignore`s with reasons in `Activities.tsx`: the early-return guards in `handleAdd`, `handleSave`,
|
||||
and `handleMove` are unreachable via the UI because the button that triggers each is disabled in
|
||||
exactly that state (`Stap toevoegen` when `!addEnabled`, `Opslaan` when the name/types are empty,
|
||||
the ↑/↓ move buttons at the list bounds).
|
||||
|
||||
Guaranteed behaviors:
|
||||
|
||||
- Activities renders the Dutch header (`Handelingen` / `Beheer handelingen per zooltype`), the
|
||||
add-handeling card, and the current-steps list with a live count (`Huidige stappen (<n>)`).
|
||||
- The insole-type toggles select/deselect a type (both the remove and re-add branches), reflected via
|
||||
`aria-pressed`; a new handeling defaults to all three types (`Kurk`, `Berk`, `3D`).
|
||||
- Creating a handeling POSTs `/api/activities` with the trimmed name and the selected `insole_types`
|
||||
subset (a deselected type is dropped from the payload); `Stap toevoegen` is disabled while the name
|
||||
is blank or every type is deselected.
|
||||
- Editing a handeling opens an inline editor prefilled from the row and PUTs `/api/activities/:id` with
|
||||
the updated name + `insole_types`; an activity stored with no insole types pre-selects all three in the
|
||||
editor; `Annuleren` exits edit mode without issuing a PUT.
|
||||
- Deleting a handeling confirms first (`window.confirm`); DELETE `/api/activities/:id` fires only when
|
||||
confirmed, and is skipped when cancelled.
|
||||
- Reorder: ↑/↓ move a row and PUT `/api/activities/reorder` with the swapped id order; ↑ is disabled on
|
||||
the first row and ↓ on the last.
|
||||
- The list shows the loading placeholder (`Laden...`) while the query is pending and the empty state
|
||||
(`Nog geen stappen. Voeg er een toe hierboven.`) when there are none; a query error falls back to the
|
||||
same empty state (there is no dedicated error UI).
|
||||
- `api/activities.ts` hooks hit the right path/method — `useActivities` → GET `/api/activities`;
|
||||
`useCreateActivity` → POST; `useUpdateActivity` → PUT `/:id`; `useDeleteActivity` → DELETE `/:id`;
|
||||
`useReorderActivities` → PUT `/reorder` — and every mutation invalidates the `['activities']` query on
|
||||
success.
|
||||
- App/nav: `App` gates on auth (no token → `Login`; a token → the authed shell with `Sidebar` + routed
|
||||
screens). `Sidebar` renders the brand, the five nav links, and the signed-in email (hidden when
|
||||
`useMe` has no data), and `Uitloggen` calls `signOut`.
|
||||
- `Sidebar` highlights the active route via `nav-link-active` and, with `end` matching on `/`, keeps the
|
||||
Live link inactive on any non-root route; clicking a nav link switches the rendered screen and moves
|
||||
the highlight.
|
||||
- Lifecycle (`src/screens/Activities.test.tsx`): create a handeling → edit its insole types down to a
|
||||
single type → reorder it above another → delete it, with each step reflected in the refetched list;
|
||||
the Sidebar test (`src/components/Sidebar.test.tsx`) covers navigation switching screens.
|
||||
|
||||
Reference in New Issue
Block a user