instance(); if ($instance->getCachedHeaderActions() === []) { $instance->cacheInteractsWithHeaderActions(); } return $instance->getCachedHeaderActions(); } function findingExceptionHeaderNames(Testable $component): array { return collect(findingExceptionHeaderActions($component)) ->reject(static fn ($action): bool => $action instanceof ActionGroup) ->map(static fn ($action): ?string => $action instanceof Action ? $action->getName() : null) ->filter() ->values() ->all(); } it('keeps finding navigation out of the header while preserving renewal and revocation actions', function (): void { [$requester, $tenant] = createUserWithTenant(role: 'owner'); $approver = User::factory()->create(); createUserWithTenant(tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager'); $finding = Finding::factory()->for($tenant)->create([ 'status' => Finding::STATUS_RISK_ACCEPTED, ]); /** @var FindingExceptionService $service */ $service = app(FindingExceptionService::class); $requested = $service->request($finding, $tenant, $requester, [ 'owner_user_id' => (int) $requester->getKey(), 'request_reason' => 'Existing compensating controls remain in place.', 'review_due_at' => now()->addDays(7)->toDateTimeString(), 'expires_at' => now()->addDays(14)->toDateTimeString(), ]); $exception = $service->approve($requested, $approver, [ 'effective_from' => now()->subDay()->toDateTimeString(), 'expires_at' => now()->addDays(14)->toDateTimeString(), 'approval_reason' => 'Accepted while remediation is scheduled.', ]); $this->actingAs($requester); Filament::setTenant($tenant, true); $component = Livewire::test(ViewFindingException::class, ['record' => $exception->getKey()]) ->assertActionVisible('renew_exception') ->assertActionVisible('revoke_exception') ->assertActionExists('revoke_exception', fn (Action $action): bool => $action->isConfirmationRequired()) ->assertSee('Related context') ->assertSee('Approval queue') ->assertSee('Open finding'); expect(findingExceptionHeaderNames($component)) ->toEqualCanonicalizing(['renew_exception', 'revoke_exception']) ->not->toContain('open_finding', 'open_approval_queue'); });