ldc-arcadia-genesis-php-client/tests/Unit/Repository/BrandApiRepositoryTest.php

224 lines
7.5 KiB
PHP
Raw Permalink Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit\Repository;
use Http\Promise\FulfilledPromise;
use Http\Promise\RejectedPromise;
use Microsoft\Kiota\Abstractions\ApiException;
use Mockery;
use Uwil\ArcadiaApiPhpClient\Error\ApiError;
use Uwil\ArcadiaApiPhpClient\Error\ServerError;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Brand;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PageOf;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PaginationDto;
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\BrandCode;
use Uwil\ArcadiaApiPhpClient\Lib\Pagination\Pagination;
use Uwil\ArcadiaApiPhpClient\Mapper\BrandMapper;
use Uwil\ArcadiaApiPhpClient\Repository\BrandApiRepository;
use Uwil\ArcadiaKiotaOpenApiClient\ApiClient;
use Uwil\ArcadiaKiotaOpenApiClient\Brands\BrandsRequestBuilder;
use Uwil\ArcadiaKiotaOpenApiClient\Brands\Item\WithBrandCodeItemRequestBuilder;
use Uwil\ArcadiaKiotaOpenApiClient\Models\Brand as KiotaBrand;
use Uwil\ArcadiaKiotaOpenApiClient\Models\BrandItemResponse;
use Uwil\ArcadiaKiotaOpenApiClient\Models\BrandListResponse;
/** @return array{
* \Uwil\ArcadiaKiotaOpenApiClient\Brands\BrandsRequestBuilder&\Mockery\MockInterface,
* \Uwil\ArcadiaKiotaOpenApiClient\ApiClient&\Mockery\MockInterface,
* \Uwil\ArcadiaApiPhpClient\Mapper\BrandMapper&\Mockery\MockInterface
* } */
function mocks(): array
{
$brandsBuilder = Mockery::mock(BrandsRequestBuilder::class);
$apiClient = Mockery::mock(ApiClient::class);
$mapper = Mockery::mock(BrandMapper::class);
return [
$brandsBuilder,
$apiClient,
$mapper,
];
}
describe('BrandApiRepository', function () {
describe('selectAll', function () {
it('returns PageOf when request succeeds', function () {
// GIVEN
$listResponse = new BrandListResponse();
$pagination = Pagination::firstPage();
$expectedPage = new PageOf(
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
[new Brand(code: new BrandCode('LGL39'), label: 'Le Gaulois')]
);
$promise = new FulfilledPromise($listResponse);
[
$brandsBuilder,
$apiClient,
$mapper,
] = mocks();
$brandsBuilder->shouldReceive('get')->once()->andReturn($promise);
$apiClient->shouldReceive('brands')->once()->andReturn($brandsBuilder);
$mapper->shouldReceive('toPage')
->once()
->with($listResponse, $pagination)
->andReturn($expectedPage);
$repository = new BrandApiRepository($apiClient, $mapper);
// WHEN
$result = $repository->selectAll($pagination);
// THEN
expect($result)->toBe($expectedPage);
});
it('returns ApiError when request fails', function () {
// GIVEN
$pagination = Pagination::firstPage();
$exception = new ApiException('Internal Server Error');
$exception->setResponseStatusCode(500);
$promise = new RejectedPromise($exception);
[
$brandsBuilder,
$apiClient,
$mapper,
] = mocks();
$brandsBuilder->shouldReceive('get')->once()->andReturn($promise);
$apiClient->shouldReceive('brands')->once()->andReturn($brandsBuilder);
$mapper->shouldNotReceive('toPage');
$repository = new BrandApiRepository($apiClient, $mapper);
// WHEN
$result = $repository->selectAll($pagination);
// THEN
expect($result)->toBeInstanceOf(ApiError::class);
expect($result)->toBeInstanceOf(ServerError::class);
expect($result->message())->toBe('Internal Server Error');
expect($result->statusCode())->toBe(500);
});
});
describe('find', function () {
it('returns Brand when brand is found', function () {
// GIVEN
$code = new BrandCode('LGL39');
$kiotaBrand = new KiotaBrand();
$itemResponse = new BrandItemResponse();
$itemResponse->setBrand($kiotaBrand);
$expectedBrand = new Brand(code: $code, label: 'Le Gaulois');
$promise = new FulfilledPromise($itemResponse);
[
$brandsBuilder,
$apiClient,
$mapper,
] = mocks();
$itemBuilder = Mockery::mock(WithBrandCodeItemRequestBuilder::class);
$itemBuilder->shouldReceive('get')->once()->andReturn($promise);
$brandsBuilder->shouldReceive('byBrandCode')
->once()
->with('LGL39')
->andReturn($itemBuilder);
$apiClient->shouldReceive('brands')->once()->andReturn($brandsBuilder);
$mapper->shouldReceive('toDto')
->once()
->with($kiotaBrand)
->andReturn($expectedBrand);
$repository = new BrandApiRepository($apiClient, $mapper);
// WHEN
$result = $repository->find($code);
// THEN
expect($result)->toBe($expectedBrand);
});
it('returns null when brand is not found (404)', function () {
// GIVEN
$code = new BrandCode('LGL39');
$exception = new ApiException('Brand not found');
$exception->setResponseStatusCode(404);
$promise = new RejectedPromise($exception);
[
$brandsBuilder,
$apiClient,
$mapper,
] = mocks();
$itemBuilder = Mockery::mock(WithBrandCodeItemRequestBuilder::class);
$itemBuilder->shouldReceive('get')->once()->andReturn($promise);
$brandsBuilder->shouldReceive('byBrandCode')
->once()
->with('LGL39')
->andReturn($itemBuilder);
$apiClient->shouldReceive('brands')->once()->andReturn($brandsBuilder);
$mapper->shouldNotReceive('toDto');
$repository = new BrandApiRepository($apiClient, $mapper);
// WHEN
$result = $repository->find($code);
// THEN
expect($result)->toBeNull();
});
it('returns ApiError when request fails', function () {
// GIVEN
$code = new BrandCode('LGL39');
$exception = new ApiException('Internal Server Error');
$exception->setResponseStatusCode(500);
$promise = new RejectedPromise($exception);
[
$brandsBuilder,
$apiClient,
$mapper,
] = mocks();
$itemBuilder = Mockery::mock(WithBrandCodeItemRequestBuilder::class);
$itemBuilder->shouldReceive('get')->once()->andReturn($promise);
$brandsBuilder->shouldReceive('byBrandCode')
->once()
->with('LGL39')
->andReturn($itemBuilder);
$apiClient->shouldReceive('brands')->once()->andReturn($brandsBuilder);
$mapper->shouldNotReceive('toDto');
$repository = new BrandApiRepository($apiClient, $mapper);
// WHEN
$result = $repository->find($code);
// THEN
expect($result)->toBeInstanceOf(ApiError::class);
expect($result)->toBeInstanceOf(ServerError::class);
expect($result->message())->toBe('Internal Server Error');
expect($result->statusCode())->toBe(500);
});
});
});