TenantAtlas/tests/Feature/BackupItemReaddTest.php
ahmido f4cf1dce6e feat/004-assignments-scope-tags (#4)
## Summary
<!-- Kurz: Was ändert sich und warum? -->

## Spec-Driven Development (SDD)
- [ ] Es gibt eine Spec unter `specs/<NNN>-<feature>/`
- [ ] Enthaltene Dateien: `plan.md`, `tasks.md`, `spec.md`
- [ ] Spec beschreibt Verhalten/Acceptance Criteria (nicht nur Implementation)
- [ ] Wenn sich Anforderungen während der Umsetzung geändert haben: Spec/Plan/Tasks wurden aktualisiert

## Implementation
- [ ] Implementierung entspricht der Spec
- [ ] Edge cases / Fehlerfälle berücksichtigt
- [ ] Keine unbeabsichtigten Änderungen außerhalb des Scopes

## Tests
- [ ] Tests ergänzt/aktualisiert (Pest/PHPUnit)
- [ ] Relevante Tests lokal ausgeführt (`./vendor/bin/sail artisan test` oder `php artisan test`)

## Migration / Config / Ops (falls relevant)
- [ ] Migration(en) enthalten und getestet
- [ ] Rollback bedacht (rückwärts kompatibel, sichere Migration)
- [ ] Neue Env Vars dokumentiert (`.env.example` / Doku)
- [ ] Queue/cron/storage Auswirkungen geprüft

## UI (Filament/Livewire) (falls relevant)
- [ ] UI-Flows geprüft
- [ ] Screenshots/Notizen hinzugefügt

## Notes
<!-- Links, Screenshots, Follow-ups, offene Punkte -->

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #4
2025-12-23 21:49:58 +00:00

136 lines
4.6 KiB
PHP

<?php
use App\Models\BackupItem;
use App\Models\BackupSet;
use App\Models\Policy;
use App\Models\Tenant;
use App\Models\User;
use App\Services\Intune\BackupService;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
beforeEach(function () {
$this->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);
});