71 lines
4.2 KiB
Gherkin
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"
|