test SignupUser displayname requirement

Adds displayname to existing assertions and new tests covering:
null/short/invalid-charset displayname, duplicate displayname,
findability by displayname. AuthenticateUser tests pick up the
seedUser displayname argument.
This commit is contained in:
Yisroel Baum 2026-05-06 22:03:40 +03:00
parent 298b8634ec
commit 4829a02aac
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
2 changed files with 80 additions and 0 deletions

View file

@ -33,13 +33,16 @@ class AuthenticateUserTest extends TestCase
private function seedUser( private function seedUser(
string $email, string $email,
string $displayName,
string $password, string $password,
bool $isAdmin, bool $isAdmin,
): User { ): User {
return $this->userRepo->create(new CreateUserDto( return $this->userRepo->create(new CreateUserDto(
email: new EmailAddress($email), email: new EmailAddress($email),
displayName: $displayName,
passwordHash: $this->hasher->hash($password), passwordHash: $this->hasher->hash($password),
isAdmin: $isAdmin, isAdmin: $isAdmin,
emailConfirmedAt: null,
)); ));
} }
@ -101,6 +104,7 @@ class AuthenticateUserTest extends TestCase
{ {
$this->seedUser( $this->seedUser(
email: 'user@example.com', email: 'user@example.com',
displayName: 'user',
password: 'correctpassword', password: 'correctpassword',
isAdmin: false, isAdmin: false,
); );
@ -116,6 +120,7 @@ class AuthenticateUserTest extends TestCase
{ {
$seeded = $this->seedUser( $seeded = $this->seedUser(
email: 'user@example.com', email: 'user@example.com',
displayName: 'user',
password: 'correctpassword', password: 'correctpassword',
isAdmin: false, isAdmin: false,
); );
@ -140,6 +145,7 @@ class AuthenticateUserTest extends TestCase
{ {
$this->seedUser( $this->seedUser(
email: 'admin@example.com', email: 'admin@example.com',
displayName: 'admin',
password: 'adminpassword', password: 'adminpassword',
isAdmin: true, isAdmin: true,
); );

View file

@ -36,6 +36,7 @@ class SignupUserTest extends TestCase
$this->expectException(BadRequestException::class); $this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: null, email: null,
displayName: 'alice',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));
} }
@ -45,6 +46,7 @@ class SignupUserTest extends TestCase
$this->expectException(BadRequestException::class); $this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: '', email: '',
displayName: 'alice',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));
} }
@ -54,6 +56,37 @@ class SignupUserTest extends TestCase
$this->expectException(BadRequestException::class); $this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: 'not-an-email', email: 'not-an-email',
displayName: 'alice',
password: 'longenoughpassword',
));
}
public function test_null_display_name_throws_bad_request(): void
{
$this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest(
email: 'user@example.com',
displayName: null,
password: 'longenoughpassword',
));
}
public function test_short_display_name_throws_bad_request(): void
{
$this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest(
email: 'user@example.com',
displayName: 'ab',
password: 'longenoughpassword',
));
}
public function test_display_name_with_invalid_chars_throws(): void
{
$this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest(
email: 'user@example.com',
displayName: 'Has Spaces',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));
} }
@ -63,6 +96,7 @@ class SignupUserTest extends TestCase
$this->expectException(BadRequestException::class); $this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: 'user@example.com', email: 'user@example.com',
displayName: 'alice',
password: null, password: null,
)); ));
} }
@ -72,6 +106,7 @@ class SignupUserTest extends TestCase
$this->expectException(BadRequestException::class); $this->expectException(BadRequestException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: 'user@example.com', email: 'user@example.com',
displayName: 'alice',
password: 'short', password: 'short',
)); ));
} }
@ -80,13 +115,34 @@ class SignupUserTest extends TestCase
{ {
$this->userRepo->create(new CreateUserDto( $this->userRepo->create(new CreateUserDto(
email: new EmailAddress('user@example.com'), email: new EmailAddress('user@example.com'),
displayName: 'first',
passwordHash: $this->hasher->hash('original-password'), passwordHash: $this->hasher->hash('original-password'),
isAdmin: false, isAdmin: false,
emailConfirmedAt: null,
)); ));
$this->expectException(DomainException::class); $this->expectException(DomainException::class);
$this->useCase->execute(new SignupUserRequest( $this->useCase->execute(new SignupUserRequest(
email: 'user@example.com', email: 'user@example.com',
displayName: 'second',
password: 'second-attempt-password',
));
}
public function test_duplicate_display_name_throws_domain_exception(): void
{
$this->userRepo->create(new CreateUserDto(
email: new EmailAddress('first@example.com'),
displayName: 'taken',
passwordHash: $this->hasher->hash('original-password'),
isAdmin: false,
emailConfirmedAt: null,
));
$this->expectException(DomainException::class);
$this->useCase->execute(new SignupUserRequest(
email: 'second@example.com',
displayName: 'taken',
password: 'second-attempt-password', password: 'second-attempt-password',
)); ));
} }
@ -95,22 +151,26 @@ class SignupUserTest extends TestCase
{ {
$created = $this->useCase->execute(new SignupUserRequest( $created = $this->useCase->execute(new SignupUserRequest(
email: 'new@example.com', email: 'new@example.com',
displayName: 'newuser',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));
$this->assertInstanceOf(User::class, $created); $this->assertInstanceOf(User::class, $created);
$this->assertSame('new@example.com', $created->getEmail()->value()); $this->assertSame('new@example.com', $created->getEmail()->value());
$this->assertSame('newuser', $created->getDisplayName());
$this->assertSame( $this->assertSame(
$this->hasher->hash('longenoughpassword'), $this->hasher->hash('longenoughpassword'),
$created->getPasswordHash(), $created->getPasswordHash(),
); );
$this->assertFalse($created->isAdmin()); $this->assertFalse($created->isAdmin());
$this->assertFalse($created->isEmailConfirmed());
} }
public function test_created_user_is_findable_by_email(): void public function test_created_user_is_findable_by_email(): void
{ {
$created = $this->useCase->execute(new SignupUserRequest( $created = $this->useCase->execute(new SignupUserRequest(
email: 'lookup@example.com', email: 'lookup@example.com',
displayName: 'lookup',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));
@ -121,10 +181,24 @@ class SignupUserTest extends TestCase
$this->assertSame($created->getId(), $found->getId()); $this->assertSame($created->getId(), $found->getId());
} }
public function test_created_user_is_findable_by_display_name(): void
{
$created = $this->useCase->execute(new SignupUserRequest(
email: 'lookup@example.com',
displayName: 'lookupbyname',
password: 'longenoughpassword',
));
$found = $this->userRepo->findByDisplayName('lookupbyname');
$this->assertNotNull($found);
$this->assertSame($created->getId(), $found->getId());
}
public function test_signup_normalizes_email_domain(): void public function test_signup_normalizes_email_domain(): void
{ {
$created = $this->useCase->execute(new SignupUserRequest( $created = $this->useCase->execute(new SignupUserRequest(
email: 'Mixed@CASE.com', email: 'Mixed@CASE.com',
displayName: 'mixed',
password: 'longenoughpassword', password: 'longenoughpassword',
)); ));