TenantAtlas/tests/Feature/PolicyVersionViewAssignmentsTest.php
Ahmed Darrazi c3bdcf4d2d feat(004): implement PolicyCaptureOrchestrator for assignment consistency
BREAKING CHANGE: Assignment capture flow completely refactored

Core Changes:
- Created PolicyCaptureOrchestrator service for centralized capture coordination
- Refactored BackupService to use orchestrator (version-first approach)
- Fixed domain model bug: PolicyVersion now stores assignments (source of truth)
- BackupItem references PolicyVersion and copies assignments for restore

Database:
- Added assignments, scope_tags, assignments_hash, scope_tags_hash to policy_versions
- Added policy_version_id foreign key to backup_items
- Migrations: 2025_12_22_171525, 2025_12_22_171545

Services:
- PolicyCaptureOrchestrator: Intelligent version reuse, idempotent backfilling
- VersionService: Enhanced to capture assignments during version creation
- BackupService: Uses orchestrator, version-first capture flow

UI:
- Moved assignments widget from Policy to PolicyVersion view
- Created PolicyVersionAssignmentsWidget Livewire component
- Updated BackupItemsRelationManager columns for new assignment fields

Tests:
- Deleted BackupWithAssignmentsTest (old behavior)
- Created BackupWithAssignmentsConsistencyTest (4 tests, all passing)
- Fixed AssignmentFetcherTest and GroupResolverTest for GraphResponse
- All 162 tests passing

Issue: Assignments/scope tags not displaying in BackupSet items table (UI only)
Status: Database contains correct data, UI column definitions need adjustment
2025-12-22 20:19:10 +01:00

75 lines
2.1 KiB
PHP

<?php
use App\Models\Policy;
use App\Models\PolicyVersion;
use App\Models\Tenant;
use App\Models\User;
beforeEach(function () {
$this->tenant = Tenant::factory()->create();
$this->policy = Policy::factory()->create([
'tenant_id' => $this->tenant->id,
]);
$this->user = User::factory()->create();
});
it('displays policy version page', function () {
$version = PolicyVersion::factory()->create([
'tenant_id' => $this->tenant->id,
'policy_id' => $this->policy->id,
'version_number' => 1,
]);
$this->actingAs($this->user);
$response = $this->get("/admin/policy-versions/{$version->id}");
$response->assertOk();
});
it('displays assignments widget when version has assignments', function () {
$version = PolicyVersion::factory()->create([
'tenant_id' => $this->tenant->id,
'policy_id' => $this->policy->id,
'version_number' => 1,
'assignments' => [
[
'id' => 'assignment-1',
'intent' => 'apply',
'target' => [
'@odata.type' => '#microsoft.graph.groupAssignmentTarget',
'groupId' => 'group-123',
],
],
],
'scope_tags' => [
'ids' => ['0'],
'names' => ['Default'],
],
]);
$this->actingAs($this->user);
$response = $this->get("/admin/policy-versions/{$version->id}");
$response->assertOk();
$response->assertSeeLivewire('policy-version-assignments-widget');
$response->assertSee('1 assignment(s)');
});
it('displays empty state when version has no assignments', function () {
$version = PolicyVersion::factory()->create([
'tenant_id' => $this->tenant->id,
'policy_id' => $this->policy->id,
'version_number' => 1,
'assignments' => null,
]);
$this->actingAs($this->user);
$response = $this->get("/admin/policy-versions/{$version->id}");
$response->assertOk();
$response->assertSee('Assignments were not captured for this version');
});