browser()->timeout(20_000); uses(RefreshDatabase::class); function spec194ApprovedFindingException(Tenant $tenant, User $requester): FindingException { $approver = User::factory()->create(); createUserWithTenant( tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); $finding = Finding::factory()->for($tenant)->create([ 'workspace_id' => (int) $tenant->workspace_id, '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' => 'Spec194 browser smoke request.', 'review_due_at' => now()->addDays(7)->toDateTimeString(), 'expires_at' => now()->addDays(14)->toDateTimeString(), ]); return $service->approve($requested, $approver, [ 'effective_from' => now()->subDay()->toDateTimeString(), 'expires_at' => now()->addDays(14)->toDateTimeString(), 'approval_reason' => 'Spec194 browser smoke approval.', ]); } function spec194SmokeLoginUrl(User $user, Tenant $tenant, string $redirect = ''): string { return route('admin.local.smoke-login', array_filter([ 'email' => $user->email, 'tenant' => $tenant->external_id, 'workspace' => $tenant->workspace->slug, 'redirect' => $redirect, ], static fn (?string $value): bool => filled($value))); } it('smokes tenant and admin governance semantics through modal entry points', function (): void { [$user, $tenant] = createUserWithTenant( role: 'owner', workspaceRole: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); $finding = Finding::factory()->for($tenant)->create(); $pendingException = 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' => 'Spec194 focused review queue smoke.', 'requested_at' => now()->subDay(), 'review_due_at' => now()->addDay(), 'evidence_summary' => ['reference_count' => 0], ]); $approvedException = spec194ApprovedFindingException($tenant, $user); $snapshotRun = OperationRun::factory()->forTenant($tenant)->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $snapshot = EvidenceSnapshot::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'operation_run_id' => (int) $snapshotRun->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), 'status' => EvidenceSnapshotStatus::Active->value, 'completeness_state' => EvidenceCompletenessState::Complete->value, 'summary' => ['finding_count' => 2], 'generated_at' => now(), ]); ReviewPack::factory()->ready()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $user->getKey(), ]); $review = composeTenantReviewForTest($tenant, $user, $snapshot); $review->forceFill([ 'status' => TenantReviewStatus::Ready->value, 'completeness_state' => TenantReviewCompletenessState::Complete->value, 'summary' => array_replace_recursive(is_array($review->summary) ? $review->summary : [], [ 'publish_blockers' => [], 'section_state_counts' => [ 'complete' => 6, 'partial' => 0, 'missing' => 0, 'stale' => 0, ], ]), ])->save(); $review = $review->refresh(); $archivedTenant = Tenant::factory()->archived()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'name' => 'Spec194 Archived Tenant', ]); createUserWithTenant( tenant: $archivedTenant, user: $user, role: 'owner', workspaceRole: 'manager', ensureDefaultMicrosoftProviderConnection: false, ); visit(spec194SmokeLoginUrl($user, $tenant)) ->waitForText('Dashboard') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs(); visit(FindingExceptionsQueue::getUrl(panel: 'admin').'?exception='.(int) $pendingException->getKey()) ->waitForText('Focused review lane') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Approve exception') ->assertSee('Reject exception'); visit(FindingExceptionResource::getUrl('view', ['record' => $approvedException], tenant: $tenant)) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Renew exception') ->assertSee('Revoke exception'); visit(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant)) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->click('Publish review') ->waitForText('Publication reason') ->click('Cancel') ->click('[aria-label="More"]') ->assertSee('Refresh review') ->assertSee('Export executive pack') ->click('[aria-label="Danger"]') ->click('Archive review') ->waitForText('Archive reason') ->click('Cancel') ->assertSee('Publish review') ->assertSee('Evidence snapshot'); visit(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshot], tenant: $tenant)) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->click('Refresh evidence') ->waitForText('Confirm') ->click('Cancel') ->click('Expire snapshot') ->waitForText('Expiry reason') ->click('Cancel') ->assertSee('Refresh evidence') ->assertSee('Expire snapshot'); visit(TenantResource::getUrl('view', ['record' => $tenant], panel: 'admin')) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->click('[aria-label="Lifecycle"]') ->click('Archive') ->waitForText('Archive reason') ->click('Cancel') ->assertSee('Lifecycle'); visit(TenantResource::getUrl('edit', ['record' => $tenant], panel: 'admin')) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Lifecycle'); visit(TenantResource::getUrl('view', ['record' => $archivedTenant], panel: 'admin')) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Lifecycle'); visit(TenantResource::getUrl('edit', ['record' => $archivedTenant], panel: 'admin')) ->waitForText('Related context') ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Lifecycle'); }); it('smokes system run triage semantics without javascript errors', function (): void { $failedRun = OperationRun::factory()->create([ 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Failed->value, 'type' => 'inventory_sync', ]); $runningRun = OperationRun::factory()->create([ 'status' => OperationRunStatus::Running->value, 'outcome' => OperationRunOutcome::Pending->value, 'type' => 'inventory_sync', 'created_at' => now()->subMinutes(15), 'started_at' => now()->subMinutes(10), ]); $platformUser = PlatformUser::factory()->create([ 'capabilities' => [ PlatformCapabilities::ACCESS_SYSTEM_PANEL, PlatformCapabilities::OPERATIONS_VIEW, PlatformCapabilities::OPERATIONS_MANAGE, ], 'is_active' => true, ]); auth('web')->logout(); $this->flushSession(); $this->actingAs($platformUser, 'platform'); visit(SystemOperationRunLinks::view($failedRun)) ->waitForText('Operation #'.(int) $failedRun->getKey()) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Retry') ->assertSee('Mark investigated') ->assertDontSee('Cancel'); visit(SystemOperationRunLinks::view($runningRun)) ->waitForText('Operation #'.(int) $runningRun->getKey()) ->assertNoJavaScriptErrors() ->assertNoConsoleLogs() ->assertSee('Mark investigated') ->assertSee('Cancel'); });