create(); $user = User::factory()->create(); $tenant = Tenant::factory()->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => Tenant::STATUS_ONBOARDING, ]); createUserWithTenant( tenant: $tenant, user: $user, role: 'owner', workspaceRole: 'owner', ensureDefaultMicrosoftProviderConnection: false, ); if ($activeTenantCount > 0) { Tenant::factory()->count($activeTenantCount)->create([ 'workspace_id' => (int) $workspace->getKey(), 'status' => Tenant::STATUS_ACTIVE, ]); } $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'workspace_id' => (int) $workspace->getKey(), 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => (string) $tenant->tenant_id, 'display_name' => 'Ready connection', 'is_default' => true, 'consent_status' => 'granted', ]); $run = OperationRun::factory()->create([ 'tenant_id' => (int) $tenant->getKey(), 'workspace_id' => (int) $workspace->getKey(), 'user_id' => (int) $user->getKey(), 'type' => 'provider.connection.check', 'status' => OperationRunStatus::Completed->value, 'outcome' => OperationRunOutcome::Succeeded->value, 'context' => [ 'provider' => 'microsoft', 'module' => 'health_check', 'provider_connection_id' => (int) $connection->getKey(), 'target_scope' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, ], ], ]); $draft = createOnboardingDraft([ 'workspace' => $workspace, 'tenant' => $tenant, 'started_by' => $user, 'updated_by' => $user, 'current_step' => 'bootstrap', 'state' => [ 'entra_tenant_id' => (string) $tenant->tenant_id, 'tenant_name' => (string) $tenant->name, 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $run->getKey(), ], ]); if ($limitOverride !== null) { $writer = app(SettingsWriter::class); $writer->updateWorkspaceSetting( actor: $user, workspace: $workspace, domain: WorkspaceEntitlementResolver::SETTING_DOMAIN, key: WorkspaceEntitlementResolver::SETTING_MANAGED_TENANT_LIMIT_OVERRIDE_VALUE, value: $limitOverride, ); if ($overrideReason !== null) { $writer->updateWorkspaceSetting( actor: $user, workspace: $workspace, domain: WorkspaceEntitlementResolver::SETTING_DOMAIN, key: WorkspaceEntitlementResolver::SETTING_MANAGED_TENANT_LIMIT_OVERRIDE_REASON, value: $overrideReason, ); } } session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $component = Livewire::actingAs($user)->test(ManagedTenantOnboardingWizard::class, [ 'onboardingDraft' => (int) $draft->getKey(), ]); return compact('workspace', 'user', 'tenant', 'draft', 'component'); } it('allows onboarding activation when the workspace is within its managed tenant limit', function (): void { $context = readyOnboardingEntitlementContext(activeTenantCount: 0); $context['component']->call('completeOnboarding'); $context['tenant']->refresh(); expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') ->exists())->toBeTrue(); }); it('blocks onboarding activation with a business-state reason when the workspace is at limit', function (): void { $context = readyOnboardingEntitlementContext( activeTenantCount: 1, limitOverride: 1, overrideReason: 'Customer currently allows one active tenant', ); $decision = app(WorkspaceEntitlementResolver::class)->resolve( $context['workspace'], WorkspaceEntitlementResolver::KEY_MANAGED_TENANT_ACTIVATION_LIMIT, ); expect($decision['is_blocked'])->toBeTrue(); $context['component'] ->assertSee('Activation entitlement') ->assertSee('Blocked') ->call('completeOnboarding'); $context['tenant']->refresh(); expect($context['tenant']->status)->toBe(Tenant::STATUS_ONBOARDING) ->and(AuditLog::query() ->where('workspace_id', (int) $context['workspace']->getKey()) ->where('action', 'managed_tenant_onboarding.activation') ->exists())->toBeFalse(); }); it('allows onboarding activation when a workspace override raises the limit above current usage', function (): void { $context = readyOnboardingEntitlementContext( activeTenantCount: 1, limitOverride: 2, overrideReason: 'Temporary support-approved exception', ); $decision = app(WorkspaceEntitlementResolver::class)->resolve( $context['workspace'], WorkspaceEntitlementResolver::KEY_MANAGED_TENANT_ACTIVATION_LIMIT, ); expect($decision) ->toMatchArray([ 'source' => 'workspace_override', 'effective_value' => 2, 'current_usage' => 1, 'is_blocked' => false, 'rationale' => 'Temporary support-approved exception', ]); $context['component']->call('completeOnboarding'); $context['tenant']->refresh(); expect($context['tenant']->status)->toBe(Tenant::STATUS_ACTIVE); });