actingAs($user); Filament::setTenant($tenant, true); return Livewire::actingAs($user)->test(AuditLogPage::class); } function auditLogPageTestRecord(?Tenant $tenant, array $attributes = []): AuditLogModel { $workspaceId = array_key_exists('workspace_id', $attributes) ? (int) $attributes['workspace_id'] : (int) ($tenant?->workspace_id ?? Workspace::factory()->create()->getKey()); return AuditLogModel::query()->create(array_merge([ 'workspace_id' => $workspaceId, 'tenant_id' => $tenant?->getKey(), 'actor_email' => 'auditor@example.com', 'actor_name' => 'Audit Operator', 'action' => 'operation.completed', 'status' => 'success', 'resource_type' => 'operation_run', 'resource_id' => '1', 'summary' => 'Operation completed', 'metadata' => [], 'recorded_at' => now(), ], $attributes)); } it('renders the canonical audit route as a summary-first monitoring surface', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('Summary-first audit history') ->assertSee('Review governance, operational, and workspace-admin events in reverse chronological order'); }); it('loads the audit page with populated filter options', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); auditLogPageTestRecord($tenant, [ 'action' => 'verification.completed', 'actor_name' => 'Ahmed Darrazi', 'resource_type' => 'tenant', 'resource_id' => (string) $tenant->getKey(), 'summary' => 'Verification completed', ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('Event type') ->assertSee('Actor') ->assertSee('Target type'); }); it('renders derived labels for audit rows that are missing evolved snapshot columns', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); DB::table('audit_logs')->insert([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_id' => null, 'actor_email' => 'spo_admin@yptw2.onmicrosoft.com', 'actor_name' => 'Ahmed Darrazi', 'action' => 'baseline.capture.started', 'resource_type' => 'baseline_profile', 'resource_id' => '2', 'status' => 'success', 'metadata' => json_encode([ 'baseline_profile_id' => 2, 'baseline_profile_name' => 'Device Compliance', ], JSON_THROW_ON_ERROR), 'recorded_at' => now(), 'created_at' => now(), 'updated_at' => now(), ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('Baseline capture started for Baseline profile #2') ->assertSee('Ahmed Darrazi') ->assertSee('Baseline profile #2') ->assertSee('Success'); }); it('renders workspace setting targets with readable labels', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); auditLogPageTestRecord($tenant, [ 'action' => 'workspace_setting.updated', 'summary' => 'Workspace setting updated for backup.retention_keep_last_default', 'resource_type' => 'workspace_setting', 'resource_id' => 'backup.retention_keep_last_default', 'target_label' => 'backup.retention_keep_last_default', ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(route('admin.monitoring.audit-log')) ->assertOk() ->assertSee('Workspace setting updated for Backup Retention Keep Last Default') ->assertSee('Backup Retention Keep Last Default'); }); it('shows reverse-chronological audit rows and supports summary search', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); $tenantB = Tenant::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant($tenantB, $user, role: 'owner'); $oldest = auditLogPageTestRecord($tenantA, [ 'resource_id' => '101', 'summary' => 'Older baseline capture completed', 'action' => 'baseline.capture.completed', 'recorded_at' => now()->subMinutes(15), ]); $middle = auditLogPageTestRecord($tenantB, [ 'resource_id' => '102', 'summary' => 'Rotate backup schedule credentials', 'action' => 'backup.updated', 'recorded_at' => now()->subMinutes(5), ]); $newest = auditLogPageTestRecord($tenantA, [ 'resource_id' => '103', 'summary' => 'Newest restore failed', 'action' => 'restore.failed', 'status' => 'failed', 'recorded_at' => now()->subMinute(), ]); auditLogPageTestComponent($user) ->assertOk() ->assertCanSeeTableRecords([$newest, $middle, $oldest], inOrder: true) ->searchTable('Rotate') ->assertCanSeeTableRecords([$middle]) ->assertCanNotSeeTableRecords([$newest, $oldest]); }); it('preselects the active tenant as the default audit filter', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); $tenantB = Tenant::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); createUserWithTenant($tenantB, $user, role: 'owner'); $visible = auditLogPageTestRecord($tenantA, [ 'resource_id' => '201', 'summary' => 'Tenant A verification completed', 'action' => 'verification.completed', ]); $hidden = auditLogPageTestRecord($tenantB, [ 'resource_id' => '202', 'summary' => 'Tenant B verification completed', 'action' => 'verification.completed', ]); auditLogPageTestComponent($user, $tenantA) ->assertSet('tableFilters.tenant_id.value', (string) $tenantA->getKey()) ->assertCanSeeTableRecords([$visible]) ->assertCanNotSeeTableRecords([$hidden]); }); it('shows a clear-filters empty state when no audit rows match the current view', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $record = auditLogPageTestRecord($tenant, [ 'summary' => 'Baseline compare completed', 'action' => 'baseline.compare.completed', ]); auditLogPageTestComponent($user) ->assertTableEmptyStateActionsExistInOrder(['clear_filters']) ->searchTable('no-such-audit-event') ->assertCountTableRecords(0) ->assertSee('No audit events match this view') ->assertSee('Clear filters') ->searchTable(null) ->assertCanSeeTableRecords([$record]); });