diff --git a/app/Livewire/BackupTasks/UpdateBackupTaskForm.php b/app/Livewire/BackupTasks/UpdateBackupTaskForm.php index cb1be4ba..361124ce 100644 --- a/app/Livewire/BackupTasks/UpdateBackupTaskForm.php +++ b/app/Livewire/BackupTasks/UpdateBackupTaskForm.php @@ -173,7 +173,7 @@ public function submit(): RedirectResponse|Redirector 'remoteServerId' => ['required', 'string', 'exists:remote_servers,id'], 'backupDestinationId' => ['required', 'string', 'exists:backup_destinations,id'], 'frequency' => ['required', 'string', 'in:daily,weekly'], - 'timeToRun' => ['string', 'regex:/^([01]?\d|2[0-3]):([0-5]?\d)$/', 'required_unless:useCustomCron,true', new UniqueScheduledTimePerRemoteServer((int) $this->remoteServerId)], + 'timeToRun' => ['string', 'regex:/^([01]?\d|2[0-3]):([0-5]?\d)$/', 'required_unless:useCustomCron,true', new UniqueScheduledTimePerRemoteServer((int) $this->remoteServerId, $this->backupTask->id)], 'cronExpression' => ['nullable', 'string', 'regex:/^(\*|([0-5]?\d)) (\*|([01]?\d|2[0-3])) (\*|([0-2]?\d|3[01])) (\*|([1-9]|1[0-2])) (\*|([0-7]))$/', 'required_if:useCustomCron,true'], 'sourcePath' => ['required', 'string', 'regex:/^(\/[^\/\0]+)+\/?$/'], ], $messages); @@ -194,7 +194,7 @@ public function submit(): RedirectResponse|Redirector 'remoteServerId' => ['required', 'string', 'exists:remote_servers,id'], 'backupDestinationId' => ['required', 'string', 'exists:backup_destinations,id'], 'frequency' => ['required', 'string', 'in:daily,weekly'], - 'timeToRun' => ['string', 'regex:/^([01]?\d|2[0-3]):([0-5]?\d)$/', 'required_unless:useCustomCron,true', new UniqueScheduledTimePerRemoteServer($this->remoteServerId)], + 'timeToRun' => ['string', 'regex:/^([01]?\d|2[0-3]):([0-5]?\d)$/', 'required_unless:useCustomCron,true', new UniqueScheduledTimePerRemoteServer((int) $this->remoteServerId, $this->backupTask->id)], 'cronExpression' => ['nullable', 'string', 'regex:/^(\*|([0-5]?\d)) (\*|([01]?\d|2[0-3])) (\*|([0-2]?\d|3[01])) (\*|([1-9]|1[0-2])) (\*|([0-7]))$/', 'required_if:useCustomCron,true'], ], $messages); diff --git a/app/Rules/UniqueScheduledTimePerRemoteServer.php b/app/Rules/UniqueScheduledTimePerRemoteServer.php index d67b81bb..6d565584 100644 --- a/app/Rules/UniqueScheduledTimePerRemoteServer.php +++ b/app/Rules/UniqueScheduledTimePerRemoteServer.php @@ -8,7 +8,7 @@ class UniqueScheduledTimePerRemoteServer implements ValidationRule { - public function __construct(public int $remoteServerId) + public function __construct(public int $remoteServerId, public ?int $taskId = null) { // } @@ -17,10 +17,13 @@ public function validate(string $attribute, mixed $value, Closure $fail): void { $query = Auth::user()?->backupTasks() ->where('remote_server_id', $this->remoteServerId) - ->where('time_to_run_at', $value) - ->exists(); + ->where('time_to_run_at', $value); - if ($query) { + if ($this->taskId) { + $query->where('id', '!=', $this->taskId); + } + + if ($query->exists()) { $fail($this->message()); } } diff --git a/tests/Feature/BackupTasks/Livewire/UpdateBackupTaskFormTest.php b/tests/Feature/BackupTasks/Livewire/UpdateBackupTaskFormTest.php index d0bb321d..f0665ad7 100644 --- a/tests/Feature/BackupTasks/Livewire/UpdateBackupTaskFormTest.php +++ b/tests/Feature/BackupTasks/Livewire/UpdateBackupTaskFormTest.php @@ -264,3 +264,34 @@ function createUserWithBackupTaskAndDependencies(): array ->call('submit') ->assertHasErrors('timeToRun'); }); + +test('a task retains its set time without validation errors', function () { + + $user = User::factory()->create(); + + $remoteServer = RemoteServer::factory()->create([ + 'user_id' => $user->id, + ]); + + $backupTask = BackupTask::factory()->create([ + 'remote_server_id' => $remoteServer->id, + 'time_to_run_at' => '12:00', + 'user_id' => $user->id, + ]); + + $this->assertDatabaseHas('backup_tasks', [ + 'time_to_run_at' => '12:00', + ]); + + $this->actingAs($user); + + Livewire::test(UpdateBackupTaskForm::class, [ + 'backupTask' => $backupTask, + 'remoteServers' => RemoteServer::all(), + ]) + ->set('timeToRun', '12:00') + ->set('sourcePath', '/var/www/html') + ->set('description', '') + ->call('submit') + ->assertHasNoErrors(); +});