Files
RenewCMS/features/register_screen.qa.md
T
2026-09-26 02:48:16 +02:00

74 lines
5.3 KiB
Markdown

# QA: Register screen
## Automated (Vitest + Vue Test Utils, `task test:web`)
Mock `useApi` (`POST /v1/auth/register` only — RegisterPage never calls
`GET /v1/auth/registration`); no real backend, no httptest server. Mount RegisterPage inside
AuthShell with a test router.
1. **Default state** — mount at /register; assert heading "Create the owner account", description
"This creates the single admin account for this site. Once it's verified, registration
closes.", Username placeholder "e.g. marta" with no value and counter "0 / 20", Email
placeholder "you@example.com" with no value, Password with no value and the checklist item
"At least 8 characters" in its unmet state, submit button "Create account", and the footer
"Already set up? Log in" linking to /login.
2. **Validation errors state** — mount at /register; set Username to "ma" and blur; assert counter
"2 / 20" in error and the error "Use 3 to 20 characters."; set Email to "marta@renew" and blur;
assert the error "Enter a full email address, like name@example.com."; set Password to "lime"
and blur; assert the checklist item stays in its error state; submit; assert the mocked
`POST /v1/auth/register` was never called and all three errors are still shown.
3. **Filled, valid state** — set Username "marta", Email "marta@renew.example", Password
"limewash2026"; toggle password visibility on; assert counter "5 / 20" with no error and the
help text restored, no Email error, Password rendered as plain text, the checklist item in its
met/green state, and the submit button enabled and reading "Create account".
4. **Submitting state** — set Username "marta", Email "marta@renew.example", Password
"limewash2026"; mock `POST /v1/auth/register` with an unresolved promise; submit; assert
Username, Email and Password are disabled and the submit button reads "Creating account…" with
a loading indicator.
5. **Registration closed state** — set the same valid values; mock `POST /v1/auth/register`
resolving 403; submit; assert the form and footer are no longer rendered; assert a ResultPanel
with title "This site already has an owner", text "Log in instead.", and a single primary
action "Go to log in"; click it and assert the router's current path is /login.
6. **Server or network error state** — two sub-cases: (a) a 500 response, (b) a rejected fetch
(network error). In each, set Username "marta", Email "marta@renew.example", Password
"limewash2026", submit, and assert an error alert with title "Couldn't create the account" and
description "Something went wrong on the server. Try again in a moment."; assert Username,
Email and Password still show their values; assert the three fields are re-enabled; assert the
submit button reads "Create account" and is no longer loading.
7. **Successful registration navigates to pending** — mock `POST /v1/auth/register` resolving 200;
set the same valid values; submit; assert the router's current path is /register/pending, and
that no `GET /v1/auth/me` call was made by RegisterPage itself.
## Visual (manual verification — desktop and mobile, light and dark)
Reference: `docs/design/source/RenewCMS Screens Auth.dc.html`, group "Register". Run
`task visual:check -- register` for each state and compare against the board frame.
- [ ] Default state: heading, description, Username with counter and help text, Email with help
text, Password with show/hide toggle and the unmet checklist item, "Create account" button,
"Already set up? Log in" footer — matches the board exactly.
- [ ] Validation errors state: Username counter and error, Email error, and the Password checklist
item's error styling all render inline per components.md.
- [ ] Filled, valid state: the checklist item's met/green transition and the revealed password
text render correctly.
- [ ] Submitting state: disabled field styling and the loading spinner in the submit button.
- [ ] Registration closed state: the ResultPanel (info tone, user-x icon tile, title, text, single
primary "Go to log in" action) fully replaces the form and footer.
- [ ] Server error state: error alert (circle-x icon, no close button per the Log in screen's
precedent) above the heading, fields retaining their values, form re-enabled.
- [ ] Keyboard/focus: Tab order is Username → Email → Password → show/hide toggle → submit; when
the Registration closed ResultPanel appears, focus moves to its title and it is
`role="status"`; the server error alert is `role="alert"` and does not steal focus from
wherever the user was; the checklist item's live state change is not visually jarring
(no layout shift) as it flips from unmet to met.
## Manual verification
- **Real POST /v1/auth/register against a running server** — Vitest only mocks `useApi`; confirm
the real 403 (`user.ErrRegistrationClosed`) and a real 200 round-trip with the actual jwt cookie
against `task dev` with a live SQLite file, since this slice's automated tests never exercise the
actual Go handler, the `CreateUser` use case, or cookie issuance.
- **Real navigation to /register/pending after a live registration** — confirm the route guard
reads the freshly set cookie correctly, since Vitest never resolves a real session against
GET /v1/auth/me on that navigation.