diff --git a/src/Api/Skill.php b/src/Api/Skill.php new file mode 100644 index 0000000..b952759 --- /dev/null +++ b/src/Api/Skill.php @@ -0,0 +1,71 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Request; +use SkillDisplay\PHPToolKit\Configuration\Settings; +use SkillDisplay\PHPToolKit\Entity\Skill as Entity; + +class Skill +{ + /** + * @var Settings + */ + protected $settings; + + /** + * @var Client + */ + protected $client; + + public function __construct( + Settings $settings, + Client $client + ) { + $this->settings = $settings; + $this->client = $client; + } + + public function getById(int $id): Entity + { + if ($id <= 0) { + throw new \Exception('ID of Skill has to be a positive integer.', 1600764849); + } + + $url = $this->settings->getAPIUrl() . '/api/v1/skill/' . $id; + $result = $this->client->send(new Request( + 'GET', + $url, + [ + 'Content-Type' => 'application/json', + 'x-api-key' => $this->settings->getApiKey() + ] + )); + + if ($result->getStatusCode() !== 200) { + throw new \Exception('Did not get proper response for skill.', 1600694312); + } + + return Entity::createFromJson((string) $result->getBody()); + } +} diff --git a/src/Api/SkillSet.php b/src/Api/SkillSet.php new file mode 100644 index 0000000..dfded92 --- /dev/null +++ b/src/Api/SkillSet.php @@ -0,0 +1,71 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Request; +use SkillDisplay\PHPToolKit\Configuration\Settings; +use SkillDisplay\PHPToolKit\Entity\SkillSet as Entity; + +class SkillSet +{ + /** + * @var Settings + */ + protected $settings; + + /** + * @var Client + */ + protected $client; + + public function __construct( + Settings $settings, + Client $client + ) { + $this->settings = $settings; + $this->client = $client; + } + + public function getById(int $id): Entity + { + if ($id <= 0) { + throw new \Exception('ID of SkillSet has to be a positive integer.', 1600764811); + } + + $url = $this->settings->getAPIUrl() . '/api/v1/skillset/' . $id; + $result = $this->client->send(new Request( + 'GET', + $url, + [ + 'Content-Type' => 'application/json', + 'x-api-key' => $this->settings->getApiKey() + ] + )); + + if ($result->getStatusCode() !== 200) { + throw new \Exception('Did not get proper response for skill.', 1600694312); + } + + return Entity::createFromJson((string) $result->getBody()); + } +} diff --git a/src/Entity/Skill.php b/src/Entity/Skill.php new file mode 100644 index 0000000..145e70d --- /dev/null +++ b/src/Entity/Skill.php @@ -0,0 +1,65 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class Skill +{ + /** + * @var array + */ + private $data; + + private function __construct(array $data) + { + $this->data = $data; + } + + public function getId(): int + { + return $this->data['uid']; + } + + public function getTitle(): string + { + return $this->data['title'] ?? ''; + } + + public function getDescription(): string + { + return $this->data['description'] ?? ''; + } + + public function getGoals(): string + { + return $this->data['goals'] ?? ''; + } + + public function toArray(): array + { + return $this->data; + } + + public static function createFromJson(string $json): Skill + { + return new Skill(json_decode($json, true)); + } +} diff --git a/src/Entity/SkillSet.php b/src/Entity/SkillSet.php new file mode 100644 index 0000000..35bfc69 --- /dev/null +++ b/src/Entity/SkillSet.php @@ -0,0 +1,78 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +class SkillSet +{ + /** + * @var array + */ + private $data; + + private function __construct(array $data) + { + $this->data = $data; + } + + public function getId(): int + { + return $this->data['uid']; + } + + public function getName(): string + { + return $this->data['name'] ?? ''; + } + + public function getDescription(): string + { + return $this->data['description'] ?? ''; + } + + /** + * @return Skill[] + */ + public function getSkills(): array + { + static $skills = []; + + if ($skills !== []) { + return $skills; + } + + foreach ($this->data['skills'] as $skill) { + $skills[] = Skill::createFromJson(json_encode($skill)); + } + + return $skills; + } + + public function toArray(): array + { + return $this->data; + } + + public static function createFromJson(string $json): SkillSet + { + return new SkillSet(json_decode($json, true)); + } +} diff --git a/tests/Unit/Api/SkillSetTest.php b/tests/Unit/Api/SkillSetTest.php new file mode 100644 index 0000000..c04259e --- /dev/null +++ b/tests/Unit/Api/SkillSetTest.php @@ -0,0 +1,146 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; +use SkillDisplay\PHPToolKit\Api\SkillSet; +use PHPUnit\Framework\TestCase; +use SkillDisplay\PHPToolKit\Configuration\Settings; +use SkillDisplay\PHPToolKit\Entity\SkillSet as Entity; + +/** + * @covers SkillDisplay\PHPToolKit\Api\SkillSet + */ +class SkillSetTest extends TestCase +{ + use ProphecyTrait; + + /** + * @test + */ + public function instanceCanBeCreated() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + + $subject = new SkillSet( + $settings->reveal(), + $client->reveal() + ); + + static::assertInstanceOf(SkillSet::class, $subject); + } + + /** + * @test + */ + public function fetchedEntityFromApi() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + $response = $this->prophesize(Response::class); + + $settings->getAPIUrl()->willReturn('https://example.com'); + $settings->getApiKey()->willReturn('none'); + + $client->send(Argument::that(function (Request $request) { + return (string) $request->getUri() === 'https://example.com/api/v1/skillset/10' + && $request->getHeader('x-api-key') === ['none'] + && $request->getHeader('Content-Type') === ['application/json'] + && $request->getMethod() === 'GET' + ; + }))->willReturn($response->reveal()); + + $response->getStatusCode()->willReturn(200); + $response->getBody()->willReturn('{"uid":10}'); + + $subject = new SkillSet( + $settings->reveal(), + $client->reveal() + ); + $result = $subject->getById(10); + static::assertInstanceOf(Entity::class, $result); + } + + /** + * @test + */ + public function throwsExceptionIfStatusCodeIsNot200() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + $response = $this->prophesize(Response::class); + + $settings->getAPIUrl()->willReturn('https://example.com'); + $settings->getApiKey()->willReturn('none'); + + $client->send(Argument::any())->willReturn($response->reveal()); + + $response->getStatusCode()->willReturn(500); + + $subject = new SkillSet( + $settings->reveal(), + $client->reveal() + ); + + $this->expectExceptionMessage('Did not get proper response for skill.'); + $this->expectExceptionCode(1600694312); + + $result = $subject->getById(10); + } + + /** + * @test + * @dataProvider nonePositiveIds + */ + public function throwsExceptionIfSkillSetIdIsNotPositive(int $skillId) + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + + $subject = new SkillSet( + $settings->reveal(), + $client->reveal() + ); + + $this->expectExceptionMessage('ID of SkillSet has to be a positive integer.'); + $this->expectExceptionCode(1600764811); + + $subject->getById($skillId); + } + + public function nonePositiveIds(): array + { + return [ + 'zero' => [ + 'skillId' => 0, + ], + 'negative' => [ + 'skillId' => -1, + ], + ]; + } +} diff --git a/tests/Unit/Api/SkillTest.php b/tests/Unit/Api/SkillTest.php new file mode 100644 index 0000000..536a1cf --- /dev/null +++ b/tests/Unit/Api/SkillTest.php @@ -0,0 +1,146 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Request; +use GuzzleHttp\Psr7\Response; +use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; +use SkillDisplay\PHPToolKit\Api\Skill; +use PHPUnit\Framework\TestCase; +use SkillDisplay\PHPToolKit\Configuration\Settings; +use SkillDisplay\PHPToolKit\Entity\Skill as Entity; + +/** + * @covers SkillDisplay\PHPToolKit\Api\Skill + */ +class SkillTest extends TestCase +{ + use ProphecyTrait; + + /** + * @test + */ + public function instanceCanBeCreated() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + + $subject = new Skill( + $settings->reveal(), + $client->reveal() + ); + + static::assertInstanceOf(Skill::class, $subject); + } + + /** + * @test + */ + public function fetchedEntityFromApi() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + $response = $this->prophesize(Response::class); + + $settings->getAPIUrl()->willReturn('https://example.com'); + $settings->getApiKey()->willReturn('none'); + + $client->send(Argument::that(function (Request $request) { + return (string) $request->getUri() === 'https://example.com/api/v1/skill/10' + && $request->getHeader('x-api-key') === ['none'] + && $request->getHeader('Content-Type') === ['application/json'] + && $request->getMethod() === 'GET' + ; + }))->willReturn($response->reveal()); + + $response->getStatusCode()->willReturn(200); + $response->getBody()->willReturn('{"uid":10}'); + + $subject = new Skill( + $settings->reveal(), + $client->reveal() + ); + $result = $subject->getById(10); + static::assertInstanceOf(Entity::class, $result); + } + + /** + * @test + */ + public function throwsExceptionIfStatusCodeIsNot200() + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + $response = $this->prophesize(Response::class); + + $settings->getAPIUrl()->willReturn('https://example.com'); + $settings->getApiKey()->willReturn('none'); + + $client->send(Argument::any())->willReturn($response->reveal()); + + $response->getStatusCode()->willReturn(500); + + $subject = new Skill( + $settings->reveal(), + $client->reveal() + ); + + $this->expectExceptionMessage('Did not get proper response for skill.'); + $this->expectExceptionCode(1600694312); + + $result = $subject->getById(10); + } + + /** + * @test + * @dataProvider nonePositiveIds + */ + public function throwsExceptionIfSkillIdIsNotPositive(int $skillId) + { + $settings = $this->prophesize(Settings::class); + $client = $this->prophesize(Client::class); + + $subject = new Skill( + $settings->reveal(), + $client->reveal() + ); + + $this->expectExceptionMessage('ID of Skill has to be a positive integer.'); + $this->expectExceptionCode(1600764849); + + $subject->getById($skillId); + } + + public function nonePositiveIds(): array + { + return [ + 'zero' => [ + 'skillId' => 0, + ], + 'negative' => [ + 'skillId' => -1, + ], + ]; + } +} diff --git a/tests/Unit/Entity/SkillSetTest.php b/tests/Unit/Entity/SkillSetTest.php new file mode 100644 index 0000000..b3af901 --- /dev/null +++ b/tests/Unit/Entity/SkillSetTest.php @@ -0,0 +1,113 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use PHPUnit\Framework\TestCase; +use SkillDisplay\PHPToolKit\Entity\SkillSet; + +/** + * @covers SkillDisplay\PHPToolKit\Entity\SkillSet + */ +class SkillSetTest extends TestCase +{ + /** + * @test + */ + public function instanceCanNotBeCreatedViaConstructor() + { + $this->expectErrorMessage('Call to private SkillDisplay\PHPToolKit\Entity\SkillSet::__construct() from context \'SkillDisplay\PHPToolKit\Tests\Unit\Entity\SkillSetTest\''); + new SkillSet(); + } + + /** + * @test + */ + public function instanceCanBeCreatedFromJson() + { + $subject = SkillSet::createFromJson('{}'); + static::assertInstanceOf(SkillSet::class, $subject); + } + + /** + * @test + */ + public function instanceReturnsId() + { + $subject = SkillSet::createFromJson('{"uid":90}'); + static::assertSame(90, $subject->getId()); + } + + /** + * @test + */ + public function instanceReturnsName() + { + $subject = SkillSet::createFromJson('{"name":"Example name"}'); + static::assertSame('Example name', $subject->getName()); + } + + /** + * @test + */ + public function instanceReturnsDescription() + { + $subject = SkillSet::createFromJson('{"description":"

Example description

"}'); + static::assertSame('

Example description

', $subject->getDescription()); + } + + /** + * @test + */ + public function instanceReturnsSkills() + { + $subject = SkillSet::createFromJson('{"skills":[{"uid":90,"title":"Example title 1"},{"goals":"

Example goals

","uid":91,"title":"Example title 2"}]}'); + $skills = $subject->getSkills(); + + static::assertCount(2, $skills); + static::assertSame(90, $skills[0]->getId()); + static::assertSame(91, $skills[1]->getId()); + } + + /** + * @test + */ + public function instanceReturnsSameSkillInstancesA2ndTime() + { + $subject = SkillSet::createFromJson('{"skills":[{"uid":90,"title":"Example title 1"},{"goals":"

Example goals

","uid":91,"title":"Example title 2"}]}'); + $skillsFirstCall = $subject->getSkills(); + $skillsSecondCall = $subject->getSkills(); + + static::assertSame($skillsFirstCall, $skillsSecondCall); + } + + /** + * @test + */ + public function canBeConvertedToArray() + { + $subject = SkillSet::createFromJson('{"uid":90,"name":"Example name"}'); + static::assertSame([ + 'uid' => 90, + 'name' => 'Example name', + ], $subject->toArray()); + } +} diff --git a/tests/Unit/Entity/SkillTest.php b/tests/Unit/Entity/SkillTest.php new file mode 100644 index 0000000..2964cb6 --- /dev/null +++ b/tests/Unit/Entity/SkillTest.php @@ -0,0 +1,98 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +use PHPUnit\Framework\TestCase; +use SkillDisplay\PHPToolKit\Entity\Skill; + +/** + * @covers SkillDisplay\PHPToolKit\Entity\Skill + */ +class SkillTest extends TestCase +{ + /** + * @test + */ + public function instanceCanNotBeCreatedViaConstructor() + { + $this->expectErrorMessage('Call to private SkillDisplay\PHPToolKit\Entity\Skill::__construct() from context \'SkillDisplay\PHPToolKit\Tests\Unit\Entity\SkillTest\''); + new Skill(); + } + + /** + * @test + */ + public function instanceCanBeCreatedFromJson() + { + $subject = Skill::createFromJson('{}'); + static::assertInstanceOf(Skill::class, $subject); + } + + /** + * @test + */ + public function instanceReturnsId() + { + $subject = Skill::createFromJson('{"uid":90}'); + static::assertSame(90, $subject->getId()); + } + + /** + * @test + */ + public function instanceReturnsTitle() + { + $subject = Skill::createFromJson('{"title":"Example title"}'); + static::assertSame('Example title', $subject->getTitle()); + } + + /** + * @test + */ + public function instanceReturnsDescription() + { + $subject = Skill::createFromJson('{"description":"

Example description

"}'); + static::assertSame('

Example description

', $subject->getDescription()); + } + + /** + * @test + */ + public function instanceReturnsGoals() + { + $subject = Skill::createFromJson('{"goals":"

Example goals

"}'); + static::assertSame('

Example goals

', $subject->getGoals()); + } + + /** + * @test + */ + public function canBeConvertedToArray() + { + $subject = Skill::createFromJson('{"goals":"

Example goals

","uid":90,"title":"Example title"}'); + static::assertSame([ + 'goals' => '

Example goals

', + 'uid' => 90, + 'title' => 'Example title', + ], $subject->toArray()); + } +}