seed(RoleSeeder::class); $this->superAdmin = User::factory()->create(); $this->superAdmin->assignRole('super_admin'); $this->targetUser = User::factory()->create(); $this->otherSuperAdmin = User::factory()->create(); $this->otherSuperAdmin->assignRole('super_admin'); } // ─── Start ─────────────────────────────────────────────── public function test_start_creates_token_for_target_user(): void { Sanctum::actingAs($this->superAdmin); $response = $this->postJson("/api/v1/admin/impersonate/{$this->targetUser->id}"); $response->assertOk(); $response->assertJsonStructure([ 'data' => ['token', 'user' => ['id', 'email'], 'admin_id'], ]); $response->assertJsonPath('data.user.id', $this->targetUser->id); $response->assertJsonPath('data.admin_id', $this->superAdmin->id); $this->assertDatabaseHas('personal_access_tokens', [ 'tokenable_id' => $this->targetUser->id, 'name' => 'impersonation-by-' . $this->superAdmin->id, ]); } public function test_start_denied_for_non_super_admin(): void { Sanctum::actingAs($this->targetUser); $response = $this->postJson("/api/v1/admin/impersonate/{$this->targetUser->id}"); $response->assertForbidden(); } public function test_start_denied_when_target_is_super_admin(): void { Sanctum::actingAs($this->superAdmin); $response = $this->postJson("/api/v1/admin/impersonate/{$this->otherSuperAdmin->id}"); $response->assertForbidden(); } // ─── Stop ──────────────────────────────────────────────── public function test_stop_deletes_impersonation_token(): void { // Start impersonation Sanctum::actingAs($this->superAdmin); $startResponse = $this->postJson("/api/v1/admin/impersonate/{$this->targetUser->id}"); $token = $startResponse->json('data.token'); // Reset auth state so the Bearer token takes effect $this->app['auth']->forgetGuards(); $response = $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/v1/admin/stop-impersonation'); $response->assertOk(); $response->assertJsonPath('data.user.id', $this->superAdmin->id); $this->assertDatabaseMissing('personal_access_tokens', [ 'tokenable_id' => $this->targetUser->id, 'name' => 'impersonation-by-' . $this->superAdmin->id, ]); } // ─── Activity Log ──────────────────────────────────────── public function test_activity_log_records_start_and_stop(): void { Sanctum::actingAs($this->superAdmin); $startResponse = $this->postJson("/api/v1/admin/impersonate/{$this->targetUser->id}"); $token = $startResponse->json('data.token'); $this->assertDatabaseHas('activity_log', [ 'event' => 'admin.impersonation.started', 'causer_id' => $this->superAdmin->id, 'subject_id' => $this->targetUser->id, ]); // Reset auth state so the Bearer token takes effect $this->app['auth']->forgetGuards(); $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/v1/admin/stop-impersonation'); $this->assertDatabaseHas('activity_log', [ 'event' => 'admin.impersonation.stopped', 'subject_id' => $this->targetUser->id, ]); } }