From 1849b5903ec6e92b3f2b097a52be128aaa349d0e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 4 May 2026 12:26:15 +0200 Subject: [PATCH] refactor(scheduled-task): simplify server() with nullsafe operators and add return type Replace nested null checks with nullsafe operator chains, add ?Server return type, drop unreachable database branch, and cover all paths with feature tests. --- app/Models/ScheduledTask.php | 18 +++---- tests/Feature/ScheduledTaskServerTest.php | 66 +++++++++++++++++++++++ 2 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 tests/Feature/ScheduledTaskServerTest.php diff --git a/app/Models/ScheduledTask.php b/app/Models/ScheduledTask.php index 40f8e1860..0a53395d3 100644 --- a/app/Models/ScheduledTask.php +++ b/app/Models/ScheduledTask.php @@ -76,20 +76,14 @@ public function executions(): HasMany return $this->hasMany(ScheduledTaskExecution::class)->orderBy('created_at', 'desc'); } - public function server() + public function server(): ?Server { if ($this->application) { - if ($this->application->destination && $this->application->destination->server) { - return $this->application->destination->server; - } - } elseif ($this->service) { - if ($this->service->destination && $this->service->destination->server) { - return $this->service->destination->server; - } - } elseif ($this->database) { - if ($this->database->destination && $this->database->destination->server) { - return $this->database->destination->server; - } + return $this->application->destination?->server; + } + + if ($this->service) { + return $this->service->destination?->server; } return null; diff --git a/tests/Feature/ScheduledTaskServerTest.php b/tests/Feature/ScheduledTaskServerTest.php new file mode 100644 index 000000000..68a9020d0 --- /dev/null +++ b/tests/Feature/ScheduledTaskServerTest.php @@ -0,0 +1,66 @@ +team = Team::factory()->create(); + $this->server = Server::factory()->create(['team_id' => $this->team->id]); + $this->destination = StandaloneDocker::where('server_id', $this->server->id)->first(); + $this->project = Project::factory()->create(['team_id' => $this->team->id]); + $this->environment = $this->project->environments()->first(); +}); + +it('returns null when neither application nor service is set', function () { + $task = ScheduledTask::factory()->create([ + 'team_id' => $this->team->id, + ]); + + expect($task->server())->toBeNull(); +}); + +it('does not throw when accessing dynamic properties on a parentless task', function () { + $task = ScheduledTask::factory()->create([ + 'team_id' => $this->team->id, + ]); + + expect(fn () => $task->server())->not->toThrow(Exception::class); +}); + +it('resolves server via application destination', function () { + $application = Application::factory()->create([ + 'environment_id' => $this->environment->id, + 'destination_id' => $this->destination->id, + 'destination_type' => $this->destination->getMorphClass(), + ]); + + $task = ScheduledTask::factory()->create([ + 'application_id' => $application->id, + 'team_id' => $this->team->id, + ]); + + expect($task->server()?->id)->toBe($this->server->id); +}); + +it('resolves server via service destination', function () { + $service = Service::factory()->create([ + 'environment_id' => $this->environment->id, + 'destination_id' => $this->destination->id, + 'destination_type' => $this->destination->getMorphClass(), + ]); + + $task = ScheduledTask::factory()->create([ + 'service_id' => $service->id, + 'team_id' => $this->team->id, + ]); + + expect($task->server()?->id)->toBe($this->server->id); +});