3.6 KiB
3.6 KiB
QA procedure: unverified_users_and_reregistration
Package: test (black-box), extending test/user_test.go (mockUserRepo) and reusing the
openInMemoryDb(t) helper from test/not_found_errors_test.go.
Setup shared by every case
- Call
validator.InitValidator()once. - Repository-level checks use
openInMemoryDb(t),db.AutoMigrate(&models.User{}), and a realpersistence.NewUserRepository(db). - HTTP-level checks use
mockUserRepo(fromtest/user_test.go) wired intouseCases.NewCreateUserUseCase(repo, &hashing.BcryptHasher{}),useCases.NewListUsersUseCase(repo),useCases.NewGetUserUseCase(repo),useCases.NewAuthenticateUserUseCase(repo, ...), andauth.NewHandler(...)with a testjwtauth.New("HS256", []byte("test-secret"), nil). MountPOST /v1/auth/registerandPOST /v1/auth/loginunprotected on a freshchi.NewRouter(), mirroringapi/router.go. No live server.
Repository-level checks (real persistence repository, in-memory SQLite, no HTTP)
- On an empty repository,
Createa user "alice"/"alice@example.com" withPasswordResetCode: ""andVerificationCode: "code-alice"→ asserterr == nil.Createa second user "bob"/"bob@example.com" withPasswordResetCode: ""andVerificationCode: "code-bob"→ asserterr == nil(regression: before the fix this fails with a SQLiteUNIQUE constraint failed: users.password_reset_codeerror). ThenGetByUsername("alice")andGetByUsername("bob")→ assertPasswordResetCode == ""for both. Createa user "alice" withPasswordResetCode: "shared-code".Createa user "bob" with the samePasswordResetCode: "shared-code"→ asserterr != nil(the unique constraint still applies to an actual shared value). AssertGetByUsername("bob")returnsuser.ErrUserNotFound(the row was never created).Createa user "alice"/"alice@example.com", capture its id.Delete(id)→ asserterr == nil.Createa new user with the same username "alice" and email "alice@example.com" (a different password and verification code) → asserterr == nil(regression: before the fix this fails with a SQLiteUNIQUE constraint failed: users.usernameerror because the row was only soft-deleted). Assert the new user's id differs from the deleted one. AssertGet(deletedId)returnsuser.ErrUserNotFound.Createa user "alice"/"alice@example.com" and do not delete it.Createa second user with username "alice" and a different email → asserterr != nil(unchanged: still rejected while the row is live).
HTTP checks (fakes, per the shared setup above)
POST /v1/auth/registerwith{"username":"alice","password":"hunter2example12","email":"alice@example.com"}against an emptymockUserRepo→ assert status200, aSet-Cookie: jwt=...header present, body decodes to{"message":"User registered! HTTPonly jwt cookie created"}.POST /v1/auth/registeragain with{"username":"bob","password":"hunter2example12","email":"bob@example.com"}(repo now holds unverified "alice") → assert status200and aSet-Cookie: jwt=...header present (register stays allowed because no user is verified yet).- Assert
mockUserRepo.usersholds two entries, bothIsVerified == falseand bothPasswordResetCode == "".
Manual verification (not exercised by the Go test)
- None.
DeleteUserhas no HTTP route mounted today, so there is no SPA-visible delete-and-re-register flow to check by hand, andCreateUserdoes not call the mailer, so there is no SMTP involvement in this slice.