feat(SPA): schema list and the sidebar Content group

This commit is contained in:
Florian Sylvain committed 2026-10-19 19:34:45 +02:00
1 parent 73a75d5cb9
commit 3c67cd2314
34 files changed
+2181 -18

No files matched your search

@@ -0,0 +1,48 @@
# QA: Schema list and content navigation (SPA slice 1)
Runner: Vitest + Vue Test Utils (already installed, `task test:web`). No Go test: there is no backend change.
Mock `/v1` through the existing api composable pattern used by the other view specs. Mount the shell (DashboardShell) with a test router and a resolved session whose role varies. Only owner and admin exist, so the forbidden cases use a session with an unknown role.
## Automated
Fixtures: three custom types (events, recipes, press-mentions) with the board's sample data for names, field counts and dates, at least one with icon "chef-hat" and one with icon null; five built-in types (articles, authors, sites, media, users) with fields arrays.
Schema list, one test per design state (screens/schema.md section 1):
1. Populated: both calls 200, role owner and role admin. Assert the title, subtitle, columns, custom rows before built-in rows, lock + "Built-in" badge on 5 rows, the built-in note, the summary "3 content types · 5 built-in", enabled "New content type". Assert the card layout below 640 px.
2. Loading: unresolved promise with fake timers. No skeleton at 149 ms, skeleton at 150 ms, "New content type" disabled. A fast response (under 150 ms) never shows skeletons.
3. Empty: content-type returns []. Assert the empty state copy, action, and the 5 built-in rows still listed.
4. Error: 500 and network failure. Assert the alert copy, the "Try again" action, no table. Then retry returns 200 and the Populated state replaces the alert (the second call is made).
5. Forbidden: unknown role. Assert the 403 page copy, "Go to Home" navigates to /home, URL stays /schema, `GET /v1/builtin-type` never called. Add a case where builtin-type answers 403 for an owner.
6. builtin-type 500 with content-type 200: Error state.
7. "New content type" pushes /schema/new.
Sidebar:
8. Schema entry visibility for owner, admin and unknown role; position after Users.
9. Content group: three links with the right hrefs, current row marked, hidden on empty, hidden on 500 and on network failure, no second request across route changes.
10. Icons: "chef-hat" in the bundle renders it, null and an unbundled name render the default "files" icon.
11. Truncation: label has the truncate classes, full name in tooltip and accessible name.
12. More than 5 types: 14 types and a selected type beyond the fifth. Assert 5 + the selected row + "Show all 14"; after activating it all 14 show. With 5 types, no "Show all".
13. Mobile (viewport helper in `components/__tests__/viewport.ts`): drawer shows one collapsed row "All content types" with count 14, expands to 14 rows.
Router and guard:
14. `/schema` is registered with auth "verified" and title "Schema"; unverified and signed-out users get the existing redirects (extend routerGuard.spec).
Client and store:
15. Typed client calls (the Examples table in the feature) incl. icon string|null typing, 403, 500, network failure.
16. Store loads once, shares state between the sidebar and the Schema list, retry reloads.
## Visual (task visual:check -- schema)
Run `task visual:check -- schema`, every capture within 10 % at desktop and mobile, light and dark. States to set up in `web/visual/states.ts`, reusing the board's sample data (names, keys, field counts, dates, counts "3 content types · 5 built-in" taken from SchemaFrame.dc.html):
- 1 Populated, 2 Loading, 3 Empty, 4 Error, 5 Forbidden (403).
- State 6 (built-in read-only view) is out of scope: report it as not set up in this slice, and flag it to the user if the check demands a setup for every state.
- None of these is clock-sensitive; if the Last updated cell turns out to be relative on the board, mark it `skip: 'clock-sensitive'`.
- Mock every `/v1` call the screen makes, including the sidebar's GET /v1/content-type.
- The sidebar group and drawer frames belong to the later `content` group.
## Manual
- Keyboard: tab order through sidebar, "Show all", table and "New content type"; visible focus rings.
- Tooltip on a truncated name on hover and on focus.
- Hover and motion of the drawer expand/collapse row.
- With a real backend: log in as owner and admin and confirm the sidebar and /schema; create a type with icon "chef-hat" via the API and see it appear.