TenantAtlas/tests/Feature/Filament/FindingViewRbacEvidenceTest.php
2026-03-09 19:43:13 +01:00

151 lines
5.7 KiB
PHP

<?php
declare(strict_types=1);
use App\Filament\Resources\FindingResource;
use App\Filament\Widgets\Dashboard\RecentDriftFindings;
use App\Models\Finding;
use App\Models\InventoryItem;
use App\Support\Baselines\BaselineSubjectKey;
use Filament\Facades\Filament;
use Livewire\Livewire;
it('renders readable role definition evidence and no-restore messaging on the finding detail page', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$subjectExternalId = BaselineSubjectKey::workspaceSafeSubjectExternalIdForPolicy(
'intuneRoleDefinition',
'Security Reader',
'rbac-role-1',
);
$finding = Finding::factory()->create([
'tenant_id' => (int) $tenant->getKey(),
'finding_type' => Finding::FINDING_TYPE_DRIFT,
'source' => 'baseline.compare',
'subject_type' => 'policy',
'subject_external_id' => (string) $subjectExternalId,
'evidence_fidelity' => 'content',
'severity' => Finding::SEVERITY_LOW,
'evidence_jsonb' => [
'change_type' => 'different_version',
'policy_type' => 'intuneRoleDefinition',
'subject_key' => hash('sha256', 'intuneRoleDefinition|rbac-role-1'),
'display_name' => 'Security Reader',
'summary' => [
'kind' => 'rbac_role_definition',
],
'baseline' => [
'policy_version_id' => 10,
'hash' => 'baseline',
],
'current' => [
'policy_version_id' => 11,
'hash' => 'current',
],
'rbac_role_definition' => [
'diff_kind' => 'metadata_only',
'diff_fingerprint' => 'rbac-diff-1',
'changed_keys' => ['Role definition > Description'],
'metadata_keys' => ['Role definition > Description'],
'permission_keys' => [],
'baseline' => [
'normalized' => [
'Role definition > Display name' => 'Security Reader',
'Role definition > Description' => 'Baseline description',
'Role definition > Role source' => 'Custom',
],
'is_built_in' => false,
'role_permission_count' => 1,
],
'current' => [
'normalized' => [
'Role definition > Display name' => 'Security Reader',
'Role definition > Description' => 'Updated description',
'Role definition > Role source' => 'Custom',
],
'is_built_in' => false,
'role_permission_count' => 1,
],
],
'fidelity' => 'content',
'provenance' => [
'baseline_profile_id' => 1,
'baseline_snapshot_id' => 1,
'compare_operation_run_id' => 1,
'inventory_sync_run_id' => 1,
],
],
]);
$this->actingAs($user)
->get(FindingResource::getUrl('view', ['record' => $finding], tenant: $tenant))
->assertOk()
->assertSee('Intune RBAC Role Definition drift')
->assertSee('Metadata-only change')
->assertSee('Changed fields')
->assertSee('Role definition > Description')
->assertSee('Baseline description')
->assertSee('Updated description')
->assertSee('Role Assignments are not included')
->assertSee('RBAC restore is not supported');
});
it('shows RBAC labels and display-name fallback in the recent drift findings widget', function (): void {
[$user, $tenant] = createUserWithTenant(role: 'owner');
$this->actingAs($user);
$tenant->makeCurrent();
Filament::setCurrentPanel(Filament::getPanel('tenant'));
Filament::setTenant($tenant, true);
$subjectExternalId = 'rbac-role-1';
InventoryItem::factory()->create([
'tenant_id' => (int) $tenant->getKey(),
'workspace_id' => (int) $tenant->workspace_id,
'external_id' => $subjectExternalId,
'policy_type' => 'intuneRoleDefinition',
'display_name' => 'Security Reader',
'meta_jsonb' => ['etag' => 'E1'],
'last_seen_at' => now(),
]);
$finding = Finding::factory()->create([
'tenant_id' => (int) $tenant->getKey(),
'finding_type' => Finding::FINDING_TYPE_DRIFT,
'source' => 'baseline.compare',
'subject_type' => 'policy',
'subject_external_id' => (string) $subjectExternalId,
'severity' => Finding::SEVERITY_HIGH,
'status' => Finding::STATUS_NEW,
'evidence_jsonb' => [
'change_type' => 'missing_policy',
'policy_type' => 'intuneRoleDefinition',
'subject_key' => hash('sha256', 'intuneRoleDefinition|rbac-role-1'),
'display_name' => 'Security Reader',
'summary' => [
'kind' => 'rbac_role_definition',
],
'baseline' => ['policy_version_id' => 10],
'current' => ['policy_version_id' => null],
'rbac_role_definition' => [
'diff_kind' => 'missing',
],
'fidelity' => 'mixed',
'provenance' => [
'baseline_profile_id' => 1,
'baseline_snapshot_id' => 1,
'compare_operation_run_id' => 1,
'inventory_sync_run_id' => null,
],
],
]);
Livewire::actingAs($user)->test(RecentDriftFindings::class)
->assertCanSeeTableRecords([$finding])
->assertSee('Security Reader')
->assertSee('Intune RBAC Role Definition drift');
});