444 lines
15 KiB
PHP
444 lines
15 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Service;
|
|
|
|
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\Inco;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Allegations;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Ingredients;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoShort;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PageOf;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PaginationDto;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\BrandCode;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoCompoId;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoId;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\Pagination\PageSize;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\Pagination\Pagination;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\Pagination\StreamOf;
|
|
use Uwil\ArcadiaApiPhpClient\Mapper\IncoCompoMapper;
|
|
use Uwil\ArcadiaApiPhpClient\Repository\IncoCompoRepository;
|
|
use Uwil\ArcadiaApiPhpClient\Repository\IncoRepository;
|
|
use Uwil\ArcadiaApiPhpClient\Repository\IncoShortRepository;
|
|
use Uwil\ArcadiaApiPhpClient\Service\ArcadiaIncoService;
|
|
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoCompo as KiotaIncoCompo;
|
|
|
|
/** @return array{
|
|
* \Uwil\ArcadiaApiPhpClient\Repository\IncoRepository&\Mockery\MockInterface,
|
|
* \Uwil\ArcadiaApiPhpClient\Repository\IncoShortRepository&\Mockery\MockInterface,
|
|
* \Uwil\ArcadiaApiPhpClient\Repository\IncoCompoRepository&\Mockery\MockInterface
|
|
* } */
|
|
function serviceIncoMocks(): array
|
|
{
|
|
return [
|
|
Mockery::mock(IncoRepository::class),
|
|
Mockery::mock(IncoShortRepository::class),
|
|
Mockery::mock(IncoCompoRepository::class),
|
|
];
|
|
}
|
|
|
|
function dummyIncoForService(): Inco
|
|
{
|
|
return new Inco(
|
|
id: new IncoId('12345'),
|
|
name: 'Poulet',
|
|
libelle: 'Poulet fermier',
|
|
description: 'Description',
|
|
allegations: new Allegations([], [], [], []),
|
|
sellArguments: '',
|
|
preparationAdvices: '',
|
|
tips: null,
|
|
sellFamilly: null,
|
|
ingredients: new Ingredients([]),
|
|
portions: null,
|
|
allergens: [],
|
|
brand: new Brand(code: new BrandCode('LGL39'), label: 'Le Gaulois'),
|
|
isSeasonal: false,
|
|
weight: null,
|
|
nutriscore: null,
|
|
storageCondition: null,
|
|
additives: [],
|
|
compo: null,
|
|
createdAt: null,
|
|
updatedAt: null,
|
|
);
|
|
}
|
|
|
|
function dummyIncoShortForService(): IncoShort
|
|
{
|
|
return new IncoShort(
|
|
id: new IncoId('12345'),
|
|
name: 'Poulet',
|
|
libelle: 'Poulet fermier',
|
|
description: 'Description',
|
|
created_at: null,
|
|
updated_at: null,
|
|
);
|
|
}
|
|
|
|
function dummyIncoCompoForService(): IncoCompo
|
|
{
|
|
return (new IncoCompoMapper())->toDto(new KiotaIncoCompo());
|
|
}
|
|
|
|
describe('ArcadiaIncoService', function () {
|
|
describe('getAll', function () {
|
|
it('returns PageOf when repository succeeds', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[dummyIncoShortForService()]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAll')
|
|
->once()
|
|
->with($pagination, null)
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->getAll($pagination);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedPage);
|
|
});
|
|
|
|
it('returns ApiError when repository fails', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
$error = new ServerError('Internal Server Error', 500);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAll')
|
|
->once()
|
|
->with($pagination, null)
|
|
->andReturn($error);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->getAll($pagination);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(ApiError::class);
|
|
expect($result)->toBe($error);
|
|
});
|
|
});
|
|
|
|
describe('getAllOfBrands', function () {
|
|
it('returns PageOf when given a single BrandCode', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
$brand = new BrandCode('LGL39');
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[dummyIncoShortForService()]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAllHavingBrands')
|
|
->once()
|
|
->with($pagination, [$brand], null)
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->getAllOfBrands($pagination, $brand);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedPage);
|
|
});
|
|
|
|
it('throws InvalidArgumentException when brands is empty', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN / THEN
|
|
expect(fn () => $service->getAllOfBrands($pagination, []))
|
|
->toThrow(\InvalidArgumentException::class, 'At least 1 brand code is required');
|
|
});
|
|
|
|
it('throws InvalidArgumentException when element is not BrandCode', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN / THEN
|
|
expect(fn () => $service->getAllOfBrands($pagination, ['not-a-brand'])) // @phpstan-ignore-line
|
|
->toThrow(\InvalidArgumentException::class, 'Expected instance of ' . BrandCode::class);
|
|
});
|
|
});
|
|
|
|
describe('getAllOfBrandsSince', function () {
|
|
it('returns PageOf when given valid brands and since', function () {
|
|
// GIVEN
|
|
$pagination = Pagination::firstPage();
|
|
$brand = new BrandCode('LGL39');
|
|
$since = new \DateTimeImmutable('2024-01-01');
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[dummyIncoShortForService()]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAllHavingBrandsSince')
|
|
->once()
|
|
->with($pagination, $since, [$brand], \SortDirection::Descending)
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->getAllOfBrandsSince($pagination, $brand, $since);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedPage);
|
|
});
|
|
});
|
|
|
|
describe('findByIncoIdLike', function () {
|
|
it('returns PageOf when search succeeds', function () {
|
|
// GIVEN
|
|
$brand = new BrandCode('LGL39');
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[dummyIncoShortForService()]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('findWhere')
|
|
->once()
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findByIncoIdLike('poulet', $brand);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedPage);
|
|
});
|
|
|
|
it('throws InvalidArgumentException when no brands are passed', function () {
|
|
// GIVEN
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN / THEN
|
|
expect(fn () => $service->findByIncoIdLike('poulet'))
|
|
->toThrow(\InvalidArgumentException::class, 'At least 1 brand code is required');
|
|
});
|
|
});
|
|
|
|
describe('findBy', function () {
|
|
it('returns Inco when found', function () {
|
|
// GIVEN
|
|
$id = new IncoId('12345');
|
|
$expectedInco = dummyIncoForService();
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$incoRepo->shouldReceive('find')
|
|
->once()
|
|
->with($id)
|
|
->andReturn($expectedInco);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findBy($id);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedInco);
|
|
});
|
|
|
|
it('returns null when not found', function () {
|
|
// GIVEN
|
|
$id = new IncoId('12345');
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$incoRepo->shouldReceive('find')
|
|
->once()
|
|
->with($id)
|
|
->andReturnNull();
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findBy($id);
|
|
|
|
// THEN
|
|
expect($result)->toBeNull();
|
|
});
|
|
|
|
it('returns ApiError when repository fails', function () {
|
|
// GIVEN
|
|
$id = new IncoId('12345');
|
|
$error = new ServerError('Internal Server Error', 500);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$incoRepo->shouldReceive('find')
|
|
->once()
|
|
->with($id)
|
|
->andReturn($error);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findBy($id);
|
|
|
|
// THEN
|
|
expect($result)->toBeInstanceOf(ApiError::class);
|
|
expect($result)->toBe($error);
|
|
});
|
|
});
|
|
|
|
describe('findCompo', function () {
|
|
it('delegates to find when given IncoCompoId', function () {
|
|
// GIVEN
|
|
$id = new IncoCompoId('99');
|
|
$expectedCompo = dummyIncoCompoForService();
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$compoRepo->shouldReceive('find')
|
|
->once()
|
|
->with($id)
|
|
->andReturn($expectedCompo);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findCompo($id);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedCompo);
|
|
});
|
|
|
|
it('delegates to findFor when given IncoId', function () {
|
|
// GIVEN
|
|
$id = new IncoId('12345');
|
|
$expectedCompo = dummyIncoCompoForService();
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$compoRepo->shouldReceive('findFor')
|
|
->once()
|
|
->with($id)
|
|
->andReturn($expectedCompo);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findCompo($id);
|
|
|
|
// THEN
|
|
expect($result)->toBe($expectedCompo);
|
|
});
|
|
|
|
it('returns null when composition not found', function () {
|
|
// GIVEN
|
|
$id = new IncoId('12345');
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$compoRepo->shouldReceive('findFor')
|
|
->once()
|
|
->with($id)
|
|
->andReturnNull();
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$result = $service->findCompo($id);
|
|
|
|
// THEN
|
|
expect($result)->toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('streaming methods', function () {
|
|
it('streamAll returns StreamOf yielding inco shorts', function () {
|
|
// GIVEN
|
|
$incoShort = dummyIncoShortForService();
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[$incoShort]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAll')
|
|
->once()
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$stream = $service->streamAll(new PageSize(50));
|
|
$items = iterator_to_array($stream);
|
|
|
|
// THEN
|
|
expect($stream)->toBeInstanceOf(StreamOf::class);
|
|
expect($items)->toHaveCount(1);
|
|
expect($items[0])->toBe($incoShort);
|
|
});
|
|
|
|
it('streamAllOfBrands returns StreamOf yielding inco shorts', function () {
|
|
// GIVEN
|
|
$incoShort = dummyIncoShortForService();
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[$incoShort]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAllHavingBrands')
|
|
->once()
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$stream = $service->streamAllOfBrands(new BrandCode('LGL39'));
|
|
$items = iterator_to_array($stream);
|
|
|
|
// THEN
|
|
expect($stream)->toBeInstanceOf(StreamOf::class);
|
|
expect($items)->toHaveCount(1);
|
|
expect($items[0])->toBe($incoShort);
|
|
});
|
|
|
|
it('streamAllOfBrandsSince returns StreamOf yielding inco shorts', function () {
|
|
// GIVEN
|
|
$incoShort = dummyIncoShortForService();
|
|
$expectedPage = new PageOf(
|
|
new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1),
|
|
[$incoShort]
|
|
);
|
|
|
|
[$incoRepo, $shortRepo, $compoRepo] = serviceIncoMocks();
|
|
$shortRepo->shouldReceive('selectAllHavingBrandsSince')
|
|
->once()
|
|
->andReturn($expectedPage);
|
|
|
|
$service = new ArcadiaIncoService($incoRepo, $shortRepo, $compoRepo);
|
|
|
|
// WHEN
|
|
$stream = $service->streamAllOfBrandsSince(new BrandCode('LGL39'), new \DateTimeImmutable('2024-01-01'));
|
|
$items = iterator_to_array($stream);
|
|
|
|
// THEN
|
|
expect($stream)->toBeInstanceOf(StreamOf::class);
|
|
expect($items)->toHaveCount(1);
|
|
expect($items[0])->toBe($incoShort);
|
|
});
|
|
});
|
|
});
|