- land the spec 192 resource, guard, browser smoke, and documentation changes - add unhandled rejection request correlation for 419 diagnostics - disable panel-wide database notification polling and cover it with focused tests
301 lines
12 KiB
PHP
301 lines
12 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Resources\AlertDestinationResource;
|
|
use App\Filament\Resources\BackupSetResource;
|
|
use App\Filament\Resources\BaselineProfileResource;
|
|
use App\Filament\Resources\BaselineSnapshotResource;
|
|
use App\Filament\Resources\EvidenceSnapshotResource;
|
|
use App\Filament\Resources\FindingExceptionResource;
|
|
use App\Filament\Resources\PolicyVersionResource;
|
|
use App\Filament\Resources\ReviewPackResource;
|
|
use App\Filament\Resources\TenantResource;
|
|
use App\Filament\Resources\TenantReviewResource;
|
|
use App\Filament\Resources\Workspaces\WorkspaceResource;
|
|
use App\Models\AlertDestination;
|
|
use App\Models\BackupSet;
|
|
use App\Models\BaselineProfile;
|
|
use App\Models\BaselineSnapshot;
|
|
use App\Models\BaselineSnapshotItem;
|
|
use App\Models\EvidenceSnapshot;
|
|
use App\Models\Finding;
|
|
use App\Models\OperationRun;
|
|
use App\Models\Policy;
|
|
use App\Models\PolicyVersion;
|
|
use App\Models\ReviewPack;
|
|
use App\Models\Tenant;
|
|
use App\Models\User;
|
|
use App\Services\Findings\FindingExceptionService;
|
|
use App\Support\Evidence\EvidenceCompletenessState;
|
|
use App\Support\Evidence\EvidenceSnapshotStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
|
|
pest()->browser()->timeout(20_000);
|
|
|
|
function spec192ApprovedFindingException(Tenant $tenant, User $requester)
|
|
{
|
|
$approver = User::factory()->create();
|
|
createUserWithTenant(tenant: $tenant, user: $approver, role: 'owner', workspaceRole: 'manager');
|
|
|
|
$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' => 'Browser smoke test exception 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' => 'Browser smoke approval.',
|
|
]);
|
|
}
|
|
|
|
it('smokes remediated standard record pages with contextual navigation and one clear next step', function (): void {
|
|
$tenant = Tenant::factory()->active()->create([
|
|
'name' => 'Spec192 Browser Tenant',
|
|
]);
|
|
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$onboardingTenant = Tenant::factory()->onboarding()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'name' => 'Spec192 Browser Onboarding Tenant',
|
|
]);
|
|
createUserWithTenant(
|
|
tenant: $onboardingTenant,
|
|
user: $user,
|
|
role: 'owner',
|
|
workspaceRole: 'owner',
|
|
ensureDefaultMicrosoftProviderConnection: false,
|
|
);
|
|
|
|
createOnboardingDraft([
|
|
'workspace' => $onboardingTenant->workspace,
|
|
'tenant' => $onboardingTenant,
|
|
'started_by' => $user,
|
|
'updated_by' => $user,
|
|
'state' => [
|
|
'entra_tenant_id' => (string) $onboardingTenant->tenant_id,
|
|
'tenant_name' => (string) $onboardingTenant->name,
|
|
],
|
|
]);
|
|
|
|
$profile = BaselineProfile::factory()->active()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'name' => 'Spec192 Browser Baseline',
|
|
]);
|
|
|
|
$baselineSnapshot = BaselineSnapshot::factory()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'baseline_profile_id' => (int) $profile->getKey(),
|
|
]);
|
|
|
|
$profile->update(['active_snapshot_id' => (int) $baselineSnapshot->getKey()]);
|
|
|
|
\App\Models\BaselineTenantAssignment::factory()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'baseline_profile_id' => (int) $profile->getKey(),
|
|
]);
|
|
|
|
$run = 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) $run->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(),
|
|
]);
|
|
|
|
$exception = spec192ApprovedFindingException($tenant, $user);
|
|
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
|
|
|
|
$this->actingAs($user)->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
|
|
|
visit(BaselineProfileResource::getUrl('view', ['record' => $profile], panel: 'admin'))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Review compare matrix')
|
|
->assertSee('Compare now');
|
|
|
|
visit(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshot], tenant: $tenant))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Review pack')
|
|
->assertSee('Refresh evidence');
|
|
|
|
visit(FindingExceptionResource::getUrl('view', ['record' => $exception], tenant: $tenant))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Open finding')
|
|
->assertSee('Renew exception');
|
|
|
|
visit(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Artifact truth')
|
|
->assertSee('Evidence snapshot');
|
|
|
|
visit(TenantResource::getUrl('edit', ['record' => $onboardingTenant], panel: 'admin'))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Resume onboarding')
|
|
->assertSee('Open tenant detail');
|
|
});
|
|
|
|
it('smokes the explicit workflow-heavy tenant detail exception without javascript errors', function (): void {
|
|
$tenant = Tenant::factory()->active()->create([
|
|
'name' => 'Spec192 Workflow Tenant',
|
|
]);
|
|
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
|
|
$this->actingAs($user)->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
|
|
|
visit(TenantResource::getUrl('view', ['record' => $tenant], panel: 'admin'))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length === 0", true)
|
|
->assertSee('Edit tenant')
|
|
->assertSee('Open provider connections');
|
|
});
|
|
|
|
it('smokes the compliant reference baseline without header regressions or javascript errors', function (): void {
|
|
$tenant = Tenant::factory()->active()->create([
|
|
'name' => 'Spec192 Reference Tenant',
|
|
]);
|
|
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner', ensureDefaultMicrosoftProviderConnection: false);
|
|
$workspace = $tenant->workspace;
|
|
|
|
$profile = BaselineProfile::factory()->active()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'name' => 'Spec192 Reference Baseline',
|
|
]);
|
|
|
|
$baselineSnapshot = BaselineSnapshot::factory()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'baseline_profile_id' => (int) $profile->getKey(),
|
|
]);
|
|
|
|
$profile->update(['active_snapshot_id' => (int) $baselineSnapshot->getKey()]);
|
|
|
|
$policy = Policy::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'display_name' => 'Spec192 Browser Policy',
|
|
]);
|
|
|
|
$version = PolicyVersion::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'policy_id' => (int) $policy->getKey(),
|
|
'baseline_profile_id' => (int) $profile->getKey(),
|
|
'version_number' => 4,
|
|
]);
|
|
|
|
BaselineSnapshotItem::factory()->create([
|
|
'baseline_snapshot_id' => (int) $baselineSnapshot->getKey(),
|
|
'meta_jsonb' => [
|
|
'display_name' => 'Spec192 Browser Policy',
|
|
'version_reference' => [
|
|
'policy_version_id' => (int) $version->getKey(),
|
|
],
|
|
],
|
|
]);
|
|
|
|
$backupSet = BackupSet::factory()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'name' => 'Spec192 Browser Backup',
|
|
]);
|
|
|
|
OperationRun::factory()->forTenant($tenant)->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'type' => 'backup_set.add_policies',
|
|
'context' => [
|
|
'backup_set_id' => (int) $backupSet->getKey(),
|
|
],
|
|
]);
|
|
|
|
$reviewSnapshot = seedTenantReviewEvidence($tenant);
|
|
$review = composeTenantReviewForTest($tenant, $user, $reviewSnapshot);
|
|
|
|
$pack = ReviewPack::factory()->ready()->create([
|
|
'tenant_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'tenant_review_id' => (int) $review->getKey(),
|
|
'evidence_snapshot_id' => (int) $reviewSnapshot->getKey(),
|
|
'initiated_by_user_id' => (int) $user->getKey(),
|
|
]);
|
|
|
|
$destination = AlertDestination::factory()->create([
|
|
'workspace_id' => (int) $workspace->getKey(),
|
|
'name' => 'Spec192 Browser Destination',
|
|
]);
|
|
|
|
$this->actingAs($user)->withSession([
|
|
WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id,
|
|
]);
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
|
|
|
|
visit(ReviewPackResource::getUrl('view', ['record' => $pack], tenant: $tenant))
|
|
->waitForText('Download')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('Regenerate');
|
|
|
|
visit(AlertDestinationResource::getUrl('view', ['record' => $destination], panel: 'admin'))
|
|
->waitForText('Send test message')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('Details');
|
|
|
|
visit(PolicyVersionResource::getUrl('view', ['record' => $version], tenant: $tenant))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('View snapshot');
|
|
|
|
visit(WorkspaceResource::getUrl('view', ['record' => $workspace], panel: 'admin'))
|
|
->waitForText('Memberships')
|
|
->assertNoJavaScriptErrors()
|
|
->assertSee('Edit');
|
|
|
|
visit(BaselineSnapshotResource::getUrl('view', ['record' => $baselineSnapshot], panel: 'admin'))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length > 0", true)
|
|
->assertSee('Spec192 Browser Policy');
|
|
|
|
visit(BackupSetResource::getUrl('view', ['record' => $backupSet], tenant: $tenant))
|
|
->waitForText('Related context')
|
|
->assertNoJavaScriptErrors()
|
|
->assertScript("document.querySelectorAll('[data-supporting-group-kind]').length > 0", true)
|
|
->assertSee('Operations');
|
|
});
|