Files
RenewCMS/features/get_current_user.qa.md
T
2026-09-25 15:17:39 +02:00

3.6 KiB

QA procedure: get_current_user

Package: test (black-box), extending test/user_test.go (mockUserRepo) and following the router wiring pattern in test/stale_token_invalidation_http_test.go.

Test infrastructure additions needed first

  1. No new mockUserRepo methods are needed: GetUser(id) already exists and is already exercised by other tests (e.g. test/stale_token_invalidation_http_test.go). DELETE /v1/auth/register already deletes the row via CancelRegistrationUseCase, already used in test/cancel_pending_registration_http_test.go.

Setup shared by every case

  1. Call validator.InitValidator() once.
  2. Build getUserUseCase := useCases.NewGetUserUseCase(userRepo).
  3. Build meHandler := auth.NewMeHandler(getUserUseCase).
  4. Also build verificationHandler := auth.NewVerificationHandler(useCases.NewVerifyUserUseCase(userRepo, hasher), useCases.NewCancelRegistrationUseCase(userRepo), true) so the "deleted account" scenario can call DELETE /v1/auth/register on the same router.
  5. Mount on a fresh chi.NewRouter(), mirroring NewAuthRouter's protected group:
    r.Route("/v1/auth", func(r chi.Router) {
        r.Group(func(r chi.Router) {
            r.Use(jwtauth.Verifier(token))
            r.Use(jwtauth.Authenticator(token))
            r.Use(middleware.RequireCurrentToken(getUserUseCase))
            r.Get("/me", meHandler.Me)
            r.Delete("/register", verificationHandler.CancelRegistration)
        })
    })
    
    with a test token := jwtauth.New("HS256", []byte("test-secret"), nil). No live server.
  6. Mint jwt cookies with token.Encode(map[string]any{"user_id": uint32(id), "token_version": uint32(v)}), the same convention as test/stale_token_invalidation_http_test.go.

HTTP-level checks

  1. Seed mockUserRepo with user id 7, username "alice", email "alice@example.com", IsVerified: true, TokenVersion: 0. Mint a cookie for user 7 with token_version: 0. GET /v1/auth/me → assert status 200, Cache-Control header equals "no-store", and the decoded JSON body has id: 7, username: "alice", email: "alice@example.com", is_verified: true.
  2. Seed user id 8, username "bob", email "bob@example.com", IsVerified: false, TokenVersion: 0. Mint a matching cookie. GET /v1/auth/me → assert status 200 (not 403), Cache-Control: no-store, and is_verified: false in the body.
  3. No jwt cookie at all against the router from step 6 → assert status 401 (produced by jwtauth.Authenticator itself; don't assert an exact body for this case, same rationale as features/account_verification.qa.md step 15).
  4. Seed user id 7 with TokenVersion: 1. Mint a cookie encoding token_version: 0 (stale). GET /v1/auth/me → assert status 401 and body exactly apperr.UnauthorizedErrorMessage.
  5. Seed user id 7, IsVerified: false, TokenVersion: 0. Mint a matching cookie. DELETE /v1/auth/register with that cookie → assert status 200. Then GET /v1/auth/me with the same cookie → assert status 401 and body exactly apperr.UnauthorizedErrorMessage.
  6. Seed user id 7, IsVerified: true, TokenVersion: 0, matching cookie. Send GET /v1/auth/me 5 times in a row on the same router/repo → assert every response is 200 and none is 429.

Manual verification (not exercised by the Go test)

  • The SPA actually calling GET /v1/auth/me on load/refresh to restore session state and route an unverified user to the pending-verification screen (rather than guessing from stored client state) is out of scope for this slice's automated test and should be checked by hand against a running dev build.