Files
RenewCMS/features/unverified_users_and_reregistration.feature

71 lines
4.2 KiB
Gherkin

Feature: Several unverified users can coexist, and deleting a user frees its username and email
As the maintainer of RenewCMS
I want an absent password reset code or verification code stored as no value instead of an empty
string, and a deleted user's row actually removed
So that several unverified users can register one after another without colliding on the unique
reset-code column, and so that deleting a user lets the same username and email register again
Background:
Given internal/infrastructure/persistence/models.User stores PasswordResetCode and VerificationCode
as nullable, unique columns, so a domain value of "" is persisted as no value (SQL NULL), and SQL
NULL is exempt from the unique constraint
And internal/infrastructure/persistence/mappers.UserToModel maps a domain "" for PasswordResetCode or
VerificationCode to no value, and UserToDomain maps no value back to ""
And internal/infrastructure/persistence/models.User no longer embeds gorm.Model, so
UserRepository.Delete removes the row instead of leaving a soft-deleted row that still occupies the
unique username and email
And POST /v1/auth/register is public, and CreateUser stores a new user with is_verified false and
PasswordResetCode "" as soon as the request is valid
And Register only answers 403 once at least one existing user is verified (SomeUsersVerified), never
because the user table already has rows
And DeleteUser has no handler mounted in api/router.go today, so deletion in these scenarios is
exercised through UserRepository.Delete / DeleteUserUseCase.DeleteUser directly, not through an
HTTP route
Scenario: Two unverified users can register one after another without a reset-code collision
Given the user repository is empty
When the client sends POST /v1/auth/register with username "alice", password "hunter2example12",
email "alice@example.com"
Then the response status is 200
And a jwt cookie is set
When the client sends POST /v1/auth/register with username "bob", password "hunter2example12",
email "bob@example.com"
Then the response status is 200
And a jwt cookie is set
And the user repository contains both "alice" and "bob", each with is_verified false and an empty
password reset code
Scenario: Creating two users with no active reset code does not violate the unique constraint
Given a repository backed by an in-memory SQLite database with models.User migrated
When Create is called with username "alice", email "alice@example.com", password_reset_code "" and
verification_code "code-alice"
And Create is called with username "bob", email "bob@example.com", password_reset_code "" and
verification_code "code-bob"
Then both calls succeed
And GetByUsername "alice" and GetByUsername "bob" each return password_reset_code ""
Scenario: The unique constraint still rejects two users sharing the same active reset code
Given a repository backed by an in-memory SQLite database containing a user "alice" with
password_reset_code "shared-code"
When Create is called with username "bob", email "bob@example.com" and password_reset_code
"shared-code"
Then the Create call returns an error
And GetByUsername "bob" still returns user.ErrUserNotFound
Scenario: Deleting a user removes the row so the same username and email can register again
Given a repository backed by an in-memory SQLite database containing a user with id 1, username
"alice" and email "alice@example.com"
When Delete is called with id 1
And Create is called with username "alice", email "alice@example.com" and a new password
Then the Create call succeeds
And the newly created user's id is different from 1
And Get with id 1 returns user.ErrUserNotFound
Scenario: Registering the same username while the first account still exists is still rejected
Given a repository backed by an in-memory SQLite database containing a user with username "alice"
and email "alice@example.com"
When Create is called with username "alice", email "someone-else@example.com" and a new password
Then the Create call returns an error
And the user repository still contains exactly one user with username "alice"