Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 2m1s
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.
322 lines
14 KiB
PHP
322 lines
14 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 Livewire\Livewire;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
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',
|
|
);
|
|
}
|
|
|
|
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,
|
|
],
|
|
'expires_at' => now()->addDay(),
|
|
]);
|
|
|
|
$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(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
|
|
->assertSee('Review pack')
|
|
->assertSee('Available')
|
|
->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('Customer-safe review pack ready')
|
|
->assertSee('Download customer-safe review pack')
|
|
->assertSee('source_surface=customer_review_workspace', false)
|
|
->assertSee('tenant_filter_id', false)
|
|
->assertSee('Open review')
|
|
->assertDontSee('Generate pack')
|
|
->assertDontSee('Regenerate')
|
|
->assertDontSee('Expire snapshot')
|
|
->assertDontSee('Expire 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,
|
|
],
|
|
'expires_at' => now()->addDay(),
|
|
]);
|
|
|
|
$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 available yet')
|
|
->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(),
|
|
]);
|
|
|
|
$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(EnvironmentReviewResource::environmentScopedUrl('view', ['record' => $review->fresh()], $tenant), false)
|
|
->assertSee('Output not customer-ready')
|
|
->assertSee('Review blockers are still recorded for this output.')
|
|
->assertSee('Download review pack with limitations')
|
|
->assertSee('Available');
|
|
});
|
|
|
|
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('Preparing')
|
|
->assertSee('Review Pack is being prepared.')
|
|
->assertSee('Unavailable')
|
|
->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('Unavailable')
|
|
->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');
|
|
});
|