create([ 'role' => UserRole::Owner, 'password' => bcrypt('secret1234'), ]); $response = $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'secret1234', 'device_name' => 'iphone-15', ]); $response->assertOk(); $response->assertJsonStructure(['token', 'user' => ['id', 'name', 'email', 'role']]); $this->assertDatabaseHas('personal_access_tokens', [ 'tokenable_id' => $user->id, 'name' => 'iphone-15', ]); } public function test_login_rejects_wrong_password(): void { $user = User::factory()->create(['password' => bcrypt('secret1234')]); $response = $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'wrong-password', 'device_name' => 'iphone-15', ]); $response->assertStatus(422); $response->assertJsonValidationErrors('email'); } public function test_authenticated_token_can_reach_protected_route(): void { $user = User::factory()->create(['password' => bcrypt('secret1234')]); $token = $this->postJson('/api/v1/login', [ 'email' => $user->email, 'password' => 'secret1234', 'device_name' => 'iphone-15', ])->json('token'); $this->withHeader('Authorization', "Bearer {$token}") ->getJson('/api/v1/me') ->assertOk() ->assertJsonPath('data.email', $user->email); } public function test_logout_revokes_the_current_token(): void { $user = User::factory()->create(['password' => bcrypt('secret1234')]); $tokenModel = $user->createToken('iphone-15'); $this->withHeader('Authorization', "Bearer {$tokenModel->plainTextToken}") ->postJson('/api/v1/logout') ->assertNoContent(); $this->assertDatabaseMissing('personal_access_tokens', ['id' => $tokenModel->accessToken->id]); } public function test_guest_cannot_reach_protected_route(): void { $this->getJson('/api/v1/me')->assertUnauthorized(); } }