create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspace->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $this->actingAs($user); $tenantGuid = '10101010-1010-1010-1010-101010101010'; $component = Livewire::actingAs($user)->test(ManagedTenantOnboardingWizard::class); $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $tenantGuid, 'environment' => 'prod', 'name' => 'Acme', 'primary_domain' => 'acme.example', 'notes' => 'Provider start test', ]); $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); OperationRun::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'inventory_sync', 'status' => 'queued', 'outcome' => 'pending', 'run_identity_hash' => sha1('busy-onboarding-'.(string) $connection->getKey()), 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), ], ]); $component->set('selectedProviderConnectionId', (int) $connection->getKey()); $component->call('startVerification'); expect(OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'provider.connection.check') ->count())->toBe(0); Bus::assertNotDispatched(ProviderConnectionHealthCheckJob::class); }); it('serializes onboarding bootstrap so only one selected provider-backed action starts at a time', function (): void { Bus::fake(); $workspace = Workspace::factory()->create(); $user = User::factory()->create(); WorkspaceMembership::factory()->create([ 'workspace_id' => $workspace->getKey(), 'user_id' => $user->getKey(), 'role' => 'owner', ]); session()->put(WorkspaceContext::SESSION_KEY, (int) $workspace->getKey()); $this->actingAs($user); $tenantGuid = '20202020-2020-2020-2020-202020202020'; $component = Livewire::actingAs($user)->test(ManagedTenantOnboardingWizard::class); $component->call('identifyManagedTenant', [ 'entra_tenant_id' => $tenantGuid, 'environment' => 'prod', 'name' => 'Acme', 'primary_domain' => 'acme.example', 'notes' => 'Provider start test', ]); $tenant = Tenant::query()->where('tenant_id', $tenantGuid)->firstOrFail(); $connection = ProviderConnection::factory()->platform()->consentGranted()->create([ 'tenant_id' => (int) $tenant->getKey(), 'provider' => 'microsoft', 'entra_tenant_id' => $tenantGuid, 'is_default' => true, ]); $verificationRun = OperationRun::query()->create([ 'tenant_id' => (int) $tenant->getKey(), 'user_id' => (int) $user->getKey(), 'initiator_name' => $user->name, 'type' => 'provider.connection.check', 'status' => 'completed', 'outcome' => 'succeeded', 'run_identity_hash' => sha1('verify-ok-bootstrap-provider-start-'.(string) $connection->getKey()), 'context' => [ 'provider_connection_id' => (int) $connection->getKey(), ], ]); $session = TenantOnboardingSession::query() ->where('workspace_id', (int) $workspace->getKey()) ->where('tenant_id', (int) $tenant->getKey()) ->firstOrFail(); $session->update([ 'state' => array_merge($session->state ?? [], [ 'provider_connection_id' => (int) $connection->getKey(), 'verification_operation_run_id' => (int) $verificationRun->getKey(), ]), ]); $component->call('startBootstrap', ['inventory_sync', 'compliance.snapshot']); $inventoryRun = OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'inventory_sync') ->latest('id') ->firstOrFail(); expect(OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(0); $inventoryRun->forceFill([ 'status' => 'completed', 'outcome' => 'succeeded', ])->save(); $component->call('startBootstrap', ['inventory_sync', 'compliance.snapshot']); expect(OperationRun::query() ->where('tenant_id', (int) $tenant->getKey()) ->where('type', 'compliance.snapshot') ->count())->toBe(1); Bus::assertDispatchedTimes(ProviderInventorySyncJob::class, 1); Bus::assertDispatchedTimes(ProviderComplianceSnapshotJob::class, 1); });