77 lines
5.0 KiB
Markdown
77 lines
5.0 KiB
Markdown
# QA procedure: cancel_pending_registration
|
|
|
|
Package: `test` (black-box), extending `test/user_test.go` (`mockUserRepo`) and following the
|
|
router/handler wiring pattern already used in `test/account_verification_http_test.go`.
|
|
|
|
## Test infrastructure reused, none new needed
|
|
|
|
`mockUserRepo` already supports deleting an entry (used by the existing `DeleteUserUseCase` tests
|
|
in `test/use_case_baseline_test.go`) and returning `user.ErrUserNotFound` from `Get` once a user is
|
|
gone. No new mock methods are required; `CancelRegistrationUseCase` only calls `Get` and `Delete`,
|
|
both of which `mockUserRepo` already implements.
|
|
|
|
## Setup shared by every case
|
|
|
|
1. Call `validator.InitValidator()` once.
|
|
2. Use-case-level checks build `useCases.NewCancelRegistrationUseCase(repo)` where `repo` is a
|
|
`mockUserRepo` pre-populated directly via `repo.users[id] = user.User{...}`.
|
|
3. HTTP-level checks wire `mockUserRepo`, `useCases.NewCancelRegistrationUseCase(repo)` and the
|
|
other existing use cases into `auth.NewHandler(...)` (extended with the new
|
|
`CancelRegistrationUseCase` parameter) with a test `jwtauth.New("HS256", []byte("test-secret"),
|
|
nil)`. Mount `DELETE /v1/auth/register` on a fresh `chi.NewRouter()` wrapped in
|
|
`jwtauth.Verifier(token)` then `jwtauth.Authenticator(token)`, mirroring the protected group
|
|
`api/router.go` adds inside `NewAuthRouter` (the same group `POST /v1/auth/verify` already sits
|
|
in). Mint jwt cookies with `token.Encode(map[string]any{"user_id": uint32(7)})` for the
|
|
valid-token cases.
|
|
|
|
## Use-case-level checks (no HTTP)
|
|
|
|
4. Repo has user id 3, `IsVerified: false`. Call `CancelRegistration(3)`. Assert `err == nil`.
|
|
Assert `repo.users` no longer has key 3 (or `repo.Get(3)` returns `user.ErrUserNotFound`).
|
|
5. Repo has user id 3, `IsVerified: true`. Call `CancelRegistration(3)`. Assert
|
|
`errors.Is(err, user.ErrAlreadyVerified)`. Assert the repo still has user id 3 with
|
|
`IsVerified: true`.
|
|
6. Repo has no user with id 42. Call `CancelRegistration(42)`. Assert
|
|
`errors.Is(err, user.ErrUserNotFound)`.
|
|
|
|
## HTTP-level checks (fakes, per the shared setup above)
|
|
|
|
7. Seed `mockUserRepo` with user id 7, username "alice", email "alice@example.com",
|
|
`IsVerified: false`. Mint a valid jwt cookie for user id 7. `DELETE /v1/auth/register` with that
|
|
cookie → assert status `200`, response body decodes to a JSON object with a `message` field,
|
|
the response has a `Set-Cookie` header for `jwt` with `MaxAge < 0` (or an `Expires` in the past)
|
|
and an empty `Value` (parse with `http.ParseSetCookie`, mirroring
|
|
`secureAttributeFromResponse` in `test/runtime_settings_injection_http_test.go`), and
|
|
`repo.Get(7)` now returns `user.ErrUserNotFound`.
|
|
8. Re-registration after cancel: repeat case 7's cancel call on the same router/repo, then
|
|
`POST /v1/auth/register` with `{"username":"alice","password":"hunter2example12","email":"alice@example.com"}`
|
|
→ assert status `200`, a `jwt` `Set-Cookie` header is present with a non-empty value, and the
|
|
newly created user's id (read back via `repo.GetByUsername("alice")` or the use case) is
|
|
different from `7`.
|
|
9. Seed `mockUserRepo` with user id 7, username "alice", email "alice@example.com",
|
|
`IsVerified: true`. Mint a valid jwt cookie for user id 7. `DELETE /v1/auth/register` with that
|
|
cookie → assert status `403`, body exactly the `apperr.AlreadyVerifiedErrorMessage` constant,
|
|
no `Set-Cookie` header for `jwt` is present in the response, and `repo.Get(7)` still returns the
|
|
user with `IsVerified: true`.
|
|
10. Table-driven over three "no valid user_id" cases, each against a fresh seed of user id 7,
|
|
`IsVerified: false`, and asserting status `401`, a response body equal to
|
|
`apperr.UnauthorizedErrorMessage`, no `jwt` `Set-Cookie` header in the response, and
|
|
`repo.Get(7)` still succeeding afterward:
|
|
- mint the jwt with `token.Encode(map[string]any{"role": "user"})` (no `user_id` key at all);
|
|
- mint the jwt with `token.Encode(map[string]any{"user_id": "seven"})` (string, not a number);
|
|
- mint the jwt with `token.Encode(map[string]any{"user_id": uint32(999)})` (well-formed but no
|
|
such user in the repo).
|
|
11. A request with no `jwt` cookie at all against the same router → assert status `401` (produced
|
|
by `jwtauth.Authenticator` itself, before the handler runs); do not assert an exact body for
|
|
this case, and assert `repo.Get(7)` still succeeds afterward.
|
|
|
|
## Manual verification (not exercised by the Go test)
|
|
|
|
- The SPA-visible "cancel registration" affordance (wherever it is surfaced to a logged-in,
|
|
unverified user, e.g. on the pending-verification screen) actually calling
|
|
`DELETE /v1/auth/register` and redirecting to a logged-out state on success is out of scope for
|
|
this slice's automated test and should be checked by hand against a running dev build.
|
|
- End-to-end confirmation against the real SQLite file that the row is physically gone (not just
|
|
hidden by a soft-delete) is already covered at the repository level by
|
|
`features/unverified_users_and_reregistration.feature` and is not re-verified here.
|