From 5f48712c28ebd2d3726d1235b33d336fd2c0cf3a Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sat, 1 May 2021 12:24:42 -0700 Subject: [PATCH] Add test coverage for RunTaskJob --- app/Jobs/Schedule/RunTaskJob.php | 2 +- .../Jobs/Schedule/RunTaskJobTest.php | 157 ++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/Integration/Jobs/Schedule/RunTaskJobTest.php diff --git a/app/Jobs/Schedule/RunTaskJob.php b/app/Jobs/Schedule/RunTaskJob.php index ddedb026..0cffe4e8 100644 --- a/app/Jobs/Schedule/RunTaskJob.php +++ b/app/Jobs/Schedule/RunTaskJob.php @@ -74,7 +74,7 @@ class RunTaskJob extends Job implements ShouldQueue $backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true); break; default: - throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.'); + throw new InvalidArgumentException('Invalid task action provided: ' . $this->task->action); } } catch (Exception $exception) { // If this isn't a DaemonConnectionException on a task that allows for failures diff --git a/tests/Integration/Jobs/Schedule/RunTaskJobTest.php b/tests/Integration/Jobs/Schedule/RunTaskJobTest.php new file mode 100644 index 00000000..bd943cbc --- /dev/null +++ b/tests/Integration/Jobs/Schedule/RunTaskJobTest.php @@ -0,0 +1,157 @@ +createServerModel(); + + /** @var \Pterodactyl\Models\Schedule $schedule */ + $schedule = Schedule::factory()->create([ + 'server_id' => $server->id, + 'is_processing' => true, + 'last_run_at' => null, + 'is_active' => false, + ]); + /** @var \Pterodactyl\Models\Task $task */ + $task = Task::factory()->create(['schedule_id' => $schedule->id, 'is_queued' => true]); + + $job = new RunTaskJob($task); + + Bus::dispatchNow($job); + + $task->refresh(); + $schedule->refresh(); + + $this->assertFalse($task->is_queued); + $this->assertFalse($schedule->is_processing); + $this->assertFalse($schedule->is_active); + $this->assertTrue(CarbonImmutable::now()->isSameAs(CarbonImmutable::ISO8601, $schedule->last_run_at)); + } + + public function testJobWithInvalidActionThrowsException() + { + $server = $this->createServerModel(); + + /** @var \Pterodactyl\Models\Schedule $schedule */ + $schedule = Schedule::factory()->create(['server_id' => $server->id]); + /** @var \Pterodactyl\Models\Task $task */ + $task = Task::factory()->create(['schedule_id' => $schedule->id, 'action' => 'foobar']); + + $job = new RunTaskJob($task); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('Invalid task action provided: foobar'); + Bus::dispatchNow($job); + } + + /** + * @dataProvider isManualRunDataProvider + */ + public function testJobIsExecuted(bool $isManualRun) + { + $server = $this->createServerModel(); + + /** @var \Pterodactyl\Models\Schedule $schedule */ + $schedule = Schedule::factory()->create([ + 'server_id' => $server->id, + 'is_active' => !$isManualRun, + 'is_processing' => true, + 'last_run_at' => null, + ]); + /** @var \Pterodactyl\Models\Task $task */ + $task = Task::factory()->create([ + 'schedule_id' => $schedule->id, + 'action' => Task::ACTION_POWER, + 'payload' => 'start', + 'is_queued' => true, + 'continue_on_failure' => false, + ]); + + $mock = Mockery::mock(DaemonPowerRepository::class); + $this->instance(DaemonPowerRepository::class, $mock); + + $mock->expects('setServer')->with(Mockery::on(function ($value) use ($server) { + return $value instanceof Server && $value->id === $server->id; + }))->andReturnSelf(); + $mock->expects('send')->with('start')->andReturn(new Response()); + + Bus::dispatchNow(new RunTaskJob($task, $isManualRun)); + + $task->refresh(); + $schedule->refresh(); + + $this->assertFalse($task->is_queued); + $this->assertFalse($schedule->is_processing); + $this->assertTrue(CarbonImmutable::now()->isSameAs(CarbonImmutable::ISO8601, $schedule->last_run_at)); + } + + /** + * @dataProvider isManualRunDataProvider + */ + public function testExceptionDuringRunIsHandledCorrectly(bool $continueOnFailure) + { + $server = $this->createServerModel(); + + /** @var \Pterodactyl\Models\Schedule $schedule */ + $schedule = Schedule::factory()->create(['server_id' => $server->id]); + /** @var \Pterodactyl\Models\Task $task */ + $task = Task::factory()->create([ + 'schedule_id' => $schedule->id, + 'action' => Task::ACTION_POWER, + 'payload' => 'start', + 'continue_on_failure' => $continueOnFailure, + ]); + + $mock = Mockery::mock(DaemonPowerRepository::class); + $this->instance(DaemonPowerRepository::class, $mock); + + $mock->expects('setServer->send')->andThrow( + new DaemonConnectionException(new BadResponseException('Bad request', new Request('GET', '/test'), new Response())) + ); + + if (!$continueOnFailure) { + $this->expectException(DaemonConnectionException::class); + } + + Bus::dispatchNow(new RunTaskJob($task)); + + if ($continueOnFailure) { + $task->refresh(); + $schedule->refresh(); + + $this->assertFalse($task->is_queued); + $this->assertFalse($schedule->is_processing); + $this->assertTrue(CarbonImmutable::now()->isSameAs(CarbonImmutable::ISO8601, $schedule->last_run_at)); + } + } + + /** + * @return array + */ + public function isManualRunDataProvider() + { + return [[true], [false]]; + } +}