Files
RenewCMS/features/reset_request_screen.qa.md
T

3.8 KiB

QA: Password reset request screen

Automated (Vitest + Vue Test Utils, task test:web)

Mock useApi (POST /v1/auth/password-reset) per case; no real backend, no httptest server. Mount ResetRequestPage inside AuthShell with a test router.

  1. Default state — mount at /register/reset/request; assert heading "Reset your password", description, Email placeholder "you@example.com" with no value, submit "Send reset link", footer "Back to log in" linking to /login.
  2. Validation error state — set Email to "marta@renew", submit; assert the mocked POST /v1/auth/password-reset was never called; assert the error "Enter a full email address, like name@example.com."
  3. Submitting state — set Email "marta@renew.example"; mock the call with an unresolved promise; submit; assert the Email field is disabled and the submit button reads "Sending…" with a loading indicator.
  4. Sent state — set Email "marta@renew.example"; mock the call resolving 200; submit; assert the form is replaced by a ResultPanel (success, mail-check, "Check your email", the neutral text, note "The link expires in 1 hour.") with a single secondary action "Back to log in"; click it and assert the router's current path is /login.
  5. Too many attempts state — set Email "marta@renew.example"; mock the call resolving 429 with Retry-After: 58; submit; assert an info alert ("Too many requests", "Wait a moment before asking for another link."); assert Email still reads "marta@renew.example"; assert the submit button reads "Try again in 0:58" and is disabled; assert the Email field is disabled; advance fake timers 58s; assert the button re-enables and reads "Send reset link" and the field is editable again.
  6. Server or network error state — two sub-cases (500 response, rejected fetch) with Email "marta@renew.example"; submit; assert an error alert ("Couldn't send the link", "Check your connection and try again."); assert Email still reads "marta@renew.example" and is re-enabled; assert the submit button reads "Send reset link" and is no longer loading.

Visual (manual verification — desktop and mobile, light and dark)

Reference: docs/design/source/RenewCMS Screens Auth.dc.html, group "Forgot password". Run task visual:check -- forgot-password for each state.

  • Default state: heading, description, Email field, "Send reset link" button, "Back to log in" footer link, matches the board exactly.
  • Validation error state: the inline field error renders with the same styling as Register's/Login's own field errors.
  • Submitting state: disabled field styling and the loading spinner in the submit button.
  • Sent state: ResultPanel (mail-check icon) with its single secondary action, note text below the description.
  • Too many attempts state: info alert (timer icon), disabled field and disabled button with the live "Try again in m:ss" countdown text.
  • Server error state: error alert (circle-x icon, no close button), field retains its value.
  • Keyboard/focus: Tab order is Email → submit; the alert (when present) is announced via role="status" (info) or role="alert" (error) without re-announcing on re-render; the ResultPanel's title receives focus on the Sent state.

Manual verification

  • Real POST /v1/auth/password-reset against a running server — Vitest only mocks useApi; confirm the real 200/429/500 round-trip (including the actual rate limiter and Retry-After header) against task dev with a live SQLite file. The endpoint's own contract is already covered by features/request_password_reset.qa.md; this slice only re-verifies the screen consumes it correctly.
  • 429 countdown drift — confirm useRetryAfter's live countdown does not drift against a real elapsed 58-second wait, since Vitest fake timers only prove the logic.