getStaticPropertyValue('isGloballySearchable'))->toBeFalse() ->and(array_keys(TenantReviewResource::getPages()))->toContain('view'); }); it('keeps tenant review list and canonical register empty states to a single CTA', function (): void { [$user, $tenant] = createUserWithTenant(role: 'owner'); $this->actingAs($user); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(ListTenantReviews::class) ->assertTableEmptyStateActionsExistInOrder(['create_first_review']) ->assertSee('No tenant reviews yet') ->mountAction('create_review') ->assertActionMounted('create_review'); setAdminPanelContext(); session()->put(WorkspaceContext::SESSION_KEY, (int) $tenant->workspace_id); Livewire::actingAs($user) ->test(ReviewRegister::class) ->searchTable('no-such-review') ->assertTableEmptyStateActionsExistInOrder(['clear_filters_empty']) ->assertSee('No review records match this view'); }); it('requires confirmation for destructive tenant-review actions and preserves disabled management visibility for readonly users', function (): void { $tenant = Tenant::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); [$readonly] = createUserWithTenant(tenant: $tenant, user: User::factory()->create(), role: 'readonly'); $review = composeTenantReviewForTest($tenant, $owner); setTenantPanelContext($tenant); Livewire::actingAs($readonly) ->test(ViewTenantReview::class, ['record' => $review->getKey()]) ->assertActionVisible('refresh_review') ->assertActionDisabled('refresh_review') ->assertActionVisible('publish_review') ->assertActionDisabled('publish_review') ->assertActionVisible('export_executive_pack') ->assertActionDisabled('export_executive_pack') ->assertActionVisible('archive_review') ->assertActionDisabled('archive_review'); Livewire::actingAs($owner) ->test(ViewTenantReview::class, ['record' => $review->getKey()]) ->mountAction('refresh_review') ->assertActionMounted('refresh_review'); Livewire::actingAs($owner) ->test(ViewTenantReview::class, ['record' => $review->getKey()]) ->mountAction('publish_review') ->assertActionMounted('publish_review'); $published = app(TenantReviewLifecycleService::class)->publish($review, $owner); Livewire::actingAs($owner) ->test(ViewTenantReview::class, ['record' => $published->getKey()]) ->mountAction('archive_review') ->assertActionMounted('archive_review'); }); it('shows publication truth and next-step guidance when a review is not yet publishable', function (): void { $tenant = Tenant::factory()->create(); [$owner, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $snapshot = seedTenantReviewEvidence($tenant); $review = TenantReview::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'evidence_snapshot_id' => (int) $snapshot->getKey(), 'initiated_by_user_id' => (int) $owner->getKey(), 'status' => 'draft', 'completeness_state' => 'complete', 'summary' => [ 'publish_blockers' => ['Review the approval note before publication.'], 'section_state_counts' => ['complete' => 6, 'partial' => 0, 'missing' => 0, 'stale' => 0], ], 'fingerprint' => hash('sha256', 'tenant-review-ui-contract'), 'generated_at' => now(), ]); $this->actingAs($owner) ->get(TenantReviewResource::tenantScopedUrl('view', ['record' => $review], $tenant)) ->assertOk() ->assertSee('Artifact truth') ->assertSee('Blocked') ->assertSee('Resolve the review blockers before publication'); });