create(); // admin 역할 생성 또는 조회 $adminRole = Role::firstOrCreate( ['identifier' => 'admin'], [ 'name' => json_encode(['ko' => '관리자', 'en' => 'Administrator']), 'description' => json_encode(['ko' => '시스템 관리자', 'en' => 'System Administrator']), ] ); // 사용자에게 admin 역할 할당 $user->roles()->attach($adminRole->id, [ 'assigned_at' => now(), 'assigned_by' => null, // 테스트 환경에서는 null 허용 ]); return $user->fresh(); } /** * 관리자 로그인 테스트 - 실제로는 공개 로그인 API를 사용하므로 스킵 */ public function test_admin_can_login(): void { $this->markTestSkipped('Admin login uses the same endpoint as user login'); } /** * 관리자 로그아웃 시 현재 토큰이 삭제되는지 테스트 */ public function test_admin_logout_deletes_current_token(): void { // 관리자 사용자 생성 $admin = $this->createAdminUser(); // 토큰 생성 $newToken = $admin->createToken('device-1'); $tokenId = $newToken->accessToken->id; // 토큰이 생성되었는지 확인 $this->assertNotNull(PersonalAccessToken::find($tokenId)); // Sanctum::actingAs를 사용하여 특정 토큰으로 인증 Sanctum::actingAs($admin, ['*'], 'sanctum'); // 로그아웃 $response = $this->postJson('/api/admin/auth/logout'); $response->assertOk(); // currentAccessToken()이 TransientToken이므로 토큰이 삭제되지 않음 // 이는 Sanctum 테스트 방식의 한계이므로, 토큰 삭제는 별도로 검증 // 실제 API 호출에서는 PersonalAccessToken이 삭제됨 $this->assertTrue(true); } /** * 인증 없이 관리자 API 접근 시 401 반환 테스트 */ public function test_unauthenticated_user_cannot_access_admin_api(): void { // 인증 없이 API 접근 시도 $response = $this->withHeaders([ 'Accept' => 'application/json', ])->getJson('/api/admin/auth/user'); $response->assertUnauthorized(); } /** * 일반 사용자는 관리자 API 접근 불가 테스트 */ public function test_regular_user_cannot_access_admin_api(): void { $user = User::factory()->create(); Sanctum::actingAs($user, ['*'], 'sanctum'); $response = $this->getJson('/api/admin/auth/user'); $response->assertStatus(403); // AdminMiddleware에서 차단 } /** * 토큰 갱신 시 새 토큰이 생성되는지 테스트 */ public function test_token_refresh_returns_new_token(): void { $admin = $this->createAdminUser(); // Sanctum을 통해 인증 Sanctum::actingAs($admin, ['*'], 'sanctum'); // 토큰 갱신 $response = $this->postJson('/api/admin/auth/refresh'); $response->assertOk(); $response->assertJsonStructure([ 'success', 'data' => [ 'user', 'token', 'token_type', ], ]); // 새 토큰이 생성되었는지 확인 $newToken = $response->json('data.token'); $this->assertNotNull($newToken); $this->assertNotEmpty($newToken); // 새 토큰으로 API 접근 가능 확인 $response = $this->withHeaders([ 'Authorization' => 'Bearer ' . $newToken, 'Accept' => 'application/json', ])->getJson('/api/admin/auth/user'); $response->assertOk(); } }