for($tenant)->create(); $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'finding.resolved', 'status' => 'success', 'resource_type' => 'finding', 'resource_id' => (string) $finding->getKey(), 'target_label' => 'Drift finding #'.$finding->getKey(), 'summary' => 'Finding resolved for Drift finding #'.$finding->getKey(), 'metadata' => [ 'finding_id' => (int) $finding->getKey(), 'before_status' => Finding::STATUS_TRIAGED, 'after_status' => Finding::STATUS_RESOLVED, ], 'recorded_at' => now(), ]); $this->actingAs($user); Filament::setTenant(null, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::actingAs($user)->test(AuditLogPage::class) ->assertCanSeeTableRecords([$audit]) ->callTableAction('inspect', $audit) ->assertSet('selectedAuditLogId', (int) $audit->getKey()) ->assertSee('Drift finding #'.$finding->getKey()) ->assertSee('Open finding'); }); it('keeps deleted findings readable while suppressing finding drill-down links', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $finding = Finding::factory()->for($tenant)->create(); $findingId = (int) $finding->getKey(); $finding->delete(); $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'finding.closed', 'status' => 'success', 'resource_type' => 'finding', 'resource_id' => (string) $findingId, 'target_label' => 'Permission posture finding #'.$findingId, 'summary' => 'Finding closed for Permission posture finding #'.$findingId, 'metadata' => [ 'finding_id' => $findingId, 'before_status' => Finding::STATUS_REOPENED, 'after_status' => Finding::STATUS_CLOSED, 'closed_reason' => 'duplicate', ], 'recorded_at' => now(), ]); $this->actingAs($user); Filament::setTenant(null, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::actingAs($user)->test(AuditLogPage::class) ->assertCanSeeTableRecords([$audit]) ->callTableAction('inspect', $audit) ->assertSet('selectedAuditLogId', (int) $audit->getKey()) ->assertSee('Permission posture finding #'.$findingId) ->assertDontSee('Open finding'); }); it('does not render internal audit bookkeeping metadata in the inspection view', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $finding = Finding::factory()->for($tenant)->resolved()->create(); $audit = AuditLog::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'finding.closed', 'status' => 'success', 'resource_type' => 'finding', 'resource_id' => (string) $finding->getKey(), 'target_label' => 'Drift finding #'.$finding->getKey(), 'summary' => 'Finding closed for Drift finding #'.$finding->getKey(), 'metadata' => [ 'finding_id' => (int) $finding->getKey(), 'before_status' => Finding::STATUS_RESOLVED, 'after_status' => Finding::STATUS_CLOSED, '_actor_type' => 'hidden-actor-marker', '_dedupe_key' => 'internal-bookkeeping-marker', ], 'recorded_at' => now(), ]); $this->actingAs($user); Filament::setTenant(null, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::actingAs($user)->test(AuditLogPage::class) ->assertCanSeeTableRecords([$audit]) ->callTableAction('inspect', $audit) ->assertSet('selectedAuditLogId', (int) $audit->getKey()) ->assertDontSee('_dedupe_key') ->assertDontSee('internal-bookkeeping-marker') ->assertDontSee('_actor_type') ->assertDontSee('hidden-actor-marker'); }); it('hides finding audit rows for tenants outside the viewer entitlement scope', function (): void { [$user, $tenantA] = createUserWithTenant(role: 'owner'); $tenantB = Tenant::factory()->create([ 'workspace_id' => (int) $tenantA->workspace_id, ]); $findingA = Finding::factory()->for($tenantA)->create(); $findingB = Finding::factory()->for($tenantB)->create(); $visible = AuditLog::query()->create([ 'workspace_id' => (int) $tenantA->workspace_id, 'tenant_id' => (int) $tenantA->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'finding.triaged', 'status' => 'success', 'resource_type' => 'finding', 'resource_id' => (string) $findingA->getKey(), 'target_label' => 'Drift finding #'.$findingA->getKey(), 'summary' => 'Finding triaged for Drift finding #'.$findingA->getKey(), 'metadata' => [ 'finding_id' => (int) $findingA->getKey(), 'before_status' => Finding::STATUS_NEW, 'after_status' => Finding::STATUS_TRIAGED, ], 'recorded_at' => now(), ]); $hidden = AuditLog::query()->create([ 'workspace_id' => (int) $tenantB->workspace_id, 'tenant_id' => (int) $tenantB->getKey(), 'actor_email' => 'owner@example.com', 'actor_name' => 'Owner', 'actor_type' => 'human', 'action' => 'finding.reopened', 'status' => 'success', 'resource_type' => 'finding', 'resource_id' => (string) $findingB->getKey(), 'target_label' => 'Drift finding #'.$findingB->getKey(), 'summary' => 'Finding reopened for Drift finding #'.$findingB->getKey(), 'metadata' => [ 'finding_id' => (int) $findingB->getKey(), 'before_status' => Finding::STATUS_RESOLVED, 'after_status' => Finding::STATUS_REOPENED, ], 'recorded_at' => now(), ]); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenantA->workspace_id]) ->get(route('admin.monitoring.audit-log').'?event='.(int) $hidden->getKey()) ->assertNotFound(); $this->actingAs($user); Filament::setTenant(null, true); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); Livewire::actingAs($user)->test(AuditLogPage::class) ->assertCanSeeTableRecords([$visible]) ->assertCanNotSeeTableRecords([$hidden]); });