From 609bf3284386bc9947026eb9668751eaa0bcbd0d Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Wed, 4 Oct 2017 23:42:04 -0500 Subject: [PATCH] Add test for service option exporter --- app/helpers.php | 28 +++++++ database/factories/ModelFactory.php | 1 + .../NestedObjectAssertionsTrait.php | 47 +++++++++++ .../ServiceOptionExporterServiceTest.php | 78 +++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 tests/Assertions/NestedObjectAssertionsTrait.php create mode 100644 tests/Unit/Services/Services/Sharing/ServiceOptionExporterServiceTest.php diff --git a/app/helpers.php b/app/helpers.php index 26dd1b8e0..0c9004695 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -43,3 +43,31 @@ if (! function_exists('is_digit')) { return is_bool($value) ? false : ctype_digit(strval($value)); } } + +if (! function_exists('object_get_strict')) { + /** + * Get an object using dot notation. An object key with a value of null is still considered valid + * and will not trigger the response of a default value (unlike object_get). + * + * @param object $object + * @param string $key + * @param null $default + * @return mixed + */ + function object_get_strict($object, $key, $default = null) + { + if (is_null($key) || trim($key) == '') { + return $object; + } + + foreach (explode('.', $key) as $segment) { + if (! is_object($object) || ! property_exists($object, $segment)) { + return value($default); + } + + $object = $object->{$segment}; + } + + return $object; + } +} diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index d61f46cc0..d8d14526b 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -107,6 +107,7 @@ $factory->define(Pterodactyl\Models\ServiceOption::class, function (Faker\Genera 'service_id' => $faker->unique()->randomNumber(), 'name' => $faker->name, 'description' => implode(' ', $faker->sentences(3)), + 'startup' => 'java -jar test.jar', 'tag' => 'test@testfactory.com:' . $faker->unique()->randomNumber(8), ]; }); diff --git a/tests/Assertions/NestedObjectAssertionsTrait.php b/tests/Assertions/NestedObjectAssertionsTrait.php new file mode 100644 index 000000000..b402696d8 --- /dev/null +++ b/tests/Assertions/NestedObjectAssertionsTrait.php @@ -0,0 +1,47 @@ +. + * + * This software is licensed under the terms of the MIT license. + * https://opensource.org/licenses/MIT + */ + +namespace Tests\Assertions; + +use PHPUnit\Framework\Assert; +use PHPUnit_Util_InvalidArgumentHelper; + +trait NestedObjectAssertionsTrait +{ + /** + * Assert that an object value matches an expected value. + * + * @param string $key + * @param mixed $expected + * @param object $object + */ + public function assertObjectNestedValueEquals(string $key, $expected, $object) + { + if (! is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(3, 'object'); + } + + Assert::assertEquals($expected, object_get_strict($object, $key, '__TEST_FAILURE'), 'Assert that an object value equals a provided value.'); + } + + /** + * Assert that an object contains a nested key. + * + * @param string $key + * @param object $object + */ + public function assertObjectHasNestedAttribute(string $key, $object) + { + if (! is_object($object)) { + throw PHPUnit_Util_InvalidArgumentHelper::factory(2, 'object'); + } + + Assert::assertNotEquals('__TEST_FAILURE', object_get_strict($object, $key, '__TEST_FAILURE'), 'Assert that an object contains a nested key.'); + } +} diff --git a/tests/Unit/Services/Services/Sharing/ServiceOptionExporterServiceTest.php b/tests/Unit/Services/Services/Sharing/ServiceOptionExporterServiceTest.php new file mode 100644 index 000000000..381e1c015 --- /dev/null +++ b/tests/Unit/Services/Services/Sharing/ServiceOptionExporterServiceTest.php @@ -0,0 +1,78 @@ +. + * + * This software is licensed under the terms of the MIT license. + * https://opensource.org/licenses/MIT + */ + +namespace Tests\Unit\Services\Services\Sharing; + +use Mockery as m; +use Carbon\Carbon; +use Tests\TestCase; +use Pterodactyl\Models\ServiceOption; +use Pterodactyl\Models\ServiceVariable; +use Tests\Assertions\NestedObjectAssertionsTrait; +use Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface; +use Pterodactyl\Services\Services\Sharing\ServiceOptionExporterService; + +class ServiceOptionExporterServiceTest extends TestCase +{ + use NestedObjectAssertionsTrait; + + /** + * @var \Carbon\Carbon + */ + protected $carbon; + + /** + * @var \Pterodactyl\Contracts\Repository\ServiceOptionRepositoryInterface|\Mockery\Mock + */ + protected $repository; + + /** + * @var \Pterodactyl\Services\Services\Sharing\ServiceOptionExporterService + */ + protected $service; + + /** + * Setup tests. + */ + public function setUp() + { + parent::setUp(); + + Carbon::setTestNow(Carbon::now()); + $this->carbon = new Carbon(); + $this->repository = m::mock(ServiceOptionRepositoryInterface::class); + + $this->service = new ServiceOptionExporterService($this->carbon, $this->repository); + } + + public function testJsonStructureIsExported() + { + $option = factory(ServiceOption::class)->make(); + $option->variables = collect([$variable = factory(ServiceVariable::class)->make()]); + + $this->repository->shouldReceive('getWithExportAttributes')->with($option->id)->once()->andReturn($option); + + $response = $this->service->handle($option->id); + $this->assertNotEmpty($response); + + $data = json_decode($response); + $this->assertEquals(JSON_ERROR_NONE, json_last_error()); + $this->assertObjectHasNestedAttribute('meta.version', $data); + $this->assertObjectNestedValueEquals('meta.version', 'PTDL_v1', $data); + $this->assertObjectHasNestedAttribute('exported_at', $data); + $this->assertObjectNestedValueEquals('exported_at', Carbon::now()->toIso8601String(), $data); + $this->assertObjectHasNestedAttribute('scripts.installation.script', $data); + $this->assertObjectHasNestedAttribute('scripts.installation.container', $data); + $this->assertObjectHasNestedAttribute('scripts.installation.entrypoint', $data); + $this->assertObjectHasAttribute('variables', $data); + $this->assertArrayHasKey('0', $data->variables); + $this->assertObjectHasAttribute('name', $data->variables[0]); + $this->assertObjectNestedValueEquals('name', $variable->name, $data->variables[0]); + } +}