TenantAtlas/apps/platform/tests/Feature/Baselines/BaselineCompareAmbiguousMatchGapTest.php
ahmido 788efee1c2 feat(baselines): implement baseline matching canonicalization (#453)
Replaced legacy tenant and environment bindings in the BaselineDriftEngine with the new ProviderResourceIdentity framework as defined in Spec 382. This ensures cross-environment compatibility and deterministic baseline matching.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #453
2026-06-15 22:48:48 +00:00

153 lines
6.0 KiB
PHP

<?php
use App\Jobs\CompareBaselineToTenantJob;
use App\Models\BaselineProfile;
use App\Models\BaselineSnapshot;
use App\Models\BaselineSnapshotItem;
use App\Models\Finding;
use App\Models\InventoryItem;
use App\Services\Baselines\BaselineSnapshotIdentity;
use App\Services\Intune\AuditLogger;
use App\Services\OperationRunService;
use App\Support\Baselines\BaselineSubjectKey;
use App\Support\Baselines\SubjectClass;
use App\Support\OperationRunOutcome;
use App\Support\OperationRunType;
use App\Support\Resources\ResourceIdentity;
use Tests\Feature\Baselines\Support\AssertsStructuredBaselineGaps;
it('treats duplicate provider identity matches as an evidence gap and suppresses findings', function () {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$identity = ResourceIdentity::providerResource('fake-provider', 'policy', 'duplicate-provider-id');
$subjectKey = spec382AmbiguousSubjectKey($identity);
$displayName = 'Duplicate Policy';
$meta = spec382AmbiguousMeta($identity, $displayName, 'baseline-etag');
$profile = BaselineProfile::factory()->active()->create([
'workspace_id' => (int) $tenant->workspace_id,
'scope_jsonb' => ['policy_types' => ['deviceConfiguration'], 'foundation_types' => []],
]);
$snapshot = BaselineSnapshot::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'baseline_profile_id' => (int) $profile->getKey(),
'captured_at' => now()->subMinute(),
]);
$profile->update(['active_snapshot_id' => (int) $snapshot->getKey()]);
BaselineSnapshotItem::factory()->create([
'baseline_snapshot_id' => (int) $snapshot->getKey(),
'subject_type' => 'policy',
'subject_external_id' => BaselineSubjectKey::workspaceSafeSubjectExternalId('deviceConfiguration', $subjectKey),
'subject_key' => $subjectKey,
'policy_type' => 'deviceConfiguration',
'baseline_hash' => hash('sha256', 'baseline'),
'meta_jsonb' => $meta + [
'evidence' => [
'fidelity' => 'content',
'source' => 'policy_version',
'observed_at' => now()->toIso8601String(),
],
],
]);
$inventorySyncRun = createInventorySyncOperationRunWithCoverage(
tenant: $tenant,
statusByType: ['deviceConfiguration' => 'succeeded'],
);
InventoryItem::factory()->create([
'managed_environment_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'external_id' => 'dup-1',
'policy_type' => 'deviceConfiguration',
'display_name' => $displayName,
'meta_jsonb' => spec382AmbiguousMeta($identity, $displayName, 'E1'),
'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(),
'last_seen_at' => now(),
]);
InventoryItem::factory()->create([
'managed_environment_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'external_id' => 'dup-2',
'policy_type' => 'deviceConfiguration',
'display_name' => 'Renamed Duplicate Policy',
'meta_jsonb' => spec382AmbiguousMeta($identity, 'Renamed Duplicate Policy', 'E2'),
'last_seen_operation_run_id' => (int) $inventorySyncRun->getKey(),
'last_seen_at' => now(),
]);
$opService = app(OperationRunService::class);
$run = $opService->ensureRunWithIdentity(
tenant: $tenant,
type: OperationRunType::BaselineCompare->value,
identityInputs: ['baseline_profile_id' => (int) $profile->getKey()],
context: [
'baseline_profile_id' => (int) $profile->getKey(),
'baseline_snapshot_id' => (int) $snapshot->getKey(),
'effective_scope' => ['policy_types' => ['deviceConfiguration'], 'foundation_types' => []],
],
initiator: $user,
);
(new CompareBaselineToTenantJob($run))->handle(
app(BaselineSnapshotIdentity::class),
app(AuditLogger::class),
$opService,
);
$run->refresh();
expect($run->status)->toBe('completed');
expect($run->outcome)->toBe(OperationRunOutcome::PartiallySucceeded->value);
expect(
Finding::query()
->where('managed_environment_id', (int) $tenant->getKey())
->where('source', 'baseline.compare')
->count(),
)->toBe(0);
$context = is_array($run->context) ? $run->context : [];
expect(data_get($context, 'baseline_compare.evidence_gaps.by_reason.ambiguous_match'))->toBe(1);
$gapSubjects = data_get($context, 'baseline_compare.evidence_gaps.subjects');
expect($gapSubjects)->toBeArray();
AssertsStructuredBaselineGaps::assertStructuredSubjects($gapSubjects);
$ambiguousSubject = collect($gapSubjects)->firstWhere('reason_code', 'ambiguous_match');
expect($ambiguousSubject)->toBeArray()
->and(data_get($ambiguousSubject, 'policy_type'))->toBe('deviceConfiguration')
->and(data_get($ambiguousSubject, 'subject_class'))->toBe('policy_backed')
->and(data_get($ambiguousSubject, 'resolution_outcome'))->toBe('ambiguous_match')
->and(data_get($ambiguousSubject, 'operator_action_category'))->toBe('inspect_subject_mapping')
->and(data_get($ambiguousSubject, 'subject_key'))->toBe($subjectKey);
});
function spec382AmbiguousSubjectKey(ResourceIdentity $identity): string
{
$subjectKey = BaselineSubjectKey::forProviderResourceIdentity(
subjectDomain: 'baseline',
subjectClass: SubjectClass::PolicyBacked,
subjectTypeKey: 'deviceConfiguration',
identity: $identity,
);
expect($subjectKey)->not->toBeNull();
return (string) $subjectKey;
}
function spec382AmbiguousMeta(ResourceIdentity $identity, string $displayName, string $etag): array
{
return [
'display_name' => $displayName,
'provider_key' => $identity->providerKey,
'provider_resource_identity' => $identity->toArray(),
'provider_resource_fingerprint' => $identity->fingerprint(),
'odata_type' => 'fake.policy',
'etag' => $etag,
];
}