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); }); }); });