create([ 'capabilities' => [ PlatformCapabilities::ACCESS_SYSTEM_PANEL, PlatformCapabilities::OPS_CONTROLS_MANAGE, ], 'is_active' => true, ]); } it('returns 403 for platform users missing the operational controls capability', function (): void { $user = PlatformUser::factory()->create([ 'capabilities' => [PlatformCapabilities::ACCESS_SYSTEM_PANEL], 'is_active' => true, ]); $this->actingAs($user, 'platform') ->get(Controls::getUrl(panel: 'system')) ->assertForbidden(); }); it('renders compact card actions and only shows the action that matches the current control state', function (): void { $user = makeControlsManager(); $this->actingAs($user, 'platform'); $this->get(Controls::getUrl(panel: 'system')) ->assertSuccessful() ->assertSee("mountAction('pause_restore_execute')", escape: false) ->assertDontSee('Findings lifecycle backfill') ->assertDontSee("mountAction('pause_findings_lifecycle_backfill')", escape: false) ->assertDontSee("mountAction('resume_findings_lifecycle_backfill')", escape: false) ->assertDontSee("mountAction('view_history_findings_lifecycle_backfill')", escape: false) ->assertDontSee('Pause Restore execution') ->assertDontSee('Resume Restore execution'); OperationalControlActivation::factory()->forGlobalScope()->create([ 'control_key' => 'restore.execute', 'reason_text' => 'Paused for compact action rendering coverage.', ]); $this->get(Controls::getUrl(panel: 'system')) ->assertSuccessful() ->assertSee("mountAction('resume_restore_execute')", escape: false) ->assertDontSee("mountAction('pause_restore_execute')", escape: false) ->assertDontSee('Findings lifecycle backfill'); }); it('previews, pauses, updates, resumes, and exposes on-demand history for restore execution', function (): void { $workspaceA = Workspace::factory()->create(['name' => 'Acme']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo']); Tenant::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); Tenant::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); $user = makeControlsManager(); $this->actingAs($user, 'platform'); $component = Livewire::test(Controls::class) ->assertActionExists('pause_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired()) ->assertActionExists('resume_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired()) ->assertActionExists('view_history_restore_execute', fn (Action $action): bool => $action->getLabel() === 'View Restore execution history'); $preview = $component->instance()->scopeImpactPreview('restore.execute', 'global', null); expect($preview['workspace_count'])->toBe(2) ->and($preview['tenant_count'])->toBe(3) ->and($preview['summary'])->toContain('2 workspaces') ->and($preview['summary'])->toContain('3 tenants'); $component ->callAction('pause_restore_execute', data: [ 'scope_type' => 'global', 'reason_text' => 'Paused for incident review.', 'expires_at' => now()->addDay()->toDateTimeString(), ]) ->assertNotified('Restore execution paused'); $activation = OperationalControlActivation::query() ->forControl('restore.execute') ->forGlobalScope() ->first(); expect($activation)->not->toBeNull() ->and($activation?->reason_text)->toBe('Paused for incident review.'); $summary = $component->instance()->controlSummary('restore.execute'); expect($summary['effective_state'])->toBe('paused') ->and($summary['active_activations'])->toHaveCount(1) ->and($summary['active_activations'][0]['owner_name'])->toBe($user->name); $component ->callAction('pause_restore_execute', data: [ 'scope_type' => 'global', 'reason_text' => 'Updated incident review scope.', 'expires_at' => now()->addDays(2)->toDateTimeString(), ]) ->assertNotified('Restore execution updated'); expect($activation?->fresh()?->reason_text)->toBe('Updated incident review scope.'); $component ->callAction('resume_restore_execute', data: [ 'scope_type' => 'global', ]) ->assertNotified('Restore execution resumed'); expect(OperationalControlActivation::query() ->forControl('restore.execute') ->forGlobalScope() ->count())->toBe(0); $audits = AuditLog::query() ->whereIn('action', [ AuditActionId::OperationalControlPaused->value, AuditActionId::OperationalControlUpdated->value, AuditActionId::OperationalControlResumed->value, ]) ->where('metadata->control_key', 'restore.execute') ->orderBy('id') ->get(); expect($audits)->toHaveCount(3) ->and($audits->pluck('workspace_id')->unique()->all())->toBe([null]) ->and($audits->pluck('tenant_id')->unique()->all())->toBe([null]) ->and($audits[0]->action)->toBe(AuditActionId::OperationalControlPaused->value) ->and($audits[1]->action)->toBe(AuditActionId::OperationalControlUpdated->value) ->and($audits[2]->action)->toBe(AuditActionId::OperationalControlResumed->value); $component ->mountAction('view_history_restore_execute') ->assertActionMounted('view_history_restore_execute'); }); it('supports workspace-scoped pauses and removes expired conflicting activations before replacement writes', function (): void { $workspaceA = Workspace::factory()->create(['name' => 'Acme']); $workspaceB = Workspace::factory()->create(['name' => 'Bravo']); Tenant::factory()->count(2)->create(['workspace_id' => (int) $workspaceA->getKey()]); Tenant::factory()->count(1)->create(['workspace_id' => (int) $workspaceB->getKey()]); $expired = OperationalControlActivation::factory()->workspaceScoped()->create([ 'control_key' => 'restore.execute', 'workspace_id' => (int) $workspaceA->getKey(), 'reason_text' => 'Expired pause.', 'expires_at' => now()->subHour(), ]); $user = makeControlsManager(); $this->actingAs($user, 'platform'); $component = Livewire::test(Controls::class) ->assertActionExists('pause_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired()) ->assertActionExists('resume_restore_execute', fn (Action $action): bool => $action->isConfirmationRequired()); $preview = $component->instance()->scopeImpactPreview('restore.execute', 'workspace', (int) $workspaceA->getKey()); expect($preview['workspace_count'])->toBe(1) ->and($preview['tenant_count'])->toBe(2) ->and($preview['summary'])->toContain('Acme'); $component ->callAction('pause_restore_execute', data: [ 'scope_type' => 'workspace', 'workspace_id' => (int) $workspaceA->getKey(), 'reason_text' => 'Paused for workspace restore maintenance.', 'expires_at' => now()->addDay()->toDateTimeString(), ]) ->assertNotified('Restore execution paused'); expect(OperationalControlActivation::query()->whereKey((int) $expired->getKey())->exists())->toBeFalse(); $activation = OperationalControlActivation::query() ->forControl('restore.execute') ->forWorkspaceScope((int) $workspaceA->getKey()) ->notExpired() ->first(); expect($activation)->not->toBeNull() ->and((int) ($activation?->workspace_id ?? 0))->toBe((int) $workspaceA->getKey()); $component ->callAction('pause_restore_execute', data: [ 'scope_type' => 'workspace', 'workspace_id' => (int) $workspaceA->getKey(), 'reason_text' => 'Updated workspace restore maintenance.', 'expires_at' => now()->addDays(3)->toDateTimeString(), ]) ->assertNotified('Restore execution updated'); expect($activation?->fresh()?->reason_text)->toBe('Updated workspace restore maintenance.'); $component ->callAction('resume_restore_execute', data: [ 'scope_type' => 'workspace', 'workspace_id' => (int) $workspaceA->getKey(), ]) ->assertNotified('Restore execution resumed'); expect(OperationalControlActivation::query() ->forControl('restore.execute') ->forWorkspaceScope((int) $workspaceA->getKey()) ->count())->toBe(0); $audits = AuditLog::query() ->whereIn('action', [ AuditActionId::OperationalControlPaused->value, AuditActionId::OperationalControlUpdated->value, AuditActionId::OperationalControlResumed->value, ]) ->where('metadata->control_key', 'restore.execute') ->orderBy('id') ->get(); expect($audits)->toHaveCount(3) ->and($audits[0]->workspace_id)->toBe((int) $workspaceA->getKey()) ->and($audits[0]->tenant_id)->toBeNull(); });