postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ]); $response->assertStatus(201); $userRepo = $this->app->make(UserRepository::class); $user = $userRepo->findByEmail( new EmailAddress('alice@example.com'), ); $this->assertNotNull($user); $this->assertFalse($user->isEmailConfirmed()); } public function test_signup_validation_returns_400(): void { $response = $this->postJson('/api/signup', [ 'email' => '', 'displayName' => 'alice', ]); $response->assertStatus(400); } public function test_duplicate_signup_returns_409(): void { $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ])->assertStatus(201); $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'aliceb', ])->assertStatus(409); } public function test_confirm_email_then_login_returns_user_and_cookie(): void { $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ])->assertStatus(201); $userRepo = $this->app->make(UserRepository::class); $user = $userRepo->findByEmail( new EmailAddress('alice@example.com'), ); $tokenRepo = $this->app->make( EmailConfirmationTokenRepository::class, ); $token = $tokenRepo->findByUser($user); $this->assertNotNull($token); $this->postJson('/api/confirm-email', [ 'token' => $token->getToken(), 'password' => 'longenoughpassword', ])->assertStatus(200); $loginResponse = $this->postJson('/api/login', [ 'email' => 'alice@example.com', 'password' => 'longenoughpassword', ]); $loginResponse->assertStatus(200); $loginResponse->assertJsonPath('user.email', 'alice@example.com'); $loginResponse->assertJsonPath('user.displayName', 'alice'); $loginResponse->assertJsonPath('user.isAdmin', false); $loginResponse->assertCookie('auth_token'); } public function test_login_with_unconfirmed_account_returns_401(): void { $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ])->assertStatus(201); $this->postJson('/api/login', [ 'email' => 'alice@example.com', 'password' => 'longenoughpassword', ])->assertStatus(401); } public function test_login_with_wrong_password_returns_401(): void { $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ])->assertStatus(201); $userRepo = $this->app->make(UserRepository::class); $user = $userRepo->findByEmail( new EmailAddress('alice@example.com'), ); $tokenRepo = $this->app->make( EmailConfirmationTokenRepository::class, ); $token = $tokenRepo->findByUser($user); $this->postJson('/api/confirm-email', [ 'token' => $token->getToken(), 'password' => 'longenoughpassword', ])->assertStatus(200); $this->postJson('/api/login', [ 'email' => 'alice@example.com', 'password' => 'wrongpassword', ])->assertStatus(401); } public function test_me_requires_auth_cookie(): void { $this->getJson('/api/me')->assertStatus(401); } public function test_login_sets_auth_cookie_on_response(): void { $this->postJson('/api/signup', [ 'email' => 'alice@example.com', 'displayName' => 'alice', ])->assertStatus(201); $userRepo = $this->app->make(UserRepository::class); $user = $userRepo->findByEmail( new EmailAddress('alice@example.com'), ); $tokenRepo = $this->app->make( EmailConfirmationTokenRepository::class, ); $token = $tokenRepo->findByUser($user); $this->postJson('/api/confirm-email', [ 'token' => $token->getToken(), 'password' => 'longenoughpassword', ])->assertStatus(200); $loginResponse = $this->postJson('/api/login', [ 'email' => 'alice@example.com', 'password' => 'longenoughpassword', ]); $loginResponse->assertStatus(200); $authCookie = $loginResponse->getCookie('auth_token', false); $this->assertNotNull($authCookie); $this->assertNotEmpty($authCookie->getValue()); } }