Some checks failed
Main Confidence / confidence (push) Failing after 53s
Automated commit and PR created by Copilot per user request. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #287
190 lines
6.5 KiB
PHP
190 lines
6.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\Workspaces\ManagedTenantOnboardingWizard;
|
|
use App\Models\AuditLog;
|
|
use App\Models\OperationRun;
|
|
use App\Models\ProviderConnection;
|
|
use App\Models\Tenant;
|
|
use App\Models\TenantOnboardingSession;
|
|
use App\Models\User;
|
|
use App\Models\Workspace;
|
|
use App\Services\Entitlements\WorkspaceEntitlementResolver;
|
|
use App\Services\Settings\SettingsWriter;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Illuminate\Support\Facades\Queue;
|
|
use Livewire\Livewire;
|
|
|
|
/**
|
|
* @return array{workspace: Workspace, user: User, tenant: Tenant, draft: TenantOnboardingSession, component: \Livewire\Features\SupportTesting\Testable}
|
|
*/
|
|
function readyOnboardingEntitlementContext(int $activeTenantCount = 0, ?int $limitOverride = null, ?string $overrideReason = null): array
|
|
{
|
|
Queue::fake();
|
|
|
|
$workspace = Workspace::factory()->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);
|
|
}); |