Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 1m12s
Replaced legacy tenant and environment bindings in the BaselineDriftEngine with the new ProviderResourceIdentity framework as defined in Spec 382.
127 lines
5.4 KiB
PHP
127 lines
5.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Jobs\CaptureBaselineSnapshotJob;
|
|
use App\Jobs\CompareBaselineToTenantJob;
|
|
use App\Models\BaselineProfile;
|
|
use App\Models\BaselineSnapshot;
|
|
use App\Models\BaselineTenantAssignment;
|
|
use App\Services\Baselines\BaselineCaptureService;
|
|
use App\Services\Baselines\BaselineCompareService;
|
|
use App\Support\Baselines\BaselineCaptureMode;
|
|
use App\Support\Baselines\BaselineReasonCodes;
|
|
use App\Support\Baselines\BaselineSupportCapabilityGuard;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Bus;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
function appendBrokenFoundationSupportConfig(): void
|
|
{
|
|
$foundationTypes = is_array(config('tenantpilot.foundation_types')) ? config('tenantpilot.foundation_types') : [];
|
|
$foundationTypes[] = [
|
|
'type' => 'brokenFoundation',
|
|
'label' => 'Broken Foundation',
|
|
'baseline_compare' => [
|
|
'supported' => true,
|
|
'identity_strategy' => 'provider_resource',
|
|
'resolution' => [
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_policy',
|
|
'compare_capability' => 'supported',
|
|
'capture_capability' => 'supported',
|
|
'source_model_expected' => 'inventory',
|
|
],
|
|
],
|
|
];
|
|
|
|
config()->set('tenantpilot.foundation_types', $foundationTypes);
|
|
}
|
|
|
|
it('persists truthful compare scope capability decisions before dispatching compare work', function (): void {
|
|
Bus::fake();
|
|
appendBrokenFoundationSupportConfig();
|
|
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$profile = BaselineProfile::factory()->active()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'capture_mode' => BaselineCaptureMode::Opportunistic->value,
|
|
'scope_jsonb' => [
|
|
'policy_types' => ['deviceConfiguration'],
|
|
'foundation_types' => ['roleScopeTag', 'brokenFoundation', 'unknownFoundation'],
|
|
],
|
|
]);
|
|
|
|
$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,
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'baseline_profile_id' => (int) $profile->getKey(),
|
|
]);
|
|
|
|
$result = app(BaselineCompareService::class)->startCompare($tenant, $user);
|
|
|
|
expect($result['ok'])->toBeTrue();
|
|
|
|
$run = $result['run'];
|
|
$scope = data_get($run->context, 'effective_scope');
|
|
|
|
expect(data_get($scope, 'truthful_types'))->toBe(['deviceConfiguration', 'roleScopeTag'])
|
|
->and(data_get($scope, 'limited_types'))->toBe(['roleScopeTag'])
|
|
->and(data_get($scope, 'all_types'))->toBe(['brokenFoundation', 'deviceConfiguration', 'roleScopeTag'])
|
|
->and(data_get($scope, 'unsupported_types'))->toBe(['brokenFoundation'])
|
|
->and(data_get($scope, 'invalid_support_types'))->toBe(['brokenFoundation'])
|
|
->and(data_get($scope, 'capabilities.deviceConfiguration.support_mode'))->toBe('supported')
|
|
->and(data_get($scope, 'capabilities.roleScopeTag.support_mode'))->toBe('limited')
|
|
->and(data_get($scope, 'capabilities.brokenFoundation.support_mode'))->toBe('invalid_support_config')
|
|
->and(data_get($scope, 'capabilities.unknownFoundation.support_mode'))->toBeNull();
|
|
|
|
Bus::assertDispatched(CompareBaselineToTenantJob::class);
|
|
});
|
|
|
|
it('blocks capture work when the scope still contains unsupported types, while preserving truthful capability context', function (): void {
|
|
Bus::fake();
|
|
appendBrokenFoundationSupportConfig();
|
|
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
$profile = BaselineProfile::factory()->active()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'capture_mode' => BaselineCaptureMode::Opportunistic->value,
|
|
'scope_jsonb' => [
|
|
'policy_types' => ['deviceConfiguration'],
|
|
'foundation_types' => ['roleScopeTag', 'brokenFoundation', 'unknownFoundation'],
|
|
],
|
|
]);
|
|
|
|
$result = app(BaselineCaptureService::class)->startCapture($profile, $tenant, $user);
|
|
|
|
$scope = $profile->normalizedScope()->toEffectiveScopeContext(
|
|
app(BaselineSupportCapabilityGuard::class),
|
|
'capture',
|
|
);
|
|
|
|
expect($result['ok'])->toBeFalse()
|
|
->and($result['reason_code'] ?? null)->toBe(BaselineReasonCodes::CAPTURE_UNSUPPORTED_SCOPE);
|
|
|
|
expect(data_get($scope, 'truthful_types'))->toBe(['deviceConfiguration', 'roleScopeTag'])
|
|
->and(data_get($scope, 'limited_types'))->toBe(['roleScopeTag'])
|
|
->and(data_get($scope, 'all_types'))->toBe(['brokenFoundation', 'deviceConfiguration', 'roleScopeTag'])
|
|
->and(data_get($scope, 'unsupported_types'))->toBe(['brokenFoundation'])
|
|
->and(data_get($scope, 'invalid_support_types'))->toBe(['brokenFoundation'])
|
|
->and(data_get($scope, 'capabilities.deviceConfiguration.support_mode'))->toBe('supported')
|
|
->and(data_get($scope, 'capabilities.roleScopeTag.support_mode'))->toBe('limited')
|
|
->and(data_get($scope, 'capabilities.brokenFoundation.support_mode'))->toBe('invalid_support_config')
|
|
->and(data_get($scope, 'capabilities.unknownFoundation.support_mode'))->toBeNull();
|
|
|
|
Bus::assertNotDispatched(CaptureBaselineSnapshotJob::class);
|
|
});
|