create([ 'status' => 'active', 'name' => 'Alpha Tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); $finding = Finding::factory()->for($tenant)->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), 'status' => FindingException::STATUS_PENDING, 'current_validity_state' => FindingException::VALIDITY_MISSING_SUPPORT, 'request_reason' => 'Read only boundary test', 'requested_at' => now()->subDay(), 'review_due_at' => now()->addDay(), 'evidence_summary' => ['reference_count' => 0], ]); $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => FindingExceptionDecision::TYPE_REQUESTED, 'reason' => 'Read only boundary test', 'metadata' => [], 'decided_at' => now()->subDay(), ]); $exception->forceFill(['current_decision_id' => (int) $decision->getKey()])->save(); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(DecisionRegister::getUrl(panel: 'admin')) ->assertOk() ->assertSee('Open decision') ->assertDontSee('Approve exception') ->assertDontSee('Reject exception') ->assertDontSee('Renew exception') ->assertDontSee('Revoke exception'); }); it('omits terminal decisions outside the 30 calendar day recently closed window', function (): void { $tenant = Tenant::factory()->create([ 'status' => 'active', 'name' => 'Alpha Tenant', ]); [$user, $tenant] = createUserWithTenant($tenant, role: 'owner', workspaceRole: 'owner'); $createTerminalException = function (string $status, string $reason, int $daysAgo) use ($tenant, $user): FindingException { $finding = Finding::factory()->for($tenant)->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $exception = FindingException::query()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'finding_id' => (int) $finding->getKey(), 'requested_by_user_id' => (int) $user->getKey(), 'owner_user_id' => (int) $user->getKey(), 'status' => $status, 'current_validity_state' => $status === FindingException::STATUS_REJECTED ? FindingException::VALIDITY_REJECTED : FindingException::VALIDITY_REVOKED, 'request_reason' => 'Recently closed boundary test', 'review_due_at' => now()->subDays($daysAgo + 1), 'rejected_at' => $status === FindingException::STATUS_REJECTED ? now()->subDays($daysAgo) : null, 'revoked_at' => $status === FindingException::STATUS_REVOKED ? now()->subDays($daysAgo) : null, 'evidence_summary' => ['reference_count' => 0], ]); $decision = $exception->decisions()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'actor_user_id' => (int) $user->getKey(), 'decision_type' => $status === FindingException::STATUS_REJECTED ? FindingExceptionDecision::TYPE_REJECTED : FindingExceptionDecision::TYPE_REVOKED, 'reason' => $reason, 'metadata' => [], 'decided_at' => now()->subDays($daysAgo), ]); $exception->forceFill(['current_decision_id' => (int) $decision->getKey()])->save(); return $exception; }; $createTerminalException(FindingException::STATUS_REJECTED, 'Recent closure reason', 2); $createTerminalException(FindingException::STATUS_REVOKED, 'Old closure reason', 45); $this->actingAs($user) ->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id]) ->get(DecisionRegister::getUrl(panel: 'admin', parameters: ['register_state' => 'recently_closed'])) ->assertOk() ->assertSee('Recent closure reason') ->assertDontSee('Old closure reason'); });