tenant = Tenant::create([ 'tenant_id' => 'tenant-123', 'name' => 'Test Tenant', ]); $this->tenant->makeCurrent(); $this->user = User::factory()->create(); $this->actingAs($this->user); $this->policy = Policy::create([ 'tenant_id' => $this->tenant->id, 'external_id' => 'policy-456', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Test Policy', 'platform' => 'windows', ]); $this->backupSet = BackupSet::create([ 'tenant_id' => $this->tenant->id, 'name' => 'Test Backup Set', 'status' => 'completed', 'created_by' => $this->user->email, ]); }); it('excludes soft-deleted items when listing available policies to add', function () { // Create a backup item $backupItem = BackupItem::create([ 'tenant_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, 'policy_type' => $this->policy->policy_type, 'platform' => $this->policy->platform, 'payload' => ['test' => 'data'], 'captured_at' => now(), ]); // Get available policies (should be empty since policy is already in backup) $existingPolicyIds = $this->backupSet->items()->pluck('policy_id')->filter()->all(); expect($existingPolicyIds)->toContain($this->policy->id); // Soft-delete the backup item $backupItem->delete(); // Verify it's soft-deleted expect($this->backupSet->items()->count())->toBe(0); expect($this->backupSet->items()->withTrashed()->count())->toBe(1); // Get available policies again - soft-deleted items should NOT be in the list (UI can re-add them) $existingPolicyIds = $this->backupSet->items()->pluck('policy_id')->filter()->all(); expect($existingPolicyIds)->not->toContain($this->policy->id) ->and($existingPolicyIds)->toHaveCount(0); }); it('prevents re-adding soft-deleted policies via BackupService', function () { // Create initial backup item $backupItem = BackupItem::create([ 'tenant_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, 'policy_type' => $this->policy->policy_type, 'platform' => $this->policy->platform, 'payload' => ['test' => 'data'], 'captured_at' => now(), ]); // Soft-delete it $backupItem->delete(); // Try to add the same policy again via BackupService $service = app(BackupService::class); $result = $service->addPoliciesToSet( tenant: $this->tenant, backupSet: $this->backupSet->refresh(), policyIds: [$this->policy->id], actorEmail: $this->user->email, actorName: $this->user->name, ); // Should restore the soft-deleted item, not create a new one expect($this->backupSet->items()->count())->toBe(1) ->and($this->backupSet->items()->withTrashed()->count())->toBe(1) ->and($result->item_count)->toBe(1) ->and($backupItem->fresh()->deleted_at)->toBeNull(); // Item should be restored }); it('allows adding different policy after one was soft-deleted', function () { // Create initial backup item $backupItem = BackupItem::create([ 'tenant_id' => $this->tenant->id, 'backup_set_id' => $this->backupSet->id, 'policy_id' => $this->policy->id, 'policy_identifier' => $this->policy->external_id, 'policy_type' => $this->policy->policy_type, 'platform' => $this->policy->platform, 'payload' => ['test' => 'data'], 'captured_at' => now(), ]); // Soft-delete it $backupItem->delete(); // Create a different policy $otherPolicy = Policy::create([ 'tenant_id' => $this->tenant->id, 'external_id' => 'policy-789', 'policy_type' => 'settingsCatalogPolicy', 'display_name' => 'Other Policy', 'platform' => 'windows', ]); // Check available policies - should include the new one but not the deleted one $existingPolicyIds = $this->backupSet->items()->withTrashed()->pluck('policy_id')->filter()->all(); expect($existingPolicyIds)->toContain($this->policy->id) ->and($existingPolicyIds)->not->toContain($otherPolicy->id); });