shouldReceive('selectAll') ->once() ->with($pagination, null) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAll($pagination); // THEN expect($result)->toBe($expectedPage); }); it('returns PageOf when repository succeeds with sorter', function () { // GIVEN $pagination = Pagination::firstPage(); $sorter = new EmployeeSorter(EmployeeSortColumn::startDate, \SortDirection::Ascending); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [dummyEmployeeForService()] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAll') ->once() ->with($pagination, $sorter) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAll($pagination, $sorter); // THEN expect($result)->toBe($expectedPage); }); it('returns ApiError when repository fails', function () { // GIVEN $pagination = Pagination::firstPage(); $error = new ServerError('Internal Server Error', 500); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAll') ->once() ->with($pagination, null) ->andReturn($error); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAll($pagination); // THEN expect($result)->toBeInstanceOf(ApiError::class); expect($result)->toBe($error); }); }); describe('getAllSince', function () { it('returns PageOf when repository succeeds', function () { // GIVEN $pagination = Pagination::firstPage(); $since = new \DateTimeImmutable('2024-01-01'); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [dummyEmployeeForService()] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllSince') ->once() ->with($pagination, $since, \SortDirection::Descending) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAllSince($pagination, $since); // THEN expect($result)->toBe($expectedPage); }); it('returns ApiError when repository fails', function () { // GIVEN $pagination = Pagination::firstPage(); $since = new \DateTimeImmutable('2024-01-01'); $error = new ServerError('Internal Server Error', 500); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllSince') ->once() ->with($pagination, $since, \SortDirection::Descending) ->andReturn($error); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAllSince($pagination, $since); // THEN expect($result)->toBeInstanceOf(ApiError::class); expect($result)->toBe($error); }); }); describe('getAllOfSites', function () { it('returns PageOf when given a single SiteId', function () { // GIVEN $pagination = Pagination::firstPage(); $site = new SiteId('PARIS'); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [dummyEmployeeForService()] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllHavingSites') ->once() ->with($pagination, [$site]) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAllOfSites($pagination, $site); // THEN expect($result)->toBe($expectedPage); }); it('returns PageOf when given an array of SiteIds with sorter', function () { // GIVEN $pagination = Pagination::firstPage(); $sites = [new SiteId('PARIS'), new SiteId('LYON')]; $sorter = new EmployeeSorter(EmployeeSortColumn::createdAt, \SortDirection::Ascending); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [dummyEmployeeForService()] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllHavingSites') ->once() ->with($pagination, $sites, $sorter) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAllOfSites($pagination, $sites, $sorter); // THEN expect($result)->toBe($expectedPage); }); it('throws InvalidArgumentException when sites array is empty', function () { // GIVEN $pagination = Pagination::firstPage(); $repository = Mockery::mock(EmployeeRepository::class); $service = new ArcadiaEmployeeService($repository); // WHEN / THEN expect(fn () => $service->getAllOfSites($pagination, [])) ->toThrow(\InvalidArgumentException::class, 'At least 1 site is required'); }); it('throws InvalidArgumentException when sites element is not SiteId', function () { // GIVEN $pagination = Pagination::firstPage(); $repository = Mockery::mock(EmployeeRepository::class); $service = new ArcadiaEmployeeService($repository); // WHEN / THEN expect(fn () => $service->getAllOfSites($pagination, ['not-a-site-id'])) // @phpstan-ignore-line ->toThrow(\InvalidArgumentException::class, 'Expected instance of ' . SiteId::class); }); }); describe('getAllOfSitesSince', function () { it('returns PageOf when given valid sites and since', function () { // GIVEN $pagination = Pagination::firstPage(); $site = new SiteId('PARIS'); $since = new \DateTimeImmutable('2024-01-01'); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [dummyEmployeeForService()] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllHavingSitesSince') ->once() ->with($pagination, $since, [$site], \SortDirection::Descending) ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->getAllOfSitesSince($pagination, $site, $since); // THEN expect($result)->toBe($expectedPage); }); it('throws InvalidArgumentException when sites array is empty', function () { // GIVEN $pagination = Pagination::firstPage(); $since = new \DateTimeImmutable('2024-01-01'); $repository = Mockery::mock(EmployeeRepository::class); $service = new ArcadiaEmployeeService($repository); // WHEN / THEN expect(fn () => $service->getAllOfSitesSince($pagination, [], $since)) ->toThrow(\InvalidArgumentException::class, 'At least 1 site is required'); }); }); describe('findBy', function () { it('returns Employee when employee is found', function () { // GIVEN $id = new ArcadiaEmployeeId('1234567'); $expectedEmployee = dummyEmployeeForService(); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('find') ->once() ->with($id) ->andReturn($expectedEmployee); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->findBy($id); // THEN expect($result)->toBe($expectedEmployee); }); it('returns null when employee is not found', function () { // GIVEN $id = new ArcadiaEmployeeId('1234567'); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('find') ->once() ->with($id) ->andReturnNull(); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->findBy($id); // THEN expect($result)->toBeNull(); }); it('returns ApiError when repository fails', function () { // GIVEN $id = new ArcadiaEmployeeId('1234567'); $error = new ServerError('Internal Server Error', 500); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('find') ->once() ->with($id) ->andReturn($error); $service = new ArcadiaEmployeeService($repository); // WHEN $result = $service->findBy($id); // THEN expect($result)->toBeInstanceOf(ApiError::class); expect($result)->toBe($error); }); }); describe('streaming methods', function () { it('streamAll returns StreamOf yielding employees', function () { // GIVEN $employee = dummyEmployeeForService(); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [$employee] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAll') ->once() ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // 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($employee); }); it('streamAllSince returns StreamOf yielding employees', function () { // GIVEN $employee = dummyEmployeeForService(); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [$employee] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllSince') ->once() ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $stream = $service->streamAllSince(new \DateTimeImmutable('2024-01-01')); $items = iterator_to_array($stream); // THEN expect($stream)->toBeInstanceOf(StreamOf::class); expect($items)->toHaveCount(1); }); it('streamAllOfSites returns StreamOf yielding employees', function () { // GIVEN $employee = dummyEmployeeForService(); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [$employee] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllHavingSites') ->once() ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $stream = $service->streamAllOfSites(new SiteId('PARIS')); $items = iterator_to_array($stream); // THEN expect($stream)->toBeInstanceOf(StreamOf::class); expect($items)->toHaveCount(1); }); it('streamAllOfSitesSince returns StreamOf yielding employees', function () { // GIVEN $employee = dummyEmployeeForService(); $expectedPage = new PageOf( new PaginationDto(page: 1, pageSize: 50, totalItems: 1, totalPages: 1), [$employee] ); $repository = Mockery::mock(EmployeeRepository::class); $repository->shouldReceive('selectAllHavingSitesSince') ->once() ->andReturn($expectedPage); $service = new ArcadiaEmployeeService($repository); // WHEN $stream = $service->streamAllOfSitesSince(new SiteId('PARIS'), new \DateTimeImmutable('2024-01-01')); $items = iterator_to_array($stream); // THEN expect($stream)->toBeInstanceOf(StreamOf::class); expect($items)->toHaveCount(1); }); }); });