- BackupWithAssignmentsTest: Added missing PolicySnapshotService mock for orphaned groups test
- BackupCreationTest: Added PolicySnapshotService mock with twice() expectation, added last_synced_at to test policies, fixed payload assertion (id instead of policyId)
- PolicyListingTest: Added last_synced_at to test policies
Root cause: Policies without last_synced_at within 7 days are filtered out by BackupItemsRelationManager (Feature 005 workaround for deleted policies)
All tests now passing: 155 passed ✅, 5 skipped
- Test resolves scope tag IDs to objects with id and displayName
- Test caching behavior (1 hour TTL)
- Test empty input handling
- Test 403 Forbidden error handling gracefully
- Test filtering to requested IDs preserving array keys
- Updated BackupWithAssignmentsTest ScopeTagResolver mocks to match actual method signature
- Fixed TenantSetupTest to expect 'granted' instead of 'ok' status
- Added ScopeTagResolver mock to BackupCreationTest
All Phase 3 (Scope Tags) functionality complete and tested.
Changes:
- Status labels: 'ok' → 'granted' (clearer meaning)
- Badge colors: granted=green, missing=orange, error=red
- Updated tests to match new status values
This makes the permission status more intuitive and visually
distinguishable on the Tenant detail page (/admin/tenants/1).
Fixes bug where removed backup items could not be re-added via UI.
🐛 Problem:
- When a BackupItem is soft-deleted (removed from BackupSet), it disappears from UI
- User tries to re-add the same policy → receives 'added successfully' notification
- Policy doesn't actually get added → BackupService filtered it out as already existing
- Confusing UX: notification says success but nothing changes
🔍 Root Cause:
BackupService checked for existence of policies including soft-deleted ones:
$existingPolicyIds = $backupSet->items()->withTrashed()->pluck('policy_id')
$policyIds = array_diff($policyIds, $existingPolicyIds) // ❌ Filters out soft-deleted
This prevented re-adding policies that were previously removed.
✅ Solution:
When a policy is re-added that already exists as soft-deleted:
1. Restore the soft-deleted BackupItem instead of ignoring it
2. Only create new items for truly new policies
3. Show restored policies in the UI dropdown (removed withTrashed() from RelationManager)
📝 Changes:
- BackupService::addPoliciesToSet():
* Separate soft-deleted items from new policies
* Restore soft-deleted items automatically
* Track restored_count in audit logs
- BackupItemsRelationManager: Removed withTrashed() so soft-deleted items appear in dropdown again
- BackupItemReaddTest: Updated to expect restore behavior instead of ignore
✅ Tests: 3 passed (11 assertions)
Impact:
- ✅ Removed policies can now be re-added via UI
- ✅ Restores existing backup data instead of creating duplicates
- ✅ Proper audit trail with restored_count