create(array_merge([ 'managed_environment_id' => $tenant->id, 'name' => 'Spec 401 backup schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', 'time_of_day' => '01:00:00', 'days_of_week' => null, 'policy_types' => ['deviceConfiguration'], 'include_foundations' => true, 'retention_keep_last' => 30, ], $attributes)); } test('backup schedule high-impact row actions require confirmation before side effects', function () { Queue::fake([RunBackupScheduleJob::class]); [$user, $tenant] = createUserWithTenant(role: 'owner'); $activeSchedule = spec401BackupSchedule($tenant, ['name' => 'Spec 401 active schedule']); $archivedSchedule = spec401BackupSchedule($tenant, [ 'name' => 'Spec 401 archived schedule', 'is_enabled' => false, ]); $archivedSchedule->delete(); $this->actingAs($user); Filament::setTenant($tenant, true); $component = Livewire::test(ListBackupSchedules::class) ->assertTableActionExists('runNow', fn (Action $action): bool => $action->isConfirmationRequired(), $activeSchedule) ->mountTableAction('runNow', $activeSchedule); expect($component->instance()->getMountedAction()?->getName())->toBe('runNow') ->and($component->instance()->getMountedAction()?->isConfirmationRequired())->toBeTrue(); expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); $component->unmountTableAction(); $component ->assertTableActionExists('retry', fn (Action $action): bool => $action->isConfirmationRequired(), $activeSchedule) ->mountTableAction('retry', $activeSchedule); expect($component->instance()->getMountedAction()?->getName())->toBe('retry') ->and($component->instance()->getMountedAction()?->isConfirmationRequired())->toBeTrue(); expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); $component->unmountTableAction(); $trashedSchedule = BackupSchedule::withTrashed()->findOrFail($archivedSchedule->id); $component = Livewire::test(ListBackupSchedules::class) ->filterTable(TrashedFilter::class, false) ->assertTableActionExists('restore', fn (Action $action): bool => $action->isConfirmationRequired(), $trashedSchedule) ->mountTableAction('restore', $trashedSchedule); expect($component->instance()->getMountedAction()?->getName())->toBe('restore') ->and($component->instance()->getMountedAction()?->isConfirmationRequired())->toBeTrue(); expect(BackupSchedule::withTrashed()->findOrFail($archivedSchedule->id)->trashed())->toBeTrue(); $this->assertDatabaseMissing('audit_logs', [ 'managed_environment_id' => $tenant->id, 'action' => 'backup_schedule.restored', 'resource_type' => 'backup_schedule', 'resource_id' => (string) $archivedSchedule->id, ]); }); test('backup schedule high-impact bulk actions require confirmation before side effects', function () { Queue::fake([RunBackupScheduleJob::class]); [$user, $tenant] = createUserWithTenant(role: 'owner'); $scheduleA = spec401BackupSchedule($tenant, ['name' => 'Spec 401 bulk schedule A']); $scheduleB = spec401BackupSchedule($tenant, ['name' => 'Spec 401 bulk schedule B']); $this->actingAs($user); Filament::setTenant($tenant, true); $component = Livewire::test(ListBackupSchedules::class) ->assertTableBulkActionExists('bulk_run_now') ->mountTableBulkAction('bulk_run_now', collect([$scheduleA, $scheduleB])) ->assertTableBulkActionMounted('bulk_run_now'); expect($component->instance()->getMountedAction()?->isConfirmationRequired())->toBeTrue(); expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); $component->unmountAction(); $component = Livewire::test(ListBackupSchedules::class) ->assertTableBulkActionExists('bulk_retry') ->mountTableBulkAction('bulk_retry', collect([$scheduleA, $scheduleB])) ->assertTableBulkActionMounted('bulk_retry'); expect($component->instance()->getMountedAction()?->isConfirmationRequired())->toBeTrue(); expect(OperationRun::query()->where('managed_environment_id', $tenant->id)->count())->toBe(0); Queue::assertNothingPushed(); }); test('backup schedules keep global search disabled for this proof pack', function () { expect(BackupScheduleResource::canGloballySearch())->toBeFalse(); });