create([ 'tenant_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_PERMISSION_POSTURE, 'payload' => ['required_count' => 1, 'granted_count' => 1], ]); StoredReport::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'report_type' => StoredReport::REPORT_TYPE_ENTRA_ADMIN_ROLES, 'payload' => ['roles' => [['displayName' => 'Global Administrator']]], ]); Finding::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, ]); Finding::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'finding_type' => Finding::FINDING_TYPE_DRIFT, ]); OperationRun::factory()->forTenant($tenant)->create(); /** @var EvidenceSnapshotService $service */ $service = app(EvidenceSnapshotService::class); $payload = $service->buildSnapshotPayload($tenant); $snapshot = EvidenceSnapshot::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'status' => EvidenceSnapshotStatus::Active->value, 'fingerprint' => $payload['fingerprint'], 'completeness_state' => $payload['completeness'], 'summary' => $payload['summary'], 'generated_at' => now(), ]); foreach ($payload['items'] as $item) { $snapshot->items()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'dimension_key' => $item['dimension_key'], 'state' => $item['state'], 'required' => $item['required'], 'source_kind' => $item['source_kind'], 'source_record_type' => $item['source_record_type'], 'source_record_id' => $item['source_record_id'], 'source_fingerprint' => $item['source_fingerprint'], 'measured_at' => $item['measured_at'], 'freshness_at' => $item['freshness_at'], 'summary_payload' => $item['summary_payload'], 'sort_order' => $item['sort_order'], ]); } return $snapshot; } // ─── No Pack State ─────────────────────────────────────────── it('shows the generate CTA when no pack exists', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('No review pack generated yet') ->assertSee('Generate') ->assertDontSee('wire:poll.10s', escape: false); }); // ─── Ready State ───────────────────────────────────────────── it('shows download and generate buttons when a ready pack exists', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); $filePath = 'review-packs/widget-test.zip'; Storage::disk('exports')->put($filePath, 'PK-test'); ReviewPack::factory()->ready()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), 'file_path' => $filePath, 'file_disk' => 'exports', ]); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('Download') ->assertSee('Generate new') ->assertDontSee('wire:poll.10s', escape: false); }); // ─── Generating State ──────────────────────────────────────── it('shows in-progress message for a generating pack', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->generating()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('Generation in progress') ->assertSee('wire:poll.10s', escape: false); }); // ─── Queued State ──────────────────────────────────────────── it('shows in-progress message for a queued pack', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->queued()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('Generation in progress') ->assertSee('wire:poll.10s', escape: false); }); // ─── Failed State ──────────────────────────────────────────── it('shows retry button for a failed pack', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->failed()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('Retry') ->assertDontSee('wire:poll.10s', escape: false); }); // ─── Expired State ─────────────────────────────────────────── it('shows generate action for an expired pack', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); ReviewPack::factory()->expired()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'initiated_by_user_id' => (int) $user->getKey(), ]); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->assertSee('Generate new') ->assertDontSee('wire:poll.10s', escape: false); }); // ─── Generate Pack Livewire Action ────────────────────────── it('can trigger generatePack Livewire action', function (): void { $tenant = Tenant::factory()->create(); [$user, $tenant] = createUserWithTenant(tenant: $tenant, role: 'owner'); seedWidgetReviewPackSnapshot($tenant); setTenantPanelContext($tenant); Livewire::actingAs($user) ->test(TenantReviewPackCard::class, ['record' => $tenant]) ->call('generatePack', true, true) ->assertHasNoErrors(); expect(ReviewPack::query()->where('tenant_id', (int) $tenant->getKey())->count())->toBe(1); });