'tenant-1', 'name' => 'Tenant', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Set 1', 'status' => 'completed', ]); BackupItem::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-1', 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'payload' => ['id' => 'policy-1'], ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListBackupSets::class) ->callTableAction('archive', $backupSet); $this->assertSoftDeleted('backup_sets', ['id' => $backupSet->id]); $this->assertSoftDeleted('backup_items', ['backup_set_id' => $backupSet->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'backup_set', 'resource_id' => (string) $backupSet->id, 'action' => 'backup.deleted', ]); }); test('backup set archive is blocked when restore runs exist', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-2', 'name' => 'Tenant 2', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Set with restore', 'status' => 'completed', ]); RestoreRun::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListBackupSets::class) ->callTableAction('archive', $backupSet); $this->assertDatabaseMissing('audit_logs', [ 'resource_type' => 'backup_set', 'resource_id' => (string) $backupSet->id, 'action' => 'backup.deleted', ]); $this->assertDatabaseHas('backup_sets', ['id' => $backupSet->id, 'deleted_at' => null]); }); test('backup set can be force deleted when trashed and unused', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-force', 'name' => 'Tenant Force', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Set force', 'status' => 'completed', ]); BackupItem::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'policy_id' => null, 'policy_identifier' => 'policy-force', 'policy_type' => 'deviceConfiguration', 'platform' => 'windows', 'payload' => ['id' => 'policy-force'], ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListBackupSets::class) ->callTableAction('archive', $backupSet) ->set('tableFilters.trashed.value', 1) ->callTableAction('forceDelete', $backupSet); $this->assertDatabaseMissing('backup_sets', ['id' => $backupSet->id]); $this->assertDatabaseMissing('backup_items', ['backup_set_id' => $backupSet->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'backup_set', 'resource_id' => (string) $backupSet->id, 'action' => 'backup.force_deleted', ]); }); test('restore run can be archived and force deleted', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-restore-run', 'name' => 'Tenant Restore Run', ]); $backupSet = BackupSet::create([ 'tenant_id' => $tenant->id, 'name' => 'Set RR', 'status' => 'completed', 'item_count' => 1, ]); $restoreRun = RestoreRun::create([ 'tenant_id' => $tenant->id, 'backup_set_id' => $backupSet->id, 'status' => 'completed', 'is_dry_run' => true, ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListRestoreRuns::class) ->callTableAction('archive', $restoreRun) ->set('tableFilters.trashed.value', 1) ->callTableAction('forceDelete', $restoreRun); $this->assertDatabaseMissing('restore_runs', ['id' => $restoreRun->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'restore_run', 'resource_id' => (string) $restoreRun->id, 'action' => 'restore_run.force_deleted', ]); }); test('policy version can be archived with audit log', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-3', 'name' => 'Tenant 3', ]); $policy = Policy::create([ 'tenant_id' => $tenant->id, 'external_id' => 'pol-1', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy', ]); $version = PolicyVersion::create([ 'tenant_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'deviceConfiguration', 'snapshot' => ['id' => 'pol-1'], ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListPolicyVersions::class) ->callTableAction('archive', $version); $this->assertSoftDeleted('policy_versions', ['id' => $version->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'policy_version', 'resource_id' => (string) $version->id, 'action' => 'policy_version.deleted', ]); }); test('policy version can be force deleted when trashed', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-3b', 'name' => 'Tenant 3b', ]); $policy = Policy::create([ 'tenant_id' => $tenant->id, 'external_id' => 'pol-1b', 'policy_type' => 'deviceConfiguration', 'display_name' => 'Policy B', ]); $version = PolicyVersion::create([ 'tenant_id' => $tenant->id, 'policy_id' => $policy->id, 'version_number' => 1, 'policy_type' => 'deviceConfiguration', 'snapshot' => ['id' => 'pol-1b'], ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListPolicyVersions::class) ->callTableAction('archive', $version) ->set('tableFilters.trashed.value', 1) ->callTableAction('forceDelete', $version); $this->assertDatabaseMissing('policy_versions', ['id' => $version->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'policy_version', 'resource_id' => (string) $version->id, 'action' => 'policy_version.force_deleted', ]); }); test('tenant can be archived and hidden from default lists', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-4', 'name' => 'Tenant 4', ]); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListTenants::class) ->callTableAction('archive', $tenant); expect(Tenant::count())->toBe(0); $this->assertSoftDeleted('tenants', ['id' => $tenant->id]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'tenant', 'resource_id' => (string) $tenant->id, 'action' => 'tenant.archived', ]); }); test('tenant must be trashed before force delete and removes permanently', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-5', 'name' => 'Tenant 5', ]); $tenant->delete(); $tenant->forceDelete(); $this->assertDatabaseMissing('tenants', ['id' => $tenant->id]); }); test('tenant table archive filter toggles active and archived tenants', function () { $active = Tenant::create([ 'tenant_id' => 'tenant-active', 'name' => 'Active Tenant', ]); $archived = Tenant::create([ 'tenant_id' => 'tenant-archived', 'name' => 'Archived Tenant', ]); $archived->delete(); $user = User::factory()->create(); $this->actingAs($user); $component = Livewire::test(ListTenants::class) ->assertSee($active->name) ->assertSee($archived->name); $component ->set('tableFilters.trashed.value', null) ->assertSee($active->name) ->assertDontSee($archived->name); $component ->set('tableFilters.trashed.value', 0) ->assertSee($archived->name) ->assertDontSee($active->name); }); test('archived tenant can be restored from the table', function () { $tenant = Tenant::create([ 'tenant_id' => 'tenant-restore', 'name' => 'Restore Tenant', ]); $tenant->delete(); $user = User::factory()->create(); $this->actingAs($user); Livewire::test(ListTenants::class) ->set('tableFilters.trashed.value', 1) ->callTableAction('restore', $tenant); $this->assertDatabaseHas('tenants', [ 'id' => $tenant->id, 'deleted_at' => null, 'status' => 'active', ]); $this->assertDatabaseHas('audit_logs', [ 'resource_type' => 'tenant', 'resource_id' => (string) $tenant->id, 'action' => 'tenant.restored', ]); });