TenantAtlas/apps/platform/tests/Feature/Reviews/CustomerReviewWorkspacePackAccessTest.php
ahmido 966b7af472
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m0s
feat: productize customer review workspace (#310)
## Summary
- productize the customer review workspace and released-review drilldown into a calmer customer-safe governance flow
- make review-pack and evidence-proof access explicit, capability-aware, and auditable in the shared Filament resources
- add focused Pest coverage, browser smoke coverage, and the full Spec 258 artifact package

## Notes
- Filament stays on v5 with Livewire v4 surfaces; no provider registration changes were introduced
- no new global-search scope, destructive action surface, or asset registration was added
- bounded additive audit action IDs were added for workspace open and evidence proof open events

## Validation
- focused Pest feature suites for workspace, review detail, review-pack, and evidence flows
- bounded browser smoke: `tests/Browser/Reviews/CustomerReviewWorkspaceSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #310
2026-04-30 18:15:32 +00:00

205 lines
8.2 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Models\PlatformUser;
use App\Models\ReviewPack;
use App\Models\Tenant;
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\TenantReviewStatus;
use App\Support\Workspaces\WorkspaceContext;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Gate;
use Livewire\Livewire;
uses(RefreshDatabase::class);
function suspendCustomerReviewWorkspacePackAccessWorkspace(Tenant $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 the ready review-pack action for the latest published review', function (): void {
$tenant = Tenant::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => TenantReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$pack = ReviewPack::factory()->ready()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'tenant_review_id' => (int) $review->getKey(),
'evidence_snapshot_id' => (int) $snapshot->getKey(),
'initiated_by_user_id' => (int) $user->getKey(),
'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)
->assertTableActionVisible('open_latest_review', $tenant)
->assertTableActionVisible('download_review_pack', $tenant)
->assertSee('Current review pack available');
});
it('keeps customer review workspace and pack actions visible while suspended read-only', function (): void {
$tenant = Tenant::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => TenantReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$pack = ReviewPack::factory()->ready()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'tenant_review_id' => (int) $review->getKey(),
'evidence_snapshot_id' => (int) $snapshot->getKey(),
'initiated_by_user_id' => (int) $user->getKey(),
'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)
->assertTableActionVisible('open_latest_review', $tenant)
->assertTableActionVisible('download_review_pack', $tenant)
->assertSee('Current review pack available');
});
it('shows an unavailable pack state and hides the download action when no current review pack exists', function (): void {
$tenant = Tenant::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => TenantReviewStatus::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)
->assertTableActionVisible('open_latest_review', $tenant)
->assertTableActionHidden('download_review_pack', $tenant)
->assertSee('No current review pack available yet');
});
it('distinguishes expired and capability-blocked review-pack states on the workspace', function (): void {
$expiredTenant = Tenant::factory()->create(['name' => 'Expired Pack Tenant']);
[$user, $expiredTenant] = createUserWithTenant(tenant: $expiredTenant, role: 'readonly');
$blockedTenant = Tenant::factory()->create([
'workspace_id' => (int) $expiredTenant->workspace_id,
'name' => 'Blocked Pack Tenant',
]);
createUserWithTenant(tenant: $blockedTenant, user: $user, role: 'readonly');
foreach ([$expiredTenant, $blockedTenant] as $tenant) {
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => TenantReviewStatus::Published->value,
'published_at' => now(),
'published_by_user_id' => (int) $user->getKey(),
])->save();
$pack = ReviewPack::factory()->ready()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'tenant_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, Tenant $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('Review pack expired')
->assertSee('Review pack access is unavailable for this actor')
->assertTableActionHidden('download_review_pack', $expiredTenant)
->assertTableActionHidden('download_review_pack', $blockedTenant);
});
it('hides review and pack actions for tenants without a published review', function (): void {
$tenant = Tenant::factory()->create();
[$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'readonly');
$snapshot = seedTenantReviewEvidence($tenant);
$review = composeTenantReviewForTest($tenant, $user, $snapshot);
$review->forceFill([
'status' => TenantReviewStatus::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)
->assertTableActionHidden('open_latest_review', $tenant)
->assertTableActionHidden('download_review_pack', $tenant)
->assertSee('No published review available yet');
});