TenantAtlas/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php
ahmido bd6f59bb7c feat: add governance artifact lifecycle retention contracts (#477)
Automated PR provided by Codex via Gitea API.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #477
2026-06-24 08:29:30 +00:00

406 lines
17 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Filament\Resources\EnvironmentReviewResource;
use App\Models\ManagedEnvironment;
use App\Models\PlatformUser;
use App\Models\ReviewPack;
use App\Models\User;
use App\Services\Entitlements\WorkspaceCommercialLifecycleResolver;
use App\Services\Settings\SettingsWriter;
use App\Support\Auth\Capabilities;
use App\Support\Auth\PlatformCapabilities;
use App\Support\EnvironmentReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
uses(RefreshDatabase::class);
beforeEach(function (): void {
Storage::fake('exports');
});
function suspendCustomerReviewWorkspacePackAccessWorkspace(ManagedEnvironment $tenant): void
{
app(SettingsWriter::class)->updateWorkspaceCommercialLifecycle(
actor: PlatformUser::factory()->create([
'capabilities' => [
PlatformCapabilities::ACCESS_SYSTEM_PANEL,
PlatformCapabilities::DIRECTORY_VIEW,
PlatformCapabilities::COMMERCIAL_LIFECYCLE_MANAGE,
],
'is_active' => true,
]),
workspace: $tenant->workspace,
state: WorkspaceCommercialLifecycleResolver::STATE_SUSPENDED_READ_ONLY,
reason: 'Customer review workspace suspended read-only test',
);
}
/**
* @return array{file_disk: string, file_path: string, file_size: int, sha256: string}
*/
function customerReviewWorkspacePackArtifactAttributes(string $filePath, string $contents = 'PK-customer-review-pack'): array
{
Storage::disk('exports')->put($filePath, $contents);
return [
'file_disk' => 'exports',
'file_path' => $filePath,
'file_size' => Storage::disk('exports')->size($filePath),
'sha256' => hash('sha256', $contents),
];
}
it('shows a customer-safe download action when the latest released review pack is ready', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant, findingCount: 0, driftCount: 0);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$review = markEnvironmentReviewCustomerSafeReady($review);
$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(),
'initiated_by_user_id' => (int) $user->getKey(),
'options' => [
'include_pii' => false,
'include_operations' => true,
],
'summary' => [
'control_interpretation' => [
'non_certification_disclosure' => 'TenantPilot interprets available evidence for review readiness. This is not a certification, legal attestation, or compliance guarantee.',
],
],
'expires_at' => now()->addDay(),
] + customerReviewWorkspacePackArtifactAttributes('review-packs/customer-safe-ready.zip', 'PK-customer-safe-ready'));
$review->forceFill([
'current_export_review_pack_id' => (int) $pack->getKey(),
])->save();
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
$component = Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertSee(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
->assertSee('Review pack')
->assertSee('Ready')
->assertSee('The current review package is available, meets the customer-safe output contract, and can be opened as a rendered report from the review detail.')
->assertSee('Download customer-safe review pack')
->assertSee('source_surface=customer_review_workspace', false)
->assertSee('tenant_filter_id', false)
->assertSee('Open review')
->assertDontSee('Customer-safe review pack ready')
->assertDontSee('Generate pack')
->assertDontSee('Regenerate')
->assertDontSee('Expire snapshot')
->assertDontSee('Expire review pack');
expect($component->html())->toMatch('/<h2[^>]*>\s*Ready\s*<\/h2>/');
});
it('does not offer a customer-safe download when the ready pack file fails validation', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant, findingCount: 0, driftCount: 0);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$review = markEnvironmentReviewCustomerSafeReady($review);
$filePath = 'review-packs/customer-safe-tampered.zip';
Storage::disk('exports')->put($filePath, 'PK-customer-safe-tampered');
$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(),
'initiated_by_user_id' => (int) $user->getKey(),
'options' => [
'include_pii' => false,
'include_operations' => true,
],
'expires_at' => now()->addDay(),
'file_disk' => 'exports',
'file_path' => $filePath,
'file_size' => Storage::disk('exports')->size($filePath),
'sha256' => str_repeat('0', 64),
]);
$review->forceFill([
'current_export_review_pack_id' => (int) $pack->getKey(),
])->save();
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertSee('Review pack')
->assertSee('Not configured')
->assertSee('Review Pack has not been generated for this released review yet.')
->assertDontSee('Download customer-safe review pack');
});
it('keeps the customer review workspace download action visible while suspended read-only', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant, findingCount: 0, driftCount: 0);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$review = markEnvironmentReviewCustomerSafeReady($review);
$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(),
'initiated_by_user_id' => (int) $user->getKey(),
'options' => [
'include_pii' => false,
'include_operations' => true,
],
'summary' => [
'control_interpretation' => [
'non_certification_disclosure' => 'TenantPilot interprets available evidence for review readiness. This is not a certification, legal attestation, or compliance guarantee.',
],
],
'expires_at' => now()->addDay(),
] + customerReviewWorkspacePackArtifactAttributes('review-packs/customer-safe-suspended.zip', 'PK-customer-safe-suspended'));
$review->forceFill([
'current_export_review_pack_id' => (int) $pack->getKey(),
])->save();
suspendCustomerReviewWorkspacePackAccessWorkspace($tenant);
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertSee(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
->assertSee('Download customer-safe review pack')
->assertSee('Open review')
->assertDontSee('Generate pack')
->assertDontSee('Regenerate')
->assertDontSee('Expire snapshot')
->assertDontSee('Expire review pack');
});
it('shows a customer-safe missing review-pack state without exposing pack mutation actions', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
'current_export_review_pack_id' => null,
])->save();
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertSee(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
->assertSee('Not configured')
->assertSee('Review Pack has not been generated for this released review yet.')
->assertDontSee('Download review pack')
->assertDontSee('Generate pack')
->assertDontSee('Regenerate')
->assertDontSee('Expire snapshot')
->assertDontSee('Expire review pack');
});
it('shows a partial governance-package state when the released review basis is limitation-aware', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedPartialEnvironmentReviewEvidence($tenant, findingCount: 0, driftCount: 0);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$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(),
'initiated_by_user_id' => (int) $user->getKey(),
'options' => [
'include_pii' => false,
'include_operations' => true,
],
'expires_at' => now()->addDay(),
] + customerReviewWorkspacePackArtifactAttributes('review-packs/partial-governance-ready.zip', 'PK-partial-governance-ready'));
$review->forceFill([
'current_export_review_pack_id' => (int) $pack->getKey(),
])->save();
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
$component = Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertSee(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
->assertSee('Needs attention')
->assertSee('Review blockers are still recorded for this output.')
->assertDontSee('Download internal preview')
->assertDontSee('Output not customer-ready')
->assertSee('Ready');
expect($component->html())->toMatch('/<h2[^>]*>\s*Needs attention\s*<\/h2>/');
});
it('shows preparing and unavailable review-pack states without download links', function (): void {
$preparingTenant = ManagedEnvironment::factory()->create(['name' => 'Preparing Pack ManagedEnvironment']);
[$user, $preparingTenant] = createUserWithTenant(tenant: $preparingTenant, role: 'readonly');
$failedTenant = ManagedEnvironment::factory()->create([
'workspace_id' => (int) $preparingTenant->workspace_id,
'name' => 'Failed Pack ManagedEnvironment',
]);
createUserWithTenant(tenant: $failedTenant, user: $user, role: 'readonly');
foreach ([$preparingTenant, $failedTenant] as $tenant) {
$snapshot = seedEnvironmentReviewEvidence($tenant);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$pack = ($tenant->is($preparingTenant)
? ReviewPack::factory()->queued()
: ReviewPack::factory()->failed())
->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(),
'initiated_by_user_id' => (int) $user->getKey(),
]);
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
}
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $preparingTenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertCanSeeTableRecords([$preparingTenant->fresh(), $failedTenant->fresh()])
->assertSee('Running')
->assertSee('Review Pack is being prepared.')
->assertSee('Failed')
->assertSee('Review Pack cannot be provided right now.')
->assertDontSee('Download review pack');
});
it('shows expired and capability-blocked review-pack states on the workspace row surface', function (): void {
$expiredTenant = ManagedEnvironment::factory()->create(['name' => 'Expired Pack ManagedEnvironment']);
[$user, $expiredTenant] = createUserWithTenant(tenant: $expiredTenant, role: 'readonly');
$blockedTenant = ManagedEnvironment::factory()->create([
'workspace_id' => (int) $expiredTenant->workspace_id,
'name' => 'Blocked Pack ManagedEnvironment',
]);
createUserWithTenant(tenant: $blockedTenant, user: $user, role: 'readonly');
foreach ([$expiredTenant, $blockedTenant] as $tenant) {
$snapshot = seedEnvironmentReviewEvidence($tenant);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$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(),
'initiated_by_user_id' => (int) $user->getKey(),
'expires_at' => $tenant->is($expiredTenant) ? now()->subDay() : now()->addDay(),
]);
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
}
Gate::define(Capabilities::REVIEW_PACK_VIEW, fn (User $actor, ManagedEnvironment $tenant): bool => ! $tenant->is($blockedTenant));
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $expiredTenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertCanSeeTableRecords([$expiredTenant->fresh(), $blockedTenant->fresh()])
->assertSee('Expired')
->assertSee('Blocked')
->assertDontSee('Download review pack');
});
it('hides tenants without a published review from the workspace rows', function (): void {
$tenant = ManagedEnvironment::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedEnvironmentReviewEvidence($tenant);
$review = composeEnvironmentReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => EnvironmentReviewStatus::Ready->value,
'published_at' => null,
'published_by_user_id' => null,
'current_export_review_pack_id' => null,
])->save();
$this->actingAs($user);
setAdminPanelContext();
session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id);
Livewire::actingAs($user)
->test(CustomerReviewWorkspace::class)
->assertCanNotSeeTableRecords([$tenant->fresh()])
->assertSee('No released customer reviews match this view')
->assertDontSee('No published review available yet');
});