active()->create([ 'workspace_id' => (int) $tenant->workspace_id, ]); $snapshot = BaselineSnapshot::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'baseline_profile_id' => (int) $profile->getKey(), ]); $profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]); BaselineTenantAssignment::factory()->create([ 'workspace_id' => (int) $tenant->workspace_id, 'tenant_id' => (int) $tenant->getKey(), 'baseline_profile_id' => (int) $profile->getKey(), ]); \App\Models\OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $tenant->workspace_id, 'type' => OperationRunType::BaselineCompare->value, 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'completed_at' => now(), 'context' => [ 'baseline_profile_id' => (int) $profile->getKey(), 'baseline_snapshot_id' => (int) $snapshot->getKey(), 'baseline_compare' => [ 'reason_code' => BaselineCompareReasonCode::NoDriftDetected->value, 'coverage' => [ 'effective_types' => ['deviceConfiguration'], 'covered_types' => ['deviceConfiguration'], 'uncovered_types' => [], 'proof' => true, ], ], ], ]); return [$user, $tenant]; } it('reuses one tenant-governance aggregate across the tenant dashboard summary widgets', function (): void { [$user, $tenant] = createTenantGovernanceMemoizationTenant(); $this->actingAs($user); Filament::setCurrentPanel(Filament::getPanel('tenant')); Filament::setTenant($tenant, true); Livewire::actingAs($user)->test(NeedsAttention::class); Livewire::actingAs($user)->test(BaselineCompareNow::class); expect(app(RequestScopedDerivedStateStore::class)->countStored( DerivedStateFamily::TenantGovernanceAggregate, Tenant::class, (string) $tenant->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1); }); it('keeps tenant switches from reusing another tenant aggregate in the same request scope', function (): void { [, $tenantA] = createTenantGovernanceMemoizationTenant(); [, $tenantB] = createTenantGovernanceMemoizationTenant(); $resolver = app(TenantGovernanceAggregateResolver::class); $aggregateA = $resolver->forTenant($tenantA); $aggregateB = $resolver->forTenant($tenantB); $store = app(RequestScopedDerivedStateStore::class); expect($aggregateA)->not->toBeNull() ->and($aggregateB)->not->toBeNull() ->and($aggregateA?->tenantId)->toBe((int) $tenantA->getKey()) ->and($aggregateB?->tenantId)->toBe((int) $tenantB->getKey()) ->and($aggregateA?->tenantId)->not->toBe($aggregateB?->tenantId) ->and($store->countStored( DerivedStateFamily::TenantGovernanceAggregate, Tenant::class, (string) $tenantA->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1) ->and($store->countStored( DerivedStateFamily::TenantGovernanceAggregate, Tenant::class, (string) $tenantB->getKey(), TenantGovernanceAggregateResolver::VARIANT_TENANT_GOVERNANCE_SUMMARY, ))->toBe(1); }); it('returns no aggregate and stores nothing when no tenant context exists', function (): void { $aggregate = app(TenantGovernanceAggregateResolver::class)->forTenant(null); expect($aggregate)->toBeNull() ->and(app(RequestScopedDerivedStateStore::class)->countStored( DerivedStateFamily::TenantGovernanceAggregate, ))->toBe(0); });