Add first API implementation

Allow to retrieve skill and skill set by ID.
Returns PHP classes with proper getter for most important info.
All info are available via PHP array from those classes.
This commit is contained in:
Daniel Siepmann 2020-09-21 15:48:04 +02:00
parent 691adc00a6
commit c234d3e757
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
8 changed files with 788 additions and 0 deletions

71
src/Api/Skill.php Normal file
View file

@ -0,0 +1,71 @@
<?php
namespace SkillDisplay\PHPToolKit\Api;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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());
}
}

71
src/Api/SkillSet.php Normal file
View file

@ -0,0 +1,71 @@
<?php
namespace SkillDisplay\PHPToolKit\Api;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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());
}
}

65
src/Entity/Skill.php Normal file
View file

@ -0,0 +1,65 @@
<?php
namespace SkillDisplay\PHPToolKit\Entity;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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));
}
}

78
src/Entity/SkillSet.php Normal file
View file

@ -0,0 +1,78 @@
<?php
namespace SkillDisplay\PHPToolKit\Entity;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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));
}
}

View file

@ -0,0 +1,146 @@
<?php
namespace SkillDisplay\PHPToolKit\Tests\Unit\Api;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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,
],
];
}
}

View file

@ -0,0 +1,146 @@
<?php
namespace SkillDisplay\PHPToolKit\Tests\Unit\Api;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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,
],
];
}
}

View file

@ -0,0 +1,113 @@
<?php
namespace SkillDisplay\PHPToolKit\Tests\Unit\Entity;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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":"<p>Example description</p>"}');
static::assertSame('<p>Example description</p>', $subject->getDescription());
}
/**
* @test
*/
public function instanceReturnsSkills()
{
$subject = SkillSet::createFromJson('{"skills":[{"uid":90,"title":"Example title 1"},{"goals":"<p>Example goals</p>","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":"<p>Example goals</p>","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());
}
}

View file

@ -0,0 +1,98 @@
<?php
namespace SkillDisplay\PHPToolKit\Tests\Unit\Entity;
/*
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
*
* 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":"<p>Example description</p>"}');
static::assertSame('<p>Example description</p>', $subject->getDescription());
}
/**
* @test
*/
public function instanceReturnsGoals()
{
$subject = Skill::createFromJson('{"goals":"<p>Example goals</p>"}');
static::assertSame('<p>Example goals</p>', $subject->getGoals());
}
/**
* @test
*/
public function canBeConvertedToArray()
{
$subject = Skill::createFromJson('{"goals":"<p>Example goals</p>","uid":90,"title":"Example title"}');
static::assertSame([
'goals' => '<p>Example goals</p>',
'uid' => 90,
'title' => 'Example title',
], $subject->toArray());
}
}