Automated PR provided by Codex via Gitea API. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #470
210 lines
8.4 KiB
PHP
210 lines
8.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\Findings\FindingsIntakeQueue;
|
|
use App\Filament\Pages\Findings\MyFindingsInbox;
|
|
use App\Filament\Pages\Governance\GovernanceInbox;
|
|
use App\Filament\Resources\FindingResource;
|
|
use App\Http\Middleware\SuppressDebugbarForSmokeRequests;
|
|
use App\Models\Finding;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\OperationRun;
|
|
use App\Models\User;
|
|
use App\Support\ManagedEnvironmentLinks;
|
|
use App\Support\OperationRunLinks;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
|
|
pest()->browser()->timeout(120_000);
|
|
|
|
it('Spec399 smokes dashboard, inbox, findings, and operations product-surface defaults', function (): void {
|
|
[$user, $environment] = spec399BrowserFixture();
|
|
|
|
spec399AuthenticateBrowser($this, $user, $environment);
|
|
|
|
visit(route('admin.workspace.home', ['workspace' => $environment->workspace]))
|
|
->resize(1440, 1100)
|
|
->waitForText('Needs attention')
|
|
->assertSee('Review recent workspace activity')
|
|
->assertScript('document.querySelector("[data-testid=\"workspace-recent-operations-disclosure\"]")?.hasAttribute("open") === false', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
visit(ManagedEnvironmentLinks::viewUrl($environment))
|
|
->resize(1440, 1100)
|
|
->waitForText($environment->name)
|
|
->assertDontSee('spec399 browser raw payload should stay hidden')
|
|
->assertNoJavaScriptErrors();
|
|
|
|
visit(GovernanceInbox::getUrl(panel: 'admin'))
|
|
->resize(1440, 1100)
|
|
->waitForText('Governance Inbox')
|
|
->assertSee('Primary inbox lanes')
|
|
->assertSee('Needs triage')
|
|
->assertScript('document.querySelector("[data-testid=\"governance-inbox-lane-needs_triage\"]") !== null', true)
|
|
->assertScript(<<<'JS'
|
|
(() => {
|
|
const lane = document.querySelector('[data-testid="governance-inbox-lane-needs_triage"]');
|
|
const item = lane?.querySelector('[data-testid^="governance-inbox-item-needs_triage"]');
|
|
const details = item?.querySelector('details');
|
|
|
|
return Boolean(item)
|
|
&& Boolean(item.querySelector('a[href]'))
|
|
&& details instanceof HTMLDetailsElement
|
|
&& details.open === false;
|
|
})()
|
|
JS, true)
|
|
->assertDontSee('spec399 browser raw payload should stay hidden')
|
|
->assertNoJavaScriptErrors();
|
|
|
|
visit(MyFindingsInbox::getUrl(panel: 'admin'))
|
|
->resize(1440, 1100)
|
|
->waitForText('My findings')
|
|
->waitForText('Spec399 Browser Assigned Finding 10')
|
|
->assertSee('Managed environment')
|
|
->assertDontSee('spec399-browser-source-key')
|
|
->assertScript('(() => { const rows = document.querySelectorAll("table tbody tr"); return rows.length > 0 && rows.length <= 8; })()', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
visit(FindingsIntakeQueue::getUrl(panel: 'admin'))
|
|
->resize(1440, 1100)
|
|
->waitForText('Findings intake')
|
|
->waitForText('Spec399 Browser Intake Finding 10')
|
|
->assertSee('Managed environment')
|
|
->assertDontSee('spec399-browser-intake-key')
|
|
->assertScript('(() => { const rows = document.querySelectorAll("table tbody tr"); return rows.length > 0 && rows.length <= 8; })()', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
visit(FindingResource::getUrl('index', tenant: $environment, panel: 'admin'))
|
|
->resize(1440, 1100)
|
|
->waitForText('Findings')
|
|
->assertDontSee('spec399-browser-source-key')
|
|
->assertDontSee('spec399-browser-intake-key')
|
|
->assertScript('(() => { const rows = document.querySelectorAll("table tbody tr"); return rows.length > 0 && rows.length <= 8; })()', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
$operationsPage = visit(OperationRunLinks::index($environment))
|
|
->resize(1440, 1100)
|
|
->waitForText('Operations Hub')
|
|
->assertSee('Which operation needs attention now?')
|
|
->assertSee('Recent operations')
|
|
->assertSee('Detail path')
|
|
->assertSee('Technical detail available')
|
|
->assertDontSee('Operation #')
|
|
->assertDontSee('OperationRuns')
|
|
->assertDontSee('Operation detail available')
|
|
->assertDontSee('Proof unavailable')
|
|
->assertDontSee('spec399 browser raw payload should stay hidden')
|
|
->assertScript('document.querySelector("[data-testid=\"operations-hub-diagnostics\"]")?.hasAttribute("open") === false', true)
|
|
->assertScript('typeof window.Livewire !== "undefined"', true)
|
|
->assertScript('typeof window.Alpine !== "undefined"', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
$operationsPage->script('document.querySelector("[data-testid=\"operations-hub-diagnostics\"] summary")?.click();');
|
|
$operationsPage
|
|
->assertScript('document.querySelector("[data-testid=\"operations-hub-diagnostics\"]")?.hasAttribute("open") === true', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
$operationsPage->script("document.documentElement.classList.add('dark');");
|
|
$operationsPage
|
|
->assertScript('document.documentElement.classList.contains("dark")', true)
|
|
->assertNoJavaScriptErrors();
|
|
|
|
$operationsPage->script("window.location.replace('about:blank');");
|
|
});
|
|
|
|
/**
|
|
* @return array{0: User, 1: ManagedEnvironment}
|
|
*/
|
|
function spec399BrowserFixture(): array
|
|
{
|
|
bindFailHardGraphClient();
|
|
|
|
$environment = ManagedEnvironment::factory()->active()->create([
|
|
'name' => 'Spec399 Browser Environment',
|
|
'external_id' => 'spec399-browser-environment',
|
|
]);
|
|
|
|
[$user, $environment] = createUserWithTenant(
|
|
tenant: $environment,
|
|
role: 'owner',
|
|
workspaceRole: 'owner',
|
|
);
|
|
|
|
OperationRun::factory()->forTenant($environment)->create([
|
|
'type' => 'inventory_sync',
|
|
'status' => OperationRunStatus::Completed->value,
|
|
'outcome' => OperationRunOutcome::Blocked->value,
|
|
'initiator_name' => 'Spec399 browser operator',
|
|
'context' => [
|
|
'reason_code' => 'write_gate_blocked',
|
|
'raw_payload' => 'spec399 browser raw payload should stay hidden',
|
|
'target_scope' => [
|
|
'scope_display_name' => 'Spec399 Browser Environment',
|
|
],
|
|
],
|
|
'completed_at' => now(),
|
|
]);
|
|
|
|
foreach (range(1, 10) as $index) {
|
|
Finding::factory()->for($environment)->create([
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'status' => Finding::STATUS_NEW,
|
|
'severity' => Finding::SEVERITY_HIGH,
|
|
'owner_user_id' => (int) $user->getKey(),
|
|
'assignee_user_id' => (int) $user->getKey(),
|
|
'subject_external_id' => $index === 1
|
|
? 'spec399-browser-source-key'
|
|
: sprintf('spec399-browser-assigned-key-%02d', $index),
|
|
'evidence_jsonb' => [
|
|
'display_name' => sprintf('Spec399 Browser Assigned Finding %02d', $index),
|
|
],
|
|
'created_at' => now()->subMinutes($index),
|
|
]);
|
|
}
|
|
|
|
foreach (range(1, 10) as $index) {
|
|
Finding::factory()->for($environment)->create([
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'status' => $index % 2 === 0 ? Finding::STATUS_NEW : Finding::STATUS_REOPENED,
|
|
'severity' => Finding::SEVERITY_MEDIUM,
|
|
'owner_user_id' => null,
|
|
'assignee_user_id' => null,
|
|
'subject_external_id' => $index === 1
|
|
? 'spec399-browser-intake-key'
|
|
: sprintf('spec399-browser-intake-key-%02d', $index),
|
|
'evidence_jsonb' => [
|
|
'display_name' => sprintf('Spec399 Browser Intake Finding %02d', $index),
|
|
],
|
|
'created_at' => now()->subMinutes($index + 20),
|
|
]);
|
|
}
|
|
|
|
return [$user, $environment];
|
|
}
|
|
|
|
function spec399AuthenticateBrowser(
|
|
mixed $test,
|
|
User $user,
|
|
ManagedEnvironment $environment,
|
|
): void {
|
|
$workspaceId = (int) $environment->workspace_id;
|
|
|
|
$session = [
|
|
WorkspaceContext::SESSION_KEY => $workspaceId,
|
|
WorkspaceContext::LAST_ENVIRONMENT_IDS_SESSION_KEY => [
|
|
(string) $workspaceId => (int) $environment->getKey(),
|
|
],
|
|
SuppressDebugbarForSmokeRequests::SESSION_KEY => SuppressDebugbarForSmokeRequests::COOKIE_VALUE,
|
|
];
|
|
|
|
$test->actingAs($user)->withSession($session);
|
|
|
|
foreach ($session as $key => $value) {
|
|
session()->put($key, $value);
|
|
}
|
|
|
|
setAdminPanelContext($environment);
|
|
}
|