Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 4m7s
Implemented deterministic Baseline Result Semantics (Spec 383), introducing CompareSubjectResult and CompareEvidenceResult. Replaced generic arrays with strict Data Transfer Objects for Baseline engine output.
134 lines
4.9 KiB
PHP
134 lines
4.9 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Models\BaselineProfile;
|
|
use App\Models\BaselineSnapshot;
|
|
use App\Models\BaselineTenantAssignment;
|
|
use App\Models\OperationRun;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\OperationRunStatus;
|
|
use App\Support\OperationRunType;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Filament\Facades\Filament;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Tests\Feature\Baselines\Support\BaselineSubjectResolutionFixtures;
|
|
|
|
uses(RefreshDatabase::class);
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
function structuredGapSurfaceContext(): array
|
|
{
|
|
return array_replace_recursive(BaselineSubjectResolutionFixtures::compareContext([
|
|
BaselineSubjectResolutionFixtures::structuredGap([
|
|
'policy_type' => 'deviceConfiguration',
|
|
'subject_key' => 'WiFi-Corp-Profile',
|
|
'subject_class' => 'policy_backed',
|
|
'resolution_path' => 'policy',
|
|
'resolution_outcome' => 'missing_local_evidence',
|
|
'reason_code' => 'missing_local_evidence',
|
|
'operator_action_category' => 'run_policy_sync_or_backup',
|
|
]),
|
|
BaselineSubjectResolutionFixtures::structuredGap([
|
|
'policy_type' => 'roleScopeTag',
|
|
'subject_key' => 'scope-tag-finance',
|
|
'subject_class' => 'foundation_backed',
|
|
'resolution_path' => 'foundation_inventory',
|
|
'resolution_outcome' => 'foundation_inventory_only',
|
|
'reason_code' => 'foundation_inventory_only',
|
|
'operator_action_category' => 'product_follow_up',
|
|
'structural' => true,
|
|
]),
|
|
]), [
|
|
'baseline_compare' => [
|
|
'reason_code' => 'compare_evidence_incomplete',
|
|
'coverage' => [
|
|
'proof' => true,
|
|
'covered_types' => ['deviceConfiguration', 'roleScopeTag'],
|
|
'uncovered_types' => [],
|
|
'effective_types' => ['deviceConfiguration', 'roleScopeTag'],
|
|
],
|
|
'fidelity' => 'meta',
|
|
],
|
|
]);
|
|
}
|
|
|
|
it('renders canonical run detail gap semantics from persisted db context only', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
|
|
bindFailHardGraphClient();
|
|
Filament::setTenant(null, true);
|
|
|
|
$run = OperationRun::factory()->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'type' => OperationRunType::BaselineCompare->value,
|
|
'status' => OperationRunStatus::Completed->value,
|
|
'outcome' => OperationRunOutcome::PartiallySucceeded->value,
|
|
'context' => structuredGapSurfaceContext(),
|
|
'completed_at' => now(),
|
|
]);
|
|
|
|
$this->actingAs($user)
|
|
->withSession([WorkspaceContext::SESSION_KEY => (int) $tenant->workspace_id])
|
|
->get(\App\Support\OperationRunLinks::tenantlessView($run))
|
|
->assertOk()
|
|
->assertSee('Evidence gap details')
|
|
->assertSee('Policy-backed')
|
|
->assertSee('Foundation-backed')
|
|
->assertSee('Missing local evidence')
|
|
->assertSee('Foundation inventory only')
|
|
->assertSee('Run policy sync or backup')
|
|
->assertSee('Product follow-up')
|
|
->assertSee('WiFi-Corp-Profile')
|
|
->assertSee('scope-tag-finance');
|
|
});
|
|
|
|
it('renders tenant landing gap semantics from persisted db context only', function (): void {
|
|
[$user, $tenant] = createUserWithTenant(role: 'owner');
|
|
$this->actingAs($user);
|
|
|
|
bindFailHardGraphClient();
|
|
$tenant->makeCurrent();
|
|
Filament::setTenant($tenant, true);
|
|
|
|
$profile = BaselineProfile::factory()->active()->create([
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
]);
|
|
|
|
$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(),
|
|
]);
|
|
|
|
OperationRun::factory()->create([
|
|
'managed_environment_id' => (int) $tenant->getKey(),
|
|
'workspace_id' => (int) $tenant->workspace_id,
|
|
'type' => OperationRunType::BaselineCompare->value,
|
|
'status' => OperationRunStatus::Completed->value,
|
|
'outcome' => OperationRunOutcome::PartiallySucceeded->value,
|
|
'context' => structuredGapSurfaceContext(),
|
|
'completed_at' => now(),
|
|
]);
|
|
|
|
baselineCompareLandingLivewire($tenant)
|
|
->assertSee('Evidence gap details')
|
|
->assertSee('Subject class')
|
|
->assertSee('Outcome')
|
|
->assertSee('Next action')
|
|
->assertSee('Foundation-backed')
|
|
->assertSee('Foundation inventory only')
|
|
->assertSee('Product follow-up')
|
|
->assertSee('scope-tag-finance');
|
|
});
|