100 lines
6.3 KiB
Markdown
100 lines
6.3 KiB
Markdown
# QA: Integration screen (API reference)
|
|
|
|
## Automated (Vitest + Vue Test Utils, `task test:web`)
|
|
|
|
Mount IntegrationPage inside DashboardShell with a resolved verified session and a test router at
|
|
/integration. Stub `window.location.origin` to `https://cms.renew.example` (the board's sample) and
|
|
`navigator.clipboard.writeText` per case. Mock only GET /v1/image-variants (see integration_images.qa.md). A spec fails if any other `/v1` call
|
|
is made.
|
|
|
|
Catalogue spec (pure data, no mount, imports web/src/data/apiCatalogue.ts):
|
|
1. The catalogue holds exactly the 20 expected key-callable routes from an explicit hand-maintained
|
|
list in the spec (Articles 7, Media 6, Users and invites 6, Settings 1), each once, with no other
|
|
expandable route. Session only has the 13 rows and Public auth flow the 6 rows listed in the
|
|
feature, from the same kind of explicit list.
|
|
2. Every catalogue route has a non-empty `description`. An empty or missing one fails the spec and
|
|
names the route.
|
|
3. Every route has method, path, access chip, key chip, a query-parameter list and a body-field list
|
|
(possibly empty), and fetch, curl and Response examples.
|
|
4. The Response sample of each route parses as JSON and uses only keys from a fixture of the real
|
|
fields:
|
|
- article: id, title, body, body_format, is_online, created_at, updated_at;
|
|
- media item: id, filename, url, size, content_type, width, height, sha256, uploaded_by,
|
|
created_at, used_in, duplicate;
|
|
- media list: items, total, page, size, counts (all, unused, duplicates), no next_cursor;
|
|
- merge: articles_updated, merged;
|
|
- usage: id, title, published;
|
|
- user list item: id, kind, username, display_name, email, role, status, created_at;
|
|
- invite: id, kind, email, status, created_at, expires_at;
|
|
- settings: version.
|
|
Any other key fails the spec. "images" and "status" are explicitly rejected on articles.
|
|
5. Request-body tables equal the validate tags (title 3-200, body optional with no length limit, filename, keep_id,
|
|
merge_ids, display_name, email). The multipart field is "file". Query tables: `format` on every
|
|
article route, and q, hash, cursor, filter, sort, limit on GET /v1/media/.
|
|
6. The three invite routes carry "Owner only", a 403 "Only the owner can do this." caption and the
|
|
rate-limit sentence. No /v1/system route is in an expandable group. Login, Log out, Register and
|
|
Reset password rows carry no 403 claim. Verify, DELETE /auth/register, /api-key/* and
|
|
/system/* are the only rows that claim 403.
|
|
7. Error captions equal fixtures copied from api/pkg/apperr/messages.go and the image domain
|
|
errors (413, 415, 400 on upload).
|
|
|
|
Component specs, one per design state:
|
|
1. **Default**: breadcrumb, title "API reference", description, intro, Base URL equals the stubbed
|
|
origin, all cards collapsed (aria-expanded "false"), section index entries present, the three
|
|
invite rows show "Owner only".
|
|
2. **Group scrolled, one card expanded**: click the POST /v1/article/ row. Assert the Query
|
|
parameters table above the Request body table, the body rows, tabs fetch/curl/Response with fetch
|
|
active in one CodeSnippet, and the Errors list with 400 and 401.
|
|
3. **Copied: base URL**: fake timers; click Copy. Clipboard gets the origin; check icon and "Copied";
|
|
announced; reverts after 2 s.
|
|
4. **Copied: CodeSnippet**: expand a card; click "Copy code". Clipboard gets the active tab's code,
|
|
only that button reads "Copied", and it reverts after 2 s.
|
|
5. **Authentication**: both cards, a CodeSnippet with curl/fetch tabs for GET /v1/auth/me, the "Manage API keys" link
|
|
href /integration/api-keys, Note 1, Note 2.
|
|
6. **Session only**: the corrected banner; lock icon and "Session only" chip only on rows that
|
|
answer 403; the caption on the login family; no expand control; the "Public auth flow" rows with
|
|
the "Public" chip.
|
|
7. **Errors**: table rows 400, 401, 403, 404, 409, 429, 500 with the real strings and the 403
|
|
sample block.
|
|
8. **Navigation**: clicking an index item sets aria-current and scrolls to its anchor; the mobile
|
|
"Jump to" lists the same sections.
|
|
9. **Tabs**: curl and Response render for a card. curl contains the stubbed origin and the
|
|
Authorization header only on non-public routes. Not visually checked.
|
|
10. **Notes**: format note, image-prefix note, CORS note.
|
|
11. **Base URL and error sample**: both are CodeSnippets (single tabs "Base URL" and "Error response · text/plain").
|
|
|
|
## Visual (`task visual:check -- integration`, desktop and mobile, light and dark)
|
|
|
|
Reference: docs/design/screens/integration.md; board "Integration" drawn by
|
|
docs/design/source/IntegrationPage.dc.html. Serve the SPA under `https://cms.renew.example`. Mocks
|
|
reuse the board's script data: BASE, KEY, group and endpoint descriptions, the request bodies
|
|
(for example the "Choosing tiles for a small bathroom" article). Response samples are not compared;
|
|
the Response tab is never active in a board frame.
|
|
|
|
Pre-approved exceptions: the user pre-approved visual exceptions for Session only, Group scrolled
|
|
one card expanded, Errors and Default. For each of these four states the coder measures the real
|
|
diff, sets the smallest `maxPercent` that is sufficient, writes the reason, and records
|
|
`approvedBy` "Florian Sylvain". The other states must still pass 10 %.
|
|
|
|
- [ ] Default (exception: owner-only chips and rate-limit line)
|
|
- [ ] Group scrolled, one card expanded (exception: Query parameters table)
|
|
- [ ] Copied: base URL (must pass 10 %)
|
|
- [ ] Copied: CodeSnippet (must pass 10 %)
|
|
- [ ] Authentication (must pass 10 %; Note 1 text changed)
|
|
- [ ] Session only (exception: banner, 13th row, captions, Public auth flow block)
|
|
- [ ] Errors (exception: 409 row)
|
|
- [ ] Navigation (must pass 10 %)
|
|
|
|
None of these states is clock-sensitive, so none is skipped.
|
|
|
|
## Manual
|
|
- Keyboard and focus order: index, Base URL Copy, each row (Enter/Space), tab strip (arrow keys),
|
|
CodeSnippet Copy, the pre (tabindex 0), Jump to on mobile.
|
|
- Hover and motion on ghost Copy buttons and rows.
|
|
- Find-in-page and a deep link to an `#ep-...` anchor.
|
|
- Real origin in a production build and under `task dev`.
|
|
- Run each documented example against a running server with a real `rcms_` key, including the
|
|
403 on a session-only route and the owner-only 403 for an admin key on the invite routes. This
|
|
needs a real server and is not automated.
|
|
- docs/api.md matches the catalogue (hand check).
|