From 0ffc4b546cda017f376e0812820fb193b0185119 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Wed, 6 May 2026 22:12:27 +0300 Subject: [PATCH] test auth controller signup, confirm-email, login, me, logout --- backend/tests/Feature/Auth/AuthFlowTest.php | 161 ++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 backend/tests/Feature/Auth/AuthFlowTest.php diff --git a/backend/tests/Feature/Auth/AuthFlowTest.php b/backend/tests/Feature/Auth/AuthFlowTest.php new file mode 100644 index 0000000..ceab2f3 --- /dev/null +++ b/backend/tests/Feature/Auth/AuthFlowTest.php @@ -0,0 +1,161 @@ +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()); + } +}