feat(service): add api service
This commit is contained in:
parent
e929853bb2
commit
e1375f1bf5
@ -4,7 +4,7 @@
|
||||
"minimum-stability": "stable",
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"php": ">=8.3",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"doctrine/dbal": "^3",
|
||||
|
10
config/services_test.yaml
Normal file
10
config/services_test.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
services:
|
||||
App\Service\Remote\BriloApiUsers:
|
||||
public: true
|
||||
autowire: true
|
||||
App\Service\Remote\BriloApiComments:
|
||||
public: true
|
||||
autowire: true
|
||||
App\Service\Remote\BriloApiPosts:
|
||||
public: true
|
||||
autowire: true
|
@ -18,8 +18,11 @@
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
<testsuite name="Project Test Suite">
|
||||
<directory>tests</directory>
|
||||
<testsuite name="unit">
|
||||
<directory>tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="integration">
|
||||
<directory>tests/Integration</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
|
@ -7,8 +7,8 @@ namespace App\Entity\Remote\Brilo\Users;
|
||||
readonly class AddressGeo
|
||||
{
|
||||
public function __construct(
|
||||
public float $lat,
|
||||
public float $lng,
|
||||
public string $lat,
|
||||
public string $lng,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
35
src/Service/Remote/BriloApiComments.php
Normal file
35
src/Service/Remote/BriloApiComments.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
use App\Entity\Remote\Brilo\Comments\Comment;
|
||||
use App\Entity\Remote\Brilo\Posts\Post;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class BriloApiComments
|
||||
{
|
||||
use BriloApiFetchTrait;
|
||||
|
||||
public function __construct(
|
||||
protected readonly HttpClientInterface $httpClient,
|
||||
protected readonly LoggerInterface $logger,
|
||||
protected readonly SerializerInterface $serializer,
|
||||
protected readonly int $retryCount = 3,
|
||||
protected readonly int $sleepTimeS = 1,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all comments from the Brilo API and return them as an array of Comment entities.
|
||||
* @return Comment[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getComments(): array
|
||||
{
|
||||
return $this->fetchApiResponse('https://jsonplaceholder.typicode.com/comments', Comment::class);
|
||||
}
|
||||
}
|
54
src/Service/Remote/BriloApiFetchTrait.php
Normal file
54
src/Service/Remote/BriloApiFetchTrait.php
Normal file
@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
use App\Entity\Remote\Brilo\Users\User;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\Exception\TransportException;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
trait BriloApiFetchTrait
|
||||
{
|
||||
use RetryingClientTrait;
|
||||
|
||||
protected readonly int $retryCount;
|
||||
protected readonly int $sleepTimeS;
|
||||
protected readonly LoggerInterface $logger;
|
||||
protected readonly HttpClientInterface $httpClient;
|
||||
protected readonly SerializerInterface $serializer;
|
||||
|
||||
/**
|
||||
* Implementation of fetch logic. Handles retrying and logging of failed requests.
|
||||
* Returns deserialized data.
|
||||
* @template T
|
||||
*
|
||||
* @param string $uri Uri of the API endpoint.
|
||||
* @param class-string<T> $class Class name of the entity to deserialize data into.
|
||||
*
|
||||
* @return T[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function fetchApiResponse(string $uri, string $class): array
|
||||
{
|
||||
return $this->retryingFailRequest($this->retryCount, $this->sleepTimeS, [TransportException::class, BriloRemoteApiException::class], $this->logger, function () use ($uri, $class) {
|
||||
$this->logger->debug('Trying to download brilo users');
|
||||
|
||||
$response = $this->httpClient->request('GET', $uri);
|
||||
|
||||
if ($response->getStatusCode() != 200) {
|
||||
$this->logger->error("Can't download brilo users. HTTP status code: " . $response->getStatusCode());
|
||||
throw new BriloRemoteApiException("Can't download brilo users. HTTP status code: " . $response->getStatusCode());
|
||||
}
|
||||
|
||||
$this->logger->debug('Brilo users downloaded');
|
||||
|
||||
$this->logger->debug('Deserialize brilo users');
|
||||
|
||||
// extra attributes muzeme safe ignorovat
|
||||
return $this->serializer->deserialize($response->getContent(), $class . '[]', 'json');
|
||||
});
|
||||
}
|
||||
}
|
10
src/Service/Remote/BriloApiPosts.php
Normal file
10
src/Service/Remote/BriloApiPosts.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
class BriloApiPosts
|
||||
{
|
||||
|
||||
}
|
35
src/Service/Remote/BriloApiUsers.php
Normal file
35
src/Service/Remote/BriloApiUsers.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
use App\Entity\Remote\Brilo\Users\User;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\HttpClient\Exception\TransportException;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
final class BriloApiUsers
|
||||
{
|
||||
use BriloApiFetchTrait;
|
||||
|
||||
public function __construct(
|
||||
protected readonly HttpClientInterface $httpClient,
|
||||
protected readonly LoggerInterface $logger,
|
||||
protected readonly SerializerInterface $serializer,
|
||||
protected readonly int $retryCount = 3,
|
||||
protected readonly int $sleepTimeS = 1,
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User[]
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getUsers(): array
|
||||
{
|
||||
return $this->fetchApiResponse('https://jsonplaceholder.typicode.com/users', User::class);
|
||||
}
|
||||
}
|
12
src/Service/Remote/BriloRemoteApiException.php
Normal file
12
src/Service/Remote/BriloRemoteApiException.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
/**
|
||||
* Remote API exception (in case return code from API endpoint is not 200 - OK)
|
||||
*/
|
||||
class BriloRemoteApiException extends \RuntimeException
|
||||
{
|
||||
}
|
58
src/Service/Remote/RetryingClientTrait.php
Normal file
58
src/Service/Remote/RetryingClientTrait.php
Normal file
@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Remote;
|
||||
|
||||
use Exception;
|
||||
use Psr\Log\LoggerInterface;
|
||||
|
||||
trait RetryingClientTrait
|
||||
{
|
||||
/**
|
||||
* Better to retry failed requests (in case of non-destructive operations) than throwing immediately.
|
||||
*
|
||||
* @param int $count
|
||||
* @param float $sleep
|
||||
* @param array<string> $catchableExceptions
|
||||
* @param LoggerInterface $logger
|
||||
* @param callable $callback
|
||||
* @return mixed
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function retryingFailRequest(
|
||||
int $count,
|
||||
float $sleep,
|
||||
array $catchableExceptions,
|
||||
LoggerInterface $logger,
|
||||
callable $callback
|
||||
): mixed {
|
||||
for ($i = 0;; $i++) {
|
||||
try {
|
||||
return $callback();
|
||||
} catch (Exception $e) {
|
||||
foreach ($catchableExceptions as $exceptionClass) {
|
||||
if ($e instanceof $exceptionClass) {
|
||||
$logger->error("transport: fail request retrying... got catchable exception", [
|
||||
'exception' => $e,
|
||||
'try' => $i
|
||||
]);
|
||||
|
||||
usleep((int) ($sleep * 1_000_000));
|
||||
|
||||
if ($i == $count) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
// phpstan fail
|
||||
return null;
|
||||
}
|
||||
}
|
21
tests/Common/LoggerTrait.php
Normal file
21
tests/Common/LoggerTrait.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Common;
|
||||
|
||||
use Monolog\Handler\TestHandler;
|
||||
use Monolog\Logger;
|
||||
|
||||
trait LoggerTrait
|
||||
{
|
||||
/**
|
||||
* @return Logger
|
||||
*/
|
||||
protected function getLogger(): Logger
|
||||
{
|
||||
$logger = new Logger('test');
|
||||
$logger->pushHandler(new TestHandler());
|
||||
return $logger;
|
||||
}
|
||||
}
|
28
tests/Integration/Service/Remote/BlogApiUsersTest.php
Normal file
28
tests/Integration/Service/Remote/BlogApiUsersTest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Integration\Service\Remote;
|
||||
|
||||
use App\Service\Remote\BriloApiUsers;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
class BlogApiUsersTest extends KernelTestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::bootKernel();
|
||||
}
|
||||
|
||||
public function testBlogApiUsersAreRetrieved(): void
|
||||
{
|
||||
/**
|
||||
* @var BriloApiUsers $apiUsers
|
||||
*/
|
||||
$apiUsers = static::getContainer()->get(BriloApiUsers::class);
|
||||
$users = $apiUsers->getUsers();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertGreaterThan(0, count($users));
|
||||
// Tady bych dal jeste check na zaznam ktery vim ze vzdy existuje
|
||||
}
|
||||
}
|
28
tests/Integration/Service/Remote/BriloApiCommentsTest.php
Normal file
28
tests/Integration/Service/Remote/BriloApiCommentsTest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Integration\Service\Remote;
|
||||
|
||||
use App\Service\Remote\BriloApiComments;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
class BriloApiCommentsTest extends KernelTestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::bootKernel();
|
||||
}
|
||||
|
||||
public function testBlogApiUsersAreRetrieved(): void
|
||||
{
|
||||
/**
|
||||
* @var BriloApiComments $api
|
||||
*/
|
||||
$api = static::getContainer()->get(BriloApiComments::class);
|
||||
$users = $api->getComments();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertGreaterThan(0, count($users));
|
||||
// Tady bych dal jeste check na zaznam ktery vim ze vzdy existuje
|
||||
}
|
||||
}
|
28
tests/Integration/Service/Remote/BriloApiPostsTest.php
Normal file
28
tests/Integration/Service/Remote/BriloApiPostsTest.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Integration\Service\Remote;
|
||||
|
||||
use App\Service\Remote\BriloApiPosts;
|
||||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
|
||||
|
||||
class BriloApiPostsTest extends KernelTestCase
|
||||
{
|
||||
public function setUp(): void
|
||||
{
|
||||
parent::bootKernel();
|
||||
}
|
||||
|
||||
public function testBlogApiUsersAreRetrieved(): void
|
||||
{
|
||||
/**
|
||||
* @var BriloApiPosts $api
|
||||
*/
|
||||
$api = static::getContainer()->get(BriloApiPosts::class);
|
||||
$users = $api->getPosts();
|
||||
$this->assertIsArray($users);
|
||||
$this->assertGreaterThan(0, count($users));
|
||||
// Tady bych dal jeste check na zaznam ktery vim ze vzdy existuje
|
||||
}
|
||||
}
|
10
tests/Unit/Service/Remote/BlogApiPostsTest.php
Normal file
10
tests/Unit/Service/Remote/BlogApiPostsTest.php
Normal file
@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service\Remote;
|
||||
|
||||
class BlogApiPostsTest
|
||||
{
|
||||
|
||||
}
|
98
tests/Unit/Service/Remote/BriloApiCommentsTest.php
Normal file
98
tests/Unit/Service/Remote/BriloApiCommentsTest.php
Normal file
@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service\Remote;
|
||||
|
||||
use App\Entity\Remote\Brilo\Comments\Comment;
|
||||
use App\Entity\Remote\Brilo\Posts\Post;
|
||||
use App\Service\Remote\BriloApiComments;
|
||||
use App\Service\Remote\BriloApiPosts;
|
||||
use App\Service\Remote\BriloRemoteApiException;
|
||||
use App\Tests\Common\LoggerTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\JsonMockResponse;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class BriloApiCommentsTest extends TestCase
|
||||
{
|
||||
use LoggerTrait;
|
||||
|
||||
private const array API_COMMENTS_LIST = [
|
||||
[
|
||||
"postId" => 1,
|
||||
"id" => 1,
|
||||
"name" => "id labore ex et quam laborum",
|
||||
"email" => "Eliseo@gardner.biz",
|
||||
"body" => "laudantium enim quasi est quidem magnam voluptate ipsam eos
|
||||
tempora quo necessitatibus
|
||||
dolor quam autem quasi
|
||||
reiciendis et nam sapiente accusantium"
|
||||
],
|
||||
[
|
||||
"postId" => 1,
|
||||
"id" => 2,
|
||||
"name" => "quo vero reiciendis velit similique earum",
|
||||
"email" => "Jayne_Kuhic@sydney.com",
|
||||
"body" => "est natus enim nihil est dolore omnis voluptatem numquam
|
||||
et omnis occaecati quod ullam at
|
||||
voluptatem error expedita pariatur
|
||||
nihil sint nostrum voluptatem reiciendis et"
|
||||
]
|
||||
];
|
||||
|
||||
public function testCommentsListSuccess(): void
|
||||
{
|
||||
$testCommentsList = $this->buildTestCommentsList();
|
||||
$serializer = $this->createMock(SerializerInterface::class);
|
||||
$serializer
|
||||
->expects($this->once())
|
||||
->method('deserialize')
|
||||
->with(
|
||||
json_encode(self::API_COMMENTS_LIST),
|
||||
Comment::class . '[]',
|
||||
'json'
|
||||
)->willReturn($testCommentsList);
|
||||
|
||||
$response = new JsonMockResponse(self::API_COMMENTS_LIST);
|
||||
$mockedClient = new MockHttpClient($response);
|
||||
$briloApiPosts = new BriloApiComments($mockedClient, $this->getLogger(), $serializer);
|
||||
$this->assertEquals($testCommentsList, $briloApiPosts->getComments());
|
||||
}
|
||||
|
||||
public function testInvalidHttpCodeReturned(): void
|
||||
{
|
||||
$serializer = $this->createMock(SerializerInterface::class);
|
||||
$serializer
|
||||
->expects($this->never())
|
||||
->method('deserialize');
|
||||
|
||||
$response = new JsonMockResponse(self::API_COMMENTS_LIST, [
|
||||
'http_code' => 401,
|
||||
]);
|
||||
$mockedClient = new MockHttpClient(function () use ($response) {
|
||||
return $response;
|
||||
});
|
||||
$this->expectException(BriloRemoteApiException::class);
|
||||
$briloApiPosts = new BriloApiComments($mockedClient, $this->getLogger(), $serializer);
|
||||
$briloApiPosts->getComments();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Comment[]
|
||||
*/
|
||||
public function buildTestCommentsList(): array
|
||||
{
|
||||
// Convert self::API_POSTS_LIST to Post[] and return it
|
||||
return array_map(function ($postData) {
|
||||
return new Comment(
|
||||
$postData['id'],
|
||||
$postData['postId'],
|
||||
$postData['name'],
|
||||
$postData['email'],
|
||||
$postData['body']
|
||||
);
|
||||
}, self::API_COMMENTS_LIST);
|
||||
}
|
||||
}
|
142
tests/Unit/Service/Remote/BriloApiUsersTest.php
Normal file
142
tests/Unit/Service/Remote/BriloApiUsersTest.php
Normal file
@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service\Remote;
|
||||
|
||||
use App\Entity\Remote\Brilo\Users\Address;
|
||||
use App\Entity\Remote\Brilo\Users\AddressGeo;
|
||||
use App\Entity\Remote\Brilo\Users\Company;
|
||||
use App\Entity\Remote\Brilo\Users\User;
|
||||
use App\Service\Remote\BriloApiUsers;
|
||||
use App\Service\Remote\BriloRemoteApiException;
|
||||
use App\Tests\Common\LoggerTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\JsonMockResponse;
|
||||
use Symfony\Component\Serializer\SerializerInterface;
|
||||
|
||||
class BriloApiUsersTest extends TestCase
|
||||
{
|
||||
use LoggerTrait;
|
||||
|
||||
private const array API_USER_LIST = [
|
||||
[
|
||||
"id" => 0,
|
||||
"name" => "Leanne Graham",
|
||||
"username" => "Bret",
|
||||
"email" => "Sincere@april.biz",
|
||||
"address" => [
|
||||
"street" => "Kulas Light",
|
||||
"suite" => "Apt. 555",
|
||||
"city" => "Gwenborough",
|
||||
"zipcode" => "92997-3874",
|
||||
"geo" => [
|
||||
"lat" => "-38.3159",
|
||||
"lng" => "80.1496"
|
||||
]
|
||||
],
|
||||
"phone" => "0-770-736-8031 x56442",
|
||||
"website" => "hildegard.org",
|
||||
"company" => [
|
||||
"name" => "Romaguera-Crona",
|
||||
"catchPhrase" => "Multi-layered client-server neural-net",
|
||||
"bs" => "harness real-time e-markets"
|
||||
],
|
||||
],
|
||||
[
|
||||
"id" => 1,
|
||||
"name" => "Ervin Howell",
|
||||
"username" => "Antonette",
|
||||
"email" => "Shanna@melissa.tv",
|
||||
"address" => [
|
||||
"street" => "Victor Plains",
|
||||
"suite" => "Suite 878",
|
||||
"city" => "Wisokyburgh",
|
||||
"zipcode" => "90565-7771",
|
||||
"geo" => [
|
||||
"lat" => "-44.9509",
|
||||
"lng" => "-35.4618"
|
||||
]
|
||||
],
|
||||
"phone" => "009-692-6593 x09125",
|
||||
"website" => "anastasia.net",
|
||||
"company" => [
|
||||
"name" => "Deckow-Crist",
|
||||
"catchPhrase" => "Proactive didactic contingency",
|
||||
"bs" => "synergize scalable supply-chains"
|
||||
],
|
||||
"nonExistentKey" => "value"
|
||||
]
|
||||
];
|
||||
|
||||
public function testUserListSuccess(): void
|
||||
{
|
||||
$testUserList = $this->buildTestUserList();
|
||||
$serializer = $this->createMock(SerializerInterface::class);
|
||||
$serializer
|
||||
->expects($this->once())
|
||||
->method('deserialize')
|
||||
->with(
|
||||
json_encode(self::API_USER_LIST),
|
||||
User::class . '[]',
|
||||
'json'
|
||||
)->willReturn($testUserList);
|
||||
|
||||
$response = new JsonMockResponse(self::API_USER_LIST);
|
||||
$mockedClient = new MockHttpClient($response);
|
||||
$briloApiUsers = new BriloApiUsers($mockedClient, $this->getLogger(), $serializer);
|
||||
$this->assertEquals($testUserList, $briloApiUsers->getUsers());
|
||||
}
|
||||
|
||||
public function testInvalidHttpCodeReturned(): void
|
||||
{
|
||||
$serializer = $this->createMock(SerializerInterface::class);
|
||||
$serializer
|
||||
->expects($this->never())
|
||||
->method('deserialize');
|
||||
|
||||
$response = new JsonMockResponse(self::API_USER_LIST, [
|
||||
'http_code' => 401,
|
||||
]);
|
||||
$mockedClient = new MockHttpClient(function () use ($response) {
|
||||
return $response;
|
||||
});
|
||||
$this->expectException(BriloRemoteApiException::class);
|
||||
$briloApiUsers = new BriloApiUsers($mockedClient, $this->getLogger(), $serializer);
|
||||
$briloApiUsers->getUsers();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User[]
|
||||
*/
|
||||
private function buildTestUserList(): array
|
||||
{
|
||||
// convert self::API_USER_LIST to User[]
|
||||
return array_map(function ($userData) {
|
||||
return new User(
|
||||
$userData['id'],
|
||||
$userData['name'],
|
||||
$userData['username'],
|
||||
$userData['email'],
|
||||
$userData['phone'],
|
||||
$userData['website'],
|
||||
new Address(
|
||||
$userData['address']['street'],
|
||||
$userData['address']['suite'],
|
||||
$userData['address']['city'],
|
||||
$userData['address']['zipcode'],
|
||||
new AddressGeo(
|
||||
$userData['address']['geo']['lat'],
|
||||
$userData['address']['geo']['lng']
|
||||
)
|
||||
),
|
||||
new Company(
|
||||
$userData['company']['name'],
|
||||
$userData['company']['catchPhrase'],
|
||||
$userData['company']['bs']
|
||||
)
|
||||
);
|
||||
}, self::API_USER_LIST);
|
||||
}
|
||||
}
|
62
tests/Unit/Service/Remote/RetryingClientTraitTest.php
Normal file
62
tests/Unit/Service/Remote/RetryingClientTraitTest.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Service\Remote;
|
||||
|
||||
use App\Service\Remote\RetryingClientTrait;
|
||||
use App\Service\Remote\RetryingFailClientTrait;
|
||||
use App\Tests\Common\LoggerTrait;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class RetryingClientTraitTest extends TestCase
|
||||
{
|
||||
use LoggerTrait;
|
||||
|
||||
private int $callCount = 0;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp(); // TODO: Change the autogenerated stub
|
||||
$this->callCount = 0;
|
||||
}
|
||||
|
||||
public function testSuccess(): void
|
||||
{
|
||||
$trait = new class {
|
||||
use RetryingClientTrait {
|
||||
retryingFailRequest as public; // make the method public
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$result = $trait->retryingFailRequest(2, 0, [\RuntimeException::class], $this->getLogger(), function () {
|
||||
$this->callCount = $this->callCount + 1;
|
||||
return 'foo';
|
||||
});
|
||||
|
||||
$this->assertEquals(1, $this->callCount);
|
||||
$this->assertEquals('foo', $result);
|
||||
}
|
||||
public function testRetyingFail(): void
|
||||
{
|
||||
$trait = new class {
|
||||
use RetryingClientTrait {
|
||||
retryingFailRequest as public; // make the method public
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
try {
|
||||
$trait->retryingFailRequest(2, 0, [\RuntimeException::class], $this->getLogger(), function () {
|
||||
$this->callCount = $this->callCount + 1;
|
||||
throw new \RuntimeException("test");
|
||||
});
|
||||
} catch (\RuntimeException) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
$this->assertEquals(3, $this->callCount);
|
||||
}
|
||||
// extra attributes muzeme safe ignorovat
|
||||
}
|
Loading…
Reference in New Issue
Block a user