From 07d7a3025ac75e0d4c66e288eb8649065b814650 Mon Sep 17 00:00:00 2001 From: Ondrej Vlach Date: Mon, 29 Jul 2024 20:41:57 +0200 Subject: [PATCH] feat(service): add post api --- src/Service/Remote/BriloApiPosts.php | 25 ++++++ src/Service/Remote/BriloApiUsers.php | 1 + .../Unit/Service/Remote/BlogApiPostsTest.php | 89 ++++++++++++++++++- 3 files changed, 113 insertions(+), 2 deletions(-) diff --git a/src/Service/Remote/BriloApiPosts.php b/src/Service/Remote/BriloApiPosts.php index e08c3af..22b3ef9 100644 --- a/src/Service/Remote/BriloApiPosts.php +++ b/src/Service/Remote/BriloApiPosts.php @@ -4,7 +4,32 @@ declare(strict_types=1); namespace App\Service\Remote; +use App\Entity\Remote\Brilo\Posts\Post; +use App\Entity\Remote\Brilo\Users\User; +use Psr\Log\LoggerInterface; +use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Contracts\HttpClient\HttpClientInterface; + class BriloApiPosts { + 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 posts from Brilo API and return them as an array of Post entities. + * @return Post[] + * @throws \Exception + */ + public function getPosts(): array + { + return $this->fetchApiResponse('https://jsonplaceholder.typicode.com/posts', Post::class); + } } diff --git a/src/Service/Remote/BriloApiUsers.php b/src/Service/Remote/BriloApiUsers.php index ca5d0ab..c699468 100644 --- a/src/Service/Remote/BriloApiUsers.php +++ b/src/Service/Remote/BriloApiUsers.php @@ -25,6 +25,7 @@ final class BriloApiUsers } /** + * Fetch all users from the Brilo API and return them as an array of User entities. * @return User[] * @throws \Exception */ diff --git a/tests/Unit/Service/Remote/BlogApiPostsTest.php b/tests/Unit/Service/Remote/BlogApiPostsTest.php index b485a7c..d8593b3 100644 --- a/tests/Unit/Service/Remote/BlogApiPostsTest.php +++ b/tests/Unit/Service/Remote/BlogApiPostsTest.php @@ -4,7 +4,92 @@ declare(strict_types=1); namespace App\Tests\Unit\Service\Remote; -class BlogApiPostsTest -{ +use App\Entity\Remote\Brilo\Posts\Post; +use App\Entity\Remote\Brilo\Users\User; +use App\Service\Remote\BriloApiPosts; +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 BlogApiPostsTest extends TestCase +{ + use LoggerTrait; + + private const array API_POSTS_LIST = [ + [ + "userId" => 1, + "id" => 1, + "title" => "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", + "body" => "quia et suscipit +suscipit recusandae consequuntur expedita et cum +reprehenderit molestiae ut ut quas totam +nostrum rerum est autem sunt rem eveniet architecto" + ], + [ + "userId" => 1, + "id" => 2, + "title" => "qui est esse", + "body" => "est rerum tempore vitae +sequi sint nihil reprehenderit dolor beatae ea dolores neque +fugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis +qui aperiam non debitis possimus qui neque nisi nulla" + ] + ]; + + public function testUserListSuccess(): void + { + $testUserList = $this->buildTestPostList(); + $serializer = $this->createMock(SerializerInterface::class); + $serializer + ->expects($this->once()) + ->method('deserialize') + ->with( + json_encode(self::API_POSTS_LIST), + Post::class . '[]', + 'json' + )->willReturn($testUserList); + + $response = new JsonMockResponse(self::API_POSTS_LIST); + $mockedClient = new MockHttpClient($response); + $briloApiPosts = new BriloApiPosts($mockedClient, $this->getLogger(), $serializer); + $this->assertEquals($testUserList, $briloApiPosts->getPosts()); + } + + public function testInvalidHttpCodeReturned(): void + { + $serializer = $this->createMock(SerializerInterface::class); + $serializer + ->expects($this->never()) + ->method('deserialize'); + + $response = new JsonMockResponse(self::API_POSTS_LIST, [ + 'http_code' => 401, + ]); + $mockedClient = new MockHttpClient(function () use ($response) { + return $response; + }); + $this->expectException(BriloRemoteApiException::class); + $briloApiPosts = new BriloApiPosts($mockedClient, $this->getLogger(), $serializer); + $briloApiPosts->getPosts(); + } + + /** + * @return Post[] + */ + public function buildTestPostList(): array + { + // Convert self::API_POSTS_LIST to Post[] and return it + return array_map(function ($postData) { + return new Post( + $postData['userId'], + $postData['id'], + $postData['title'], + $postData['body'] + ); + }, self::API_POSTS_LIST); + } }