Applied customer/auditor safety layout changes to CustomerReviewWorkspace, EnvironmentReviewResource, EvidenceSnapshotResource, ReviewPackResource, and StoredReportResource as per Spec 372. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #443
272 lines
11 KiB
PHP
272 lines
11 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
|
use App\Filament\Resources\EnvironmentReviewResource;
|
|
use App\Filament\Resources\EvidenceSnapshotResource;
|
|
use App\Filament\Resources\ReviewPackResource;
|
|
use App\Filament\Resources\StoredReportResource;
|
|
use App\Models\EnvironmentReview;
|
|
use App\Models\EvidenceSnapshot;
|
|
use App\Models\EvidenceSnapshotItem;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\OperationRun;
|
|
use App\Models\ReviewPack;
|
|
use App\Models\StoredReport;
|
|
use App\Models\User;
|
|
use App\Support\EnvironmentReviewStatus;
|
|
use App\Support\Evidence\EvidenceCompletenessState;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\OperationRunType;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
pest()->browser()->timeout(60_000);
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
beforeEach(function (): void {
|
|
Storage::fake('exports');
|
|
});
|
|
|
|
it('Spec372 smokes customer and auditor review output surfaces with screenshots', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner', workspaceRole: 'manager');
|
|
$tenant->forceFill(['name' => 'Spec372 Browser Environment'])->save();
|
|
|
|
[
|
|
'review' => $review,
|
|
'snapshot' => $snapshot,
|
|
'pack' => $pack,
|
|
'report' => $report,
|
|
] = spec372BrowserFixture($tenant, $user);
|
|
|
|
$workspacePath = spec372BrowserPath(CustomerReviewWorkspace::environmentFilterUrl($tenant));
|
|
$reviewPath = spec372BrowserPath(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant));
|
|
$packPath = spec372BrowserPath(ReviewPackResource::getUrl('view', ['record' => $pack], tenant: $tenant, panel: 'admin'));
|
|
$reportPath = spec372BrowserPath(StoredReportResource::getUrl('view', ['record' => $report], tenant: $tenant, panel: 'admin'));
|
|
$evidencePath = spec372BrowserPath(EvidenceSnapshotResource::getUrl('view', ['record' => $snapshot], tenant: $tenant, panel: 'admin'));
|
|
|
|
$page = visit(spec372BrowserLoginUrl($user, $tenant, $workspacePath))
|
|
->resize(1440, 1100)
|
|
->waitForText('Customer Review Workspace')
|
|
->assertSee('Evidence path')
|
|
->assertSee('Review pack state')
|
|
->assertDontSee('Operation proof')
|
|
->assertNoJavaScriptErrors()
|
|
->assertNoConsoleLogs()
|
|
->screenshot(true, '001-customer-review-workspace-after');
|
|
spec372BrowserCopyScreenshot('001-customer-review-workspace-after');
|
|
|
|
$page = visit($reviewPath)
|
|
->resize(1440, 1100)
|
|
->waitForText('Outcome summary')
|
|
->assertSee('Output guidance')
|
|
->assertSee('Executive posture')
|
|
->assertSee('Evidence basis')
|
|
->assertSee('Technical details')
|
|
->assertScript("document.body.textContent.indexOf('Output guidance') < document.body.textContent.indexOf('Technical details')", true)
|
|
->assertNoJavaScriptErrors()
|
|
->assertNoConsoleLogs()
|
|
->screenshot(true, '002-environment-review-view-after');
|
|
spec372BrowserCopyScreenshot('002-environment-review-view-after');
|
|
|
|
$page = visit($packPath)
|
|
->resize(1440, 1100)
|
|
->waitForText('Outcome summary')
|
|
->assertSee('Output guidance')
|
|
->assertSee('Pack readiness and contents')
|
|
->assertSee('Technical pack details')
|
|
->assertScript("document.body.textContent.indexOf('Pack readiness and contents') < document.body.textContent.indexOf('Technical pack details')", true)
|
|
->assertNoJavaScriptErrors()
|
|
->assertNoConsoleLogs()
|
|
->screenshot(true, '003-review-pack-view-after');
|
|
spec372BrowserCopyScreenshot('003-review-pack-view-after');
|
|
|
|
$page = visit($reportPath)
|
|
->resize(1440, 1100)
|
|
->waitForText('Outcome summary')
|
|
->assertSee('Report scope and readiness')
|
|
->assertSee('Permission posture summary')
|
|
->assertSee('Technical report details')
|
|
->assertScript("document.body.textContent.indexOf('Permission posture summary') < document.body.textContent.indexOf('Technical report details')", true)
|
|
->assertNoJavaScriptErrors()
|
|
->assertNoConsoleLogs()
|
|
->screenshot(true, '004-stored-report-view-after');
|
|
spec372BrowserCopyScreenshot('004-stored-report-view-after');
|
|
|
|
$page = visit($evidencePath)
|
|
->resize(1440, 1100)
|
|
->waitForText('Outcome summary')
|
|
->assertSee('Evidence basis and readiness')
|
|
->assertSee('Related review and report context')
|
|
->assertSee('Technical evidence details')
|
|
->assertSee('Evidence dimensions')
|
|
->assertScript("document.body.textContent.indexOf('Related review and report context') < document.body.textContent.indexOf('Technical evidence details')", true)
|
|
->assertNoJavaScriptErrors()
|
|
->assertNoConsoleLogs()
|
|
->screenshot(true, '005-evidence-snapshot-view-after-or-blocked');
|
|
spec372BrowserCopyScreenshot('005-evidence-snapshot-view-after-or-blocked');
|
|
|
|
$page
|
|
->resize(430, 900)
|
|
->assertScript('document.documentElement.scrollWidth <= window.innerWidth', true)
|
|
->assertNoJavaScriptErrors()
|
|
->screenshot(true, '006-evidence-snapshot-view-mobile');
|
|
spec372BrowserCopyScreenshot('006-evidence-snapshot-view-mobile');
|
|
});
|
|
|
|
/**
|
|
* @return array{review: EnvironmentReview, snapshot: EvidenceSnapshot, pack: ReviewPack, report: StoredReport, run: OperationRun}
|
|
*/
|
|
function spec372BrowserFixture(ManagedEnvironment $tenant, User $user): array
|
|
{
|
|
$snapshot = seedEnvironmentReviewEvidence($tenant, findingCount: 1, driftCount: 0);
|
|
$run = OperationRun::factory()
|
|
->forTenant($tenant)
|
|
->withUser($user)
|
|
->create([
|
|
'type' => OperationRunType::ReviewPackGenerate->value,
|
|
'status' => OperationRunStatus::Completed->value,
|
|
'initiator_name' => 'Spec372 Browser Operator',
|
|
]);
|
|
|
|
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
|
|
$review->forceFill([
|
|
'status' => EnvironmentReviewStatus::Published->value,
|
|
'generated_at' => now()->subHours(2),
|
|
'published_at' => now()->subHour(),
|
|
'published_by_user_id' => (int) $user->getKey(),
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
])->save();
|
|
$review = markEnvironmentReviewCustomerSafeReady($review);
|
|
|
|
Storage::disk('exports')->put('review-packs/spec372-browser-review-pack.zip', 'PK-spec372-browser');
|
|
|
|
$pack = ReviewPack::factory()->ready()->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'environment_review_id' => (int) $review->getKey(),
|
|
'evidence_snapshot_id' => (int) $snapshot->getKey(),
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'initiated_by_user_id' => (int) $user->getKey(),
|
|
'file_path' => 'review-packs/spec372-browser-review-pack.zip',
|
|
'file_disk' => 'exports',
|
|
'summary' => [
|
|
'finding_count' => 1,
|
|
'report_count' => 2,
|
|
'operation_count' => 1,
|
|
'evidence_resolution' => ['outcome' => 'complete'],
|
|
],
|
|
'options' => [
|
|
'include_pii' => false,
|
|
'include_operations' => true,
|
|
],
|
|
]);
|
|
|
|
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
|
|
|
|
$report = StoredReport::factory()
|
|
->permissionPosture([
|
|
'posture_score' => 78,
|
|
'required_count' => 4,
|
|
'granted_count' => 3,
|
|
'permissions' => [
|
|
['key' => 'DeviceManagementConfiguration.Read.All', 'status' => 'granted'],
|
|
['key' => 'DeviceManagementApps.ReadWrite.All', 'status' => 'missing'],
|
|
],
|
|
])
|
|
->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
]);
|
|
|
|
$snapshot->forceFill([
|
|
'operation_run_id' => (int) $run->getKey(),
|
|
'summary' => array_replace(is_array($snapshot->summary) ? $snapshot->summary : [], [
|
|
'finding_count' => 1,
|
|
'report_count' => 2,
|
|
'operation_count' => 1,
|
|
'missing_dimensions' => 0,
|
|
'stale_dimensions' => 0,
|
|
]),
|
|
])->save();
|
|
|
|
EvidenceSnapshotItem::query()->updateOrCreate(
|
|
[
|
|
'evidence_snapshot_id' => (int) $snapshot->getKey(),
|
|
'dimension_key' => 'permission_posture',
|
|
],
|
|
[
|
|
'workspace_id' => (int) $snapshot->workspace_id,
|
|
'managed_environment_id' => (int) $snapshot->managed_environment_id,
|
|
'state' => EvidenceCompletenessState::Complete->value,
|
|
'required' => true,
|
|
'source_kind' => 'stored_report',
|
|
'source_record_type' => 'stored_report',
|
|
'source_record_id' => (string) $report->getKey(),
|
|
'measured_at' => now(),
|
|
'freshness_at' => now(),
|
|
'summary_payload' => [
|
|
'required_count' => 4,
|
|
'granted_count' => 3,
|
|
'posture_score' => 78,
|
|
'payload' => [
|
|
'missing_permissions' => ['DeviceManagementApps.ReadWrite.All'],
|
|
],
|
|
],
|
|
'sort_order' => 10,
|
|
],
|
|
);
|
|
|
|
return [
|
|
'review' => $review->refresh(),
|
|
'snapshot' => $snapshot->refresh(),
|
|
'pack' => $pack->refresh(),
|
|
'report' => $report->refresh(),
|
|
'run' => $run,
|
|
];
|
|
}
|
|
|
|
function spec372BrowserLoginUrl(User $user, ManagedEnvironment $tenant, string $redirect): string
|
|
{
|
|
return route('admin.local.smoke-login', [
|
|
'email' => $user->email,
|
|
'tenant' => $tenant->external_id,
|
|
'workspace' => $tenant->workspace->slug,
|
|
'redirect' => $redirect,
|
|
]);
|
|
}
|
|
|
|
function spec372BrowserPath(string $url): string
|
|
{
|
|
$path = parse_url($url, PHP_URL_PATH) ?: '/admin';
|
|
$query = parse_url($url, PHP_URL_QUERY);
|
|
|
|
return is_string($query) && $query !== '' ? $path.'?'.$query : $path;
|
|
}
|
|
|
|
function spec372BrowserCopyScreenshot(string $name): void
|
|
{
|
|
$filename = $name.'.png';
|
|
$source = base_path('tests/Browser/Screenshots/'.$filename);
|
|
$targetDirectory = repo_path('specs/372-customer-auditor-surface-safety-pass/artifacts/screenshots');
|
|
|
|
if (! is_dir($targetDirectory)) {
|
|
@mkdir($targetDirectory, 0755, true);
|
|
}
|
|
|
|
if (! is_file($source)) {
|
|
$source = \Pest\Browser\Support\Screenshot::path($filename);
|
|
}
|
|
|
|
for ($attempt = 0; $attempt < 10 && ! is_file($source); $attempt++) {
|
|
usleep(100_000);
|
|
clearstatcache(true, $source);
|
|
}
|
|
|
|
if (is_file($source) && is_dir($targetDirectory) && is_writable($targetDirectory)) {
|
|
@copy($source, $targetDirectory.DIRECTORY_SEPARATOR.$filename);
|
|
}
|
|
}
|