TenantAtlas/apps/platform/tests/Feature/Baselines/Support/BaselineSubjectResolutionFixtures.php
ahmido 39298f27f2 feat(ui): implement baseline subject resolution ui (#455)
Added `BaselineSubjectResolution` page and supporting logic to visualize missing identities, ambiguous matches, and skipped coverages as defined in Spec 384. Replaces legacy compare warnings with an actionable, deterministic UI surface.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #455
2026-06-16 23:36:38 +00:00

148 lines
5.3 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Feature\Baselines\Support;
use App\Models\InventoryItem;
use App\Support\Baselines\OperatorActionCategory;
use App\Support\Baselines\ResolutionOutcome;
use App\Support\Baselines\ResolutionPath;
use App\Support\Baselines\SubjectClass;
use App\Support\Resources\ProviderResourceDescriptor;
use App\Support\Resources\ResourceIdentity;
final class BaselineSubjectResolutionFixtures
{
/**
* @param array<string, mixed> $overrides
* @return array<string, mixed>
*/
public static function structuredGap(array $overrides = []): array
{
return array_replace([
'policy_type' => 'deviceConfiguration',
'subject_external_id' => 'subject-1',
'subject_key' => 'deviceconfiguration|subject-1',
'subject_class' => SubjectClass::PolicyBacked->value,
'resolution_path' => ResolutionPath::Policy->value,
'resolution_outcome' => ResolutionOutcome::PolicyRecordMissing->value,
'reason_code' => 'policy_record_missing',
'operator_action_category' => OperatorActionCategory::RunPolicySyncOrBackup->value,
'structural' => false,
'retryable' => false,
'source_model_expected' => 'policy',
'source_model_found' => null,
], $overrides);
}
/**
* @param list<array<string, mixed>> $subjects
* @param array<string, mixed> $overrides
* @return array<string, mixed>
*/
public static function compareContext(array $subjects, array $overrides = []): array
{
$byReason = [];
foreach ($subjects as $subject) {
$reasonCode = is_string($subject['reason_code'] ?? null) ? $subject['reason_code'] : 'unknown';
$byReason[$reasonCode] = ($byReason[$reasonCode] ?? 0) + 1;
}
return array_replace_recursive([
'baseline_compare' => [
'evidence_gaps' => [
'count' => count($subjects),
'by_reason' => $byReason,
'subjects' => $subjects,
],
],
], $overrides);
}
/**
* @param list<array<string, mixed>> $subjects
* @param array<string, mixed> $overrides
* @return array<string, mixed>
*/
public static function captureContext(array $subjects, array $overrides = []): array
{
$byReason = [];
foreach ($subjects as $subject) {
$reasonCode = is_string($subject['reason_code'] ?? null) ? $subject['reason_code'] : 'unknown';
$byReason[$reasonCode] = ($byReason[$reasonCode] ?? 0) + 1;
}
return array_replace_recursive([
'baseline_capture' => [
'gaps' => [
'count' => count($subjects),
'by_reason' => $byReason,
'subjects' => $subjects,
],
],
], $overrides);
}
/**
* @param array<string, mixed> $overrides
* @return array<string, mixed>
*/
public static function semanticOutcome(array $overrides = []): array
{
return array_replace_recursive([
'reason' => 'identity_required',
'category' => 'action_required',
'actionability' => 'binding_required',
'readiness_impact' => 'customer_blocker',
'identity_status' => 'unresolved',
'comparison_status' => 'not_compared',
'coverage_status' => 'missing_local_evidence',
'trust_level' => 'untrusted',
'subject' => [
'subject_domain' => 'baseline',
'subject_class' => SubjectClass::PolicyBacked->value,
'subject_type_key' => 'deviceConfiguration',
'subject_key' => 'subject-key',
'display_label' => 'Subject label',
],
'proof' => [],
], $overrides);
}
public static function inventoryCandidate(mixed $tenant, ResourceIdentity $identity, string $displayName): InventoryItem
{
$descriptor = self::providerDescriptor($identity, $displayName);
return InventoryItem::factory()->create([
'workspace_id' => (int) $tenant->workspace_id,
'managed_environment_id' => (int) $tenant->getKey(),
'policy_type' => 'deviceConfiguration',
'external_id' => $identity->providerResourceId,
'display_name' => $displayName,
'meta_jsonb' => [
'provider_resource_descriptor' => $descriptor->toArray(),
'provider_resource_identity' => $identity->toArray(),
'provider_resource_fingerprint' => $identity->fingerprint(),
],
'last_seen_at' => now(),
]);
}
public static function providerDescriptor(ResourceIdentity $identity, string $displayName): ProviderResourceDescriptor
{
return ProviderResourceDescriptor::fromIdentity(
identity: $identity,
subjectDomain: 'baseline',
subjectClass: SubjectClass::PolicyBacked,
subjectTypeKey: 'deviceConfiguration',
displayLabel: $displayName,
sourceReferences: [],
fingerprint: $identity->fingerprint(),
lastSeenAt: now()->toIso8601String(),
);
}
}