Some checks failed
Main Confidence / confidence (push) Failing after 1m45s
## Summary - add the bounded workspace commercial lifecycle overlay from spec 251 on top of the existing entitlement substrate - expose audited commercial state inspection and mutation on the system workspace detail surface - gate onboarding activation and review-pack start actions through the shared lifecycle decision while preserving suspended read-only access to existing review, evidence, and generated-pack history - add focused Pest coverage plus the spec/plan/tasks/data-model/contract artifacts for the feature ## Validation - targeted Pest unit and feature lanes for lifecycle resolution, system-plane mutation, onboarding gating, review-pack enforcement, download preservation, customer review workspace access, and evidence snapshot access - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - integrated browser smoke on the system workspace detail and the preserved read-only review/evidence/review-pack surfaces ## Notes - branch: `251-commercial-entitlements-billing-state` - base: `dev` - commit: `606e9760` Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #292
157 lines
5.9 KiB
PHP
157 lines
5.9 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\Services\Entitlements\WorkspaceCommercialLifecycleResolver;
|
|
use App\Services\Settings\SettingsWriter;
|
|
use App\Support\Auth\PlatformCapabilities;
|
|
use App\Support\TenantReviewStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
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('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('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('Unavailable');
|
|
});
|
|
|
|
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');
|
|
});
|