3.3 KiB
3.3 KiB
QA procedure: user_roles
Package: test (black-box). Reuse mockUserRepo, stubHasher, mockMailRepo, mockInviteRepo.
No live server, no real SQLite file, no real SMTP.
Setup shared by every case
- Call
validator.InitValidator()once. - Use cases:
NewGetUserUseCase,NewCreateInviteUseCase,NewListUsersAndInvitesUseCase,NewCreateUserUseCase,NewAcceptInviteUseCaseover the fakes. - Router mirrors
NewUserRouter:jwtauth.Verifier+Authenticatorwithjwtauth.New("HS256", []byte("test-secret"), nil),RequireCurrentToken,RequireVerifiedUser,GET /, and a group withRequireOwner(getUser),TrustedProxyRealIP(nil),NewRateLimiter(2, time.Minute),POST /invite. A second router mirrorsNewAuthRouterfor/register,/invite/acceptand/me. - Seed: owner id 1 "marta" (role owner), admin id 2 "jonas" (role admin), both verified.
Cookies carry
user_idandtoken_version, and never a role.
Roles at creation
- Empty repo,
POST /v1/auth/register-> 200, the stored user hasRole == user.RoleOwner. - Pending invite with a known code (stubHasher),
POST /v1/auth/invite/accept-> 200, the stored user hasRole == user.RoleAdmin, and user 1 is still owner. - Use-case level:
CreateUserreturns a user withRoleOwner;AcceptInvitereturnsRoleAdmin.
GET /v1/auth/me
- Table over owner and admin: 200, decode into
map[string]json.RawMessage, keyroleequals the stored role. - Unverified owner -> 200,
role"owner",is_verifiedfalse. - The key set of the public user is exactly the eight fields, and
POST /v1/auth/verifyreturns the same eight.
GET /v1/user/
- Seed three users plus a pending invite. 200; user items have exactly the keys id, kind, username, display_name, email, role, status, created_at; email and role match the seed. The invite item has exactly id, kind, email, status, created_at. No forbidden key appears anywhere.
- Cookie of admin 2 -> 200.
POST /v1/user/invite
- Owner cookie, valid body -> 201, one invite, one "invitation" mail.
- Admin cookie, valid body -> 403, body exactly
apperr.OwnerRequiredErrorMessage,Content-Typeis not JSON-decoded (plain text), no invite, no mail. - Admin cookie with
{"email":"not-an-email"}and withnot json-> 403 both. - Rate limit 2: admin sends 3 requests -> 403, 403, 403.
- Flip user 2's stored role from owner to admin between two requests with the same cookie -> second request 403.
- Existing auth table from invitations.qa.md (no cookie 401, unverified 403, stale token 401) is
unchanged; the unverified 403 body remains
apperr.VerificationRequiredErrorMessage.
Use case level
RequireOwnerwith a user id that no longer exists -> 401apperr.UnauthorizedErrorMessage; with an unexpected repository error -> 500.
Manual verification (not exercised by the Go tests)
- Persistence backfill: copy a SQLite file from before this change with 3 users and no role column.
Start the app: the column exists, the lowest id is
owner, the othersadmin. Restart: nothing changes. Start against a fresh file: registering creates an owner. - Layering check by review:
Roleand the sentinel/constants live ininternal/domain/user; GORM tags only inpersistence/models, converted by the mapper.