diff --git a/backend/tests/Unit/User/UseCases/SignupUserTest.php b/backend/tests/Unit/User/UseCases/SignupUserTest.php new file mode 100644 index 0000000..1ae841e --- /dev/null +++ b/backend/tests/Unit/User/UseCases/SignupUserTest.php @@ -0,0 +1,133 @@ +userRepo = new FakeUserRepository; + $this->hasher = new FakePasswordHasher; + $this->useCase = new SignupUser( + $this->userRepo, + $this->hasher, + ); + } + + public function test_null_email_throws_bad_request(): void + { + $this->expectException(BadRequestException::class); + $this->useCase->execute(new SignupUserRequest( + email: null, + password: 'longenoughpassword', + )); + } + + public function test_empty_email_throws_bad_request(): void + { + $this->expectException(BadRequestException::class); + $this->useCase->execute(new SignupUserRequest( + email: '', + password: 'longenoughpassword', + )); + } + + public function test_invalid_email_format_throws_bad_request(): void + { + $this->expectException(BadRequestException::class); + $this->useCase->execute(new SignupUserRequest( + email: 'not-an-email', + password: 'longenoughpassword', + )); + } + + public function test_null_password_throws_bad_request(): void + { + $this->expectException(BadRequestException::class); + $this->useCase->execute(new SignupUserRequest( + email: 'user@example.com', + password: null, + )); + } + + public function test_short_password_throws_bad_request(): void + { + $this->expectException(BadRequestException::class); + $this->useCase->execute(new SignupUserRequest( + email: 'user@example.com', + password: 'short', + )); + } + + public function test_duplicate_email_throws_domain_exception(): void + { + $this->userRepo->create(new CreateUserDto( + email: new EmailAddress('user@example.com'), + passwordHash: $this->hasher->hash('original-password'), + isAdmin: false, + )); + + $this->expectException(DomainException::class); + $this->useCase->execute(new SignupUserRequest( + email: 'user@example.com', + password: 'second-attempt-password', + )); + } + + public function test_valid_signup_returns_user_with_hashed_password(): void + { + $created = $this->useCase->execute(new SignupUserRequest( + email: 'new@example.com', + password: 'longenoughpassword', + )); + + $this->assertInstanceOf(User::class, $created); + $this->assertSame('new@example.com', $created->getEmail()->value()); + $this->assertSame( + $this->hasher->hash('longenoughpassword'), + $created->getPasswordHash(), + ); + $this->assertFalse($created->isAdmin()); + } + + public function test_created_user_is_findable_by_email(): void + { + $created = $this->useCase->execute(new SignupUserRequest( + email: 'lookup@example.com', + password: 'longenoughpassword', + )); + + $found = $this->userRepo->findByEmail( + new EmailAddress('lookup@example.com') + ); + $this->assertNotNull($found); + $this->assertSame($created->getId(), $found->getId()); + } + + public function test_signup_normalizes_email_domain(): void + { + $created = $this->useCase->execute(new SignupUserRequest( + email: 'Mixed@CASE.com', + password: 'longenoughpassword', + )); + + $this->assertSame('Mixed@case.com', $created->getEmail()->value()); + } +}