Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m0s
Implemented the output contract and readiness semantics for review packs. Also added spec 348. Includes changes to ChooseEnvironment, CustomerReviewWorkspace, GenerateReviewPackJob and related blade views. Added comprehensive tests.
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 and meets the customer-safe output contract.')
|
|
->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('Published with limitations')
|
|
->assertSee('The review package is published, but the evidence basis is incomplete.')
|
|
->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');
|
|
});
|