4.2 KiB
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):
- 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.
- 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.
- Empty: content-type returns []. Assert the empty state copy, action, and the 5 built-in rows still listed.
- 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).
- Forbidden: unknown role. Assert the 403 page copy, "Go to Home" navigates to /home, URL stays /schema,
GET /v1/builtin-typenever called. Add a case where builtin-type answers 403 for an owner. - builtin-type 500 with content-type 200: Error state.
- "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
/v1call the screen makes, including the sidebar's GET /v1/content-type. - The sidebar group and drawer frames belong to the later
contentgroup.
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.