TenantAtlas/apps/platform/tests/Feature/EnvironmentReview/EnvironmentReviewExplanationSurfaceTest.php
ahmido 9cd06e8b66 feat: review pack pdf and html renderer v1 (spec 356) (#427)
Implemented the first version of the PDF and HTML renderer for review packs. Added ReviewPackRenderedReportController and related blade views to render reports. Updated EnvironmentReviewResource, ReviewPackResource, ReviewPackService, and routing. Added new tests for the renderer and download actions, and updated UI documentation.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #427
2026-06-05 20:39:13 +00:00

123 lines
5.5 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Filament\Pages\Reviews\ReviewRegister;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Models\ManagedEnvironment;
use App\Support\OperationRunLinks;
use App\Support\ReasonTranslation\ReasonPresenter;
use App\Support\Ui\GovernanceArtifactTruth\ArtifactTruthPresenter;
use App\Support\Ui\GovernanceArtifactTruth\SurfaceCompressionContext;
use App\Support\Workspaces\WorkspaceContext;
use Livewire\Livewire;
use Tests\Feature\Concerns\BuildsGovernanceArtifactTruthFixtures;
uses(BuildsGovernanceArtifactTruthFixtures::class);
it('reuses the same operator explanation on environment review detail and review register surfaces', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner');
$snapshot = $this->makeArtifactTruthEvidenceSnapshot($tenant);
$review = $this->makeArtifactTruthReview(
tenant: $tenant,
user: $user,
snapshot: $snapshot,
reviewOverrides: [
'status' => 'draft',
'completeness_state' => 'complete',
],
summaryOverrides: [
'publish_blockers' => ['Review the missing approval note before publication.'],
],
);
$presenter = app(ArtifactTruthPresenter::class);
$truth = $presenter->forEnvironmentReview($review);
$explanation = $truth->operatorExplanation;
$detailOutcome = $presenter->compressedOutcomeFor($review, SurfaceCompressionContext::environmentReview());
$registerOutcome = $presenter->compressedOutcomeFor($review, SurfaceCompressionContext::reviewRegister());
$reasonSemantics = app(ReasonPresenter::class)->semantics($truth->reason?->toReasonResolutionEnvelope());
expect($reasonSemantics)->not->toBeNull();
setAdminEnvironmentContext($tenant);
$this->actingAs($user)
->get(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant))
->assertOk()
->assertSee($detailOutcome?->primaryReason ?? '')
->assertSee($explanation?->nextActionText ?? '')
->assertSee('Reason owner')
->assertSee($reasonSemantics['owner_label'])
->assertSee('Platform reason family')
->assertSee($reasonSemantics['family_label']);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
Livewire::actingAs($user)
->test(ReviewRegister::class)
->assertCanSeeTableRecords([$review])
->assertSee($registerOutcome?->primaryReason ?? '')
->assertSee($explanation?->nextActionText ?? '');
});
it('keeps customer-workspace review detail customer-readable by hiding internal reason ownership and fingerprints', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => 'published',
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
expect($review->operation_run_id)->not->toBeNull();
setAdminEnvironmentContext($tenant);
$this->actingAs($user)
->get(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review], $tenant).'?'.http_build_query([
CustomerReviewWorkspace::DETAIL_CONTEXT_QUERY_KEY => 1,
'source_surface' => CustomerReviewWorkspace::SOURCE_SURFACE,
'tenant_filter_id' => (string) $tenant->getKey(),
'interpretation_version' => $review->controlInterpretationVersion(),
]))
->assertOk()
->assertSee('Released governance record')
->assertSee('This released review is available for customer-safe governance consumption.')
->assertSee('View report with limitations')
->assertSee('Governance package')
->assertSee('Review status')
->assertSee('Evidence')
->assertSee('Accepted risk status')
->assertSee('Last review')
->assertSee('Primary action')
->assertSee('Download governance package')
->assertSee('Executive entrypoint')
->assertSee('Start with executive-summary.md in the downloaded package.')
->assertSee('Structured auditor appendix')
->assertSee('metadata.json, summary.json, and sections.json remain included as the secondary structured appendix.')
->assertSee('Anchored to evidence snapshot #')
->assertSee('Assessment basis')
->assertSee('Evidence basis')
->assertSee('Review the surfaced findings with the tenant and agree ownership plus follow-up timing.')
->assertSee('Evidence snapshot')
->assertSee('review_id='.$review->getKey(), false)
->assertSee('source_surface=customer_review_workspace', false)
->assertDontSeeText('Compliance evidence mapping v1')
->assertDontSeeText($review->controlInterpretationVersion())
->assertDontSeeText('Control readiness interpretation')
->assertDontSee('Reason owner')
->assertDontSee('Platform reason family')
->assertDontSee('Fingerprint')
->assertDontSee('Download current review pack')
->assertDontSee(OperationRunLinks::tenantlessView((int) $review->operation_run_id), false)
->assertDontSee('Inspect the latest review composition or refresh run.');
});