TenantAtlas/apps/platform/tests/Feature/System/OpsControls/AiExecutionOperationalControlTest.php
ahmido ff3392892b
Some checks failed
Main Confidence / confidence (push) Failing after 56s
Heavy Governance Lane / heavy-governance (push) Has been skipped
Browser Lane / browser (push) Has been skipped
Merge 248-private-ai-policy-foundation into dev (#288)
Automated PR: merge branch 248-private-ai-policy-foundation into dev (created by Copilot)

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #288
2026-04-27 21:18:37 +00:00

110 lines
3.9 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\System\Pages\Ops\Controls;
use App\Models\AuditLog;
use App\Models\OperationalControlActivation;
use App\Models\PlatformUser;
use App\Models\Tenant;
use App\Models\Workspace;
use App\Support\Audit\AuditActionId;
use App\Support\Auth\PlatformCapabilities;
use Filament\Actions\Action;
use Filament\Facades\Filament;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function (): void {
Filament::setCurrentPanel('system');
Filament::bootCurrentPanel();
});
function makeAiControlsManager(): PlatformUser
{
return PlatformUser::factory()->create([
'capabilities' => [
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
PlatformCapabilities::OPS_CONTROLS_MANAGE,
],
'is_active' => true,
]);
}
it('pauses and resumes ai execution through the global-only controls card', 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 = makeAiControlsManager();
$this->actingAs($user, 'platform');
$this->get(Controls::getUrl(panel: 'system'))
->assertSuccessful()
->assertSee("mountAction('pause_ai_execution')", escape: false);
$component = Livewire::test(Controls::class)
->assertActionExists('pause_ai_execution', fn (Action $action): bool => $action->isConfirmationRequired())
->assertActionExists('resume_ai_execution', fn (Action $action): bool => $action->isConfirmationRequired())
->assertActionExists('view_history_ai_execution', fn (Action $action): bool => $action->getLabel() === 'View AI execution history');
$summary = $component->instance()->controlSummary('ai.execution');
$preview = $component->instance()->scopeImpactPreview('ai.execution', 'global', null);
expect($summary['label'])->toBe('AI execution')
->and($summary['supported_scopes'])->toBe(['global'])
->and($summary['effective_state'])->toBe('enabled')
->and($preview['summary'])->toContain('AI execution')
->and($preview['workspace_count'])->toBe(2)
->and($preview['tenant_count'])->toBe(3);
$component
->callAction('pause_ai_execution', data: [
'scope_type' => 'global',
'reason_text' => 'Paused for AI rollout review.',
'expires_at' => now()->addDay()->toDateTimeString(),
])
->assertNotified('AI execution paused');
$activation = OperationalControlActivation::query()
->forControl('ai.execution')
->forGlobalScope()
->first();
expect($activation)->not->toBeNull()
->and($activation?->reason_text)->toBe('Paused for AI rollout review.');
$pausedSummary = $component->instance()->controlSummary('ai.execution');
expect($pausedSummary['effective_state'])->toBe('paused')
->and($pausedSummary['state_label'])->toBe('Paused globally');
$component
->callAction('resume_ai_execution', data: [
'scope_type' => 'global',
])
->assertNotified('AI execution resumed');
expect(OperationalControlActivation::query()
->forControl('ai.execution')
->forGlobalScope()
->count())->toBe(0);
$audits = AuditLog::query()
->whereIn('action', [
AuditActionId::OperationalControlPaused->value,
AuditActionId::OperationalControlResumed->value,
])
->where('metadata->control_key', 'ai.execution')
->orderBy('id')
->get();
expect($audits)->toHaveCount(2)
->and($audits[0]->workspace_id)->toBeNull()
->and($audits[1]->workspace_id)->toBeNull();
});