3.7 KiB
3.7 KiB
QA procedure: user_response_field_hygiene
Package: test (black-box), extending test/account_verification_http_test.go's
newAccountVerificationRouter / newAccountVerificationTestUserRepo helpers and
test/user_test.go's mockUserRepo / stubHasher.
Setup shared by every case
- Call
validator.InitValidator()once. - Reuse
newAccountVerificationRouter(userRepo, mailRepo, token)fromtest/account_verification_http_test.go, which wiresauth.NewHandler(...)with fakes over a freshchi.NewRouter()mirroringapi/router.go's/v1/authgroup (public routes plus thejwtauth.Verifier+Authenticator-wrappedverifyroute). No live server, no real SQLite, no real SMTP. newAccountVerificationTestUserRepo()seeds user id 7 with a non-emptyVerificationCode("hashed:abc123") andVerificationExpirationone hour out, matching the existing fixture.
Response-shape check for POST /v1/auth/verify (the fix)
- Successful verify:
POST /v1/auth/verifywith{"code":"abc123"}and a valid jwt cookie for user id 7. Decode the response body intomap[string]json.RawMessage(not intouser.User) and assert:- the key set is exactly
{"id", "username", "email", "is_verified", "created_at", "updated_at", "display_name", "role"}; - none of
password,password_reset_code,verification_code,verification_expiration,password_reset_expiration,token_versionis present; is_verifiedunmarshals totrue;display_nameunmarshals to"";roleunmarshals to"owner"(seeded user 7 hasRole: owner).
- the key set is exactly
- Rejected verify: same seed,
{"code":"wrong-code"}→ assert status403and that the raw response body bytes, treated as a string, contain none of the substringspassword,verification_code,password_reset_code,verification_expiration,password_reset_expiration(the body is plain text fromhttp.Error, so this is a substring check, not a JSON-key check).
Registration check (its own case, correctly gated)
POST /v1/auth/registeragainst an emptymockUserRepo(the registration gate only allows register while no verified account exists) with{"username":"bob","password":"hunter2example12","email":"bob@example.com"}→ assert status200and that the raw response body string contains none of the six sensitive substrings from step 5.
Table-driven sweep of the other auth endpoints (regression guard, not the fix)
- For each of
POST /v1/auth/login,/logout,/password-reset,/password-reset/confirm, seed amockUserRepo/mockMailRepopair with a verified user "alice" (IsVerified: true, matching the Scenario Outline's Given, since these endpoints don't depend on the registration gate), send the request, and assert the raw response body string contains none of the six sensitive substrings from step 5. This should already pass today since these handlers only ever write a{"message": ...}body; the point of the test is to pin that fact down so a future change can't quietly regress it.
Manual verification (not exercised by the Go test)
- The SPA's post-verification screen (
web/src/) only ever needsusername/is_verifiedto render; confirm by hand that no SPA code readspassword,verification_codeorpassword_reset_codeoff the verify response, since removing them from the wire format could otherwise silently break a screen that isn't covered by this Go test suite. - Confirm the public response type lives in the shared package under
api/pkg(not a change tointernal/domain/user/userDomain.go's json tags), per the project's stated preference to keep the domain struct's tags intact and shape the public response in the handler layer instead.