set('graph.client_id', 'platform-client-id'); config()->set('graph.client_secret', 'platform-client-secret'); $platformTenant = Tenant::factory()->create([ 'tenant_id' => 'platform-classification-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $platformConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'tenant_id' => (int) $platformTenant->getKey(), 'workspace_id' => (int) $platformTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'platform-classification-tenant-id', 'is_default' => true, ]); $dedicatedTenant = Tenant::factory()->create([ 'tenant_id' => 'dedicated-classification-tenant-id', 'app_client_id' => null, 'app_client_secret' => null, ]); $dedicatedConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'tenant_id' => (int) $dedicatedTenant->getKey(), 'workspace_id' => (int) $dedicatedTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'dedicated-classification-tenant-id', 'is_default' => true, ]); $dedicatedCredential = ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $dedicatedConnection->getKey(), 'source' => null, 'credential_kind' => null, 'payload' => [ 'client_id' => 'legacy-dedicated-client-id', 'client_secret' => 'legacy-dedicated-client-secret', ], ]); $hybridTenant = Tenant::factory()->create([ 'tenant_id' => 'hybrid-classification-tenant-id', 'app_client_id' => 'legacy-tenant-client-id', 'app_client_secret' => 'legacy-tenant-client-secret', ]); $hybridConnection = ProviderConnection::factory()->platform()->verifiedHealthy()->create([ 'tenant_id' => (int) $hybridTenant->getKey(), 'workspace_id' => (int) $hybridTenant->workspace_id, 'provider' => 'microsoft', 'entra_tenant_id' => 'hybrid-classification-tenant-id', 'is_default' => true, ]); ProviderCredential::factory()->create([ 'provider_connection_id' => (int) $hybridConnection->getKey(), 'source' => null, 'payload' => [ 'client_id' => 'legacy-different-client-id', 'client_secret' => 'legacy-different-client-secret', ], ]); $this->artisan('tenantpilot:provider-connections:classify', ['--write' => true]) ->expectsOutputToContain('Applied classifications: 3') ->expectsOutputToContain('Review required: 1') ->assertSuccessful(); $platformConnection->refresh(); $dedicatedConnection->refresh(); $hybridConnection->refresh(); $dedicatedCredential->refresh(); expect($platformConnection->connection_type->value)->toBe('platform') ->and($platformConnection->migration_review_required)->toBeFalse() ->and($platformConnection->metadata)->toMatchArray([ 'legacy_identity_result' => 'platform', 'effective_app' => [ 'app_id' => 'platform-client-id', 'source' => 'platform_config', ], ]); expect($dedicatedConnection->connection_type->value)->toBe('dedicated') ->and($dedicatedConnection->migration_review_required)->toBeFalse() ->and($dedicatedConnection->metadata)->toMatchArray([ 'legacy_identity_result' => 'dedicated', 'effective_app' => [ 'app_id' => 'legacy-dedicated-client-id', 'source' => 'dedicated_credential', ], ]); expect($dedicatedCredential->source)->toBe(ProviderCredentialSource::LegacyMigrated) ->and($dedicatedCredential->credential_kind)->toBe(ProviderCredentialKind::ClientSecret); expect($hybridConnection->connection_type->value)->toBe('dedicated') ->and($hybridConnection->migration_review_required)->toBeTrue() ->and($hybridConnection->verification_status->value)->toBe('blocked') ->and($hybridConnection->status)->toBe('error') ->and($hybridConnection->health_status)->toBe('down') ->and($hybridConnection->last_error_reason_code)->toBe(ProviderReasonCodes::ProviderConnectionReviewRequired) ->and($hybridConnection->metadata)->toMatchArray([ 'legacy_identity_review_required' => true, 'legacy_identity_result' => 'dedicated', 'effective_app' => [ 'app_id' => null, 'source' => 'review_required', ], ]); });