From 83d01adfc80c05d520f19ff79a9284beeca25f2a Mon Sep 17 00:00:00 2001 From: Maciej Kobus Date: Fri, 5 Nov 2021 15:21:45 +0100 Subject: [PATCH 1/2] IBX-843: Introduced ContentLocationMapper For more details see https://issues.ibexa.co/browse/IBX-843 and https://github.com/ezsystems/ezplatform-kernel/pull/249 * Created InMemoryContentLocationMapper * Implemented LocationService hooks for ContentLocationMapper * Registered DI services * Created unit tests --- .../EzPublishCoreExtension.php | 1 + .../ContentLocationMapper.php | 23 ++ .../DecoratedLocationService.php | 131 ++++++++++ .../InMemoryContentLocationMapper.php | 56 +++++ eZ/Publish/Core/Repository/Mapper/Readme.md | 7 +- .../DecoratedLocationServiceTest.php | 231 ++++++++++++++++++ .../InMemoryContentLocationMapperTest.php | 60 +++++ eZ/Publish/Core/settings/containerBuilder.php | 1 + .../Core/settings/content_location_mapper.yml | 14 ++ 9 files changed, 520 insertions(+), 4 deletions(-) create mode 100644 eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php create mode 100644 eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php create mode 100644 eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php create mode 100644 eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php create mode 100644 eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php create mode 100644 eZ/Publish/Core/settings/content_location_mapper.yml diff --git a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php index 8de738e3ad..741a121db3 100644 --- a/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php +++ b/eZ/Bundle/EzPublishCoreBundle/DependencyInjection/EzPublishCoreExtension.php @@ -344,6 +344,7 @@ private function handleApiLoading(ContainerBuilder $container, FileLoader $loade $coreLoader->load('user_preference.yml'); $coreLoader->load('events.yml'); $coreLoader->load('thumbnails.yml'); + $coreLoader->load('content_location_mapper.yml'); // Public API services $loader->load('papi.yml'); diff --git a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php b/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php new file mode 100644 index 0000000000..15294944c3 --- /dev/null +++ b/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php @@ -0,0 +1,23 @@ +contentLocationMapper = $contentLocationMapper; + } + + public function loadLocation( + int $locationId, + ?array $prioritizedLanguages = null, + ?bool $useAlwaysAvailable = null + ): Location { + $location = $this->innerService->loadLocation( + $locationId, + $prioritizedLanguages, + $useAlwaysAvailable + ); + + $this->contentLocationMapper->setMapping( + $locationId, + $location->contentId + ); + + return $location; + } + + public function loadLocationList( + array $locationIds, + ?array $prioritizedLanguages = null, + ?bool $useAlwaysAvailable = null + ): iterable { + $locationList = $this->innerService->loadLocationList( + $locationIds, + $prioritizedLanguages, + $useAlwaysAvailable + ); + + $this->setLocationMappings($locationList); + + return $locationList; + } + + public function loadLocations( + ContentInfo $contentInfo, + ?Location $rootLocation = null, + ?array $prioritizedLanguages = null + ): iterable { + $locations = $this->innerService->loadLocations( + $contentInfo, + $rootLocation, + $prioritizedLanguages + ); + + $this->setLocationMappings($locations); + + return $locations; + } + + public function loadLocationChildren( + Location $location, + int $offset = 0, + int $limit = 25, + ?array $prioritizedLanguages = null + ): LocationList { + $locationChildren = $this->innerService->loadLocationChildren( + $location, + $offset, + $limit, + $prioritizedLanguages + ); + + $this->setLocationMappings($locationChildren->locations); + + return $locationChildren; + } + + public function loadAllLocations( + int $offset = 0, + int $limit = 25 + ): array { + $locations = $this->innerService->loadAllLocations( + $offset, + $limit + ); + + $this->setLocationMappings($locations); + + return $locations; + } + + /** + * @param iterable<\eZ\Publish\API\Repository\Values\Content\Location> + */ + private function setLocationMappings(iterable $locationList): void + { + foreach ($locationList as $location) { + $this->contentLocationMapper->setMapping( + $location->id, + $location->contentId + ); + } + } +} diff --git a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php b/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php new file mode 100644 index 0000000000..bd731dfe45 --- /dev/null +++ b/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php @@ -0,0 +1,56 @@ + */ + private $map; + + /** + * @param int[] $map + */ + public function __construct(array $map = []) + { + $this->map = $map; + } + + public function hasMapping(int $locationId): bool + { + return isset($this->map[$locationId]); + } + + public function getMapping(int $locationId): int + { + return $this->map[$locationId]; + } + + public function setMapping(int $locationId, int $contentId): void + { + $this->map[$locationId] = $contentId; + } + + public function removeMapping(int $locationId): void + { + unset($this->map[$locationId]); + } +} diff --git a/eZ/Publish/Core/Repository/Mapper/Readme.md b/eZ/Publish/Core/Repository/Mapper/Readme.md index e9c609f342..9e5c7de284 100644 --- a/eZ/Publish/Core/Repository/Mapper/Readme.md +++ b/eZ/Publish/Core/Repository/Mapper/Readme.md @@ -1,7 +1,6 @@ # Mappers -Collection of light mappers meant for internal use in Repository -and/or RepositoryServices. +Collection of light mappers meant for internal use by Ibexa packages only. -Given their use they can not rely on Repository or RepositoryServices as -that will lead to cyclic dependencies, they can only rely on SPI and other helpers. +Given their use they should not rely on Repository or RepositoryServices as +that will lead to cyclic dependencies, they should only rely on SPI and other helpers. diff --git a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php b/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php new file mode 100644 index 0000000000..0e967ba16e --- /dev/null +++ b/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php @@ -0,0 +1,231 @@ +mapper = $this->createMock(ContentLocationMapper::class); + $this->innerLocationService = $this->createMock(ApiLocationService::class); + + $this->locationService = new DecoratedLocationService($this->innerLocationService, $this->mapper); + } + + public function testLoadLocation(): void + { + $location = new Location([ + 'id' => 1, + 'contentInfo' => new ContentInfo([ + 'id' => 2, + ]), + ]); + + $this->innerLocationService + ->method('loadLocation') + ->willReturn($location); + + $this->mapper + ->expects($this->once()) + ->method('setMapping') + ->with(1, 2); + + $actualLocation = $this->locationService->loadLocation(1); + self::assertInstanceOf(Location::class, $actualLocation); + self::assertEquals(1, $actualLocation->id); + self::assertEquals(2, $actualLocation->contentId); + } + + public function testLoadLocationList(): void + { + $locations = new LocationList([ + 'locations' => [ + new Location([ + 'id' => 1, + 'contentInfo' => new ContentInfo([ + 'id' => 2, + ]), + ]), + new Location([ + 'id' => 3, + 'contentInfo' => new ContentInfo([ + 'id' => 4, + ]), + ]), + ], + ]); + + $this->innerLocationService + ->method('loadLocationList') + ->willReturn($locations); + + $this->mapper + ->expects($this->atLeastOnce()) + ->method('setMapping') + ->withConsecutive([1, 2], [3, 4]); + + $actualLocations = $this->locationService->loadLocationList([1, 2]); + + $location1 = $actualLocations->locations[0]; + self::assertInstanceOf(Location::class, $location1); + self::assertEquals(1, $location1->id); + self::assertEquals(2, $location1->contentId); + + $location2 = $actualLocations->locations[1]; + self::assertInstanceOf(Location::class, $location2); + self::assertEquals(3, $location2->id); + self::assertEquals(4, $location2->contentId); + } + + public function testLoadLocations(): void + { + $contentInfo = new ContentInfo([ + 'id' => 1, + ]); + $locations = [ + new Location([ + 'id' => 1, + 'contentInfo' => new ContentInfo([ + 'id' => 2, + ]), + ]), + new Location([ + 'id' => 3, + 'contentInfo' => new ContentInfo([ + 'id' => 4, + ]), + ]), + ]; + + $this->innerLocationService + ->method('loadLocations') + ->with($contentInfo) + ->willReturn($locations); + + $this->mapper + ->expects($this->atLeastOnce()) + ->method('setMapping') + ->withConsecutive([1, 2], [3, 4]); + + $actualLocations = $this->locationService->loadLocations($contentInfo); + + $location1 = $actualLocations[0]; + self::assertInstanceOf(Location::class, $location1); + self::assertEquals(1, $location1->id); + self::assertEquals(2, $location1->contentId); + + $location2 = $actualLocations[1]; + self::assertInstanceOf(Location::class, $location2); + self::assertEquals(3, $location2->id); + self::assertEquals(4, $location2->contentId); + } + + public function testLoadLocationChildren(): void + { + $location = new Location([ + 'id' => 5, + ]); + $locationList = new LocationList([ + 'locations' => [ + new Location([ + 'id' => 1, + 'contentInfo' => new ContentInfo([ + 'id' => 2, + ]), + ]), + new Location([ + 'id' => 3, + 'contentInfo' => new ContentInfo([ + 'id' => 4, + ]), + ]), + ], + ]); + + $this->innerLocationService + ->method('loadLocationChildren') + ->with($location) + ->willReturn($locationList); + + $this->mapper + ->expects($this->atLeastOnce()) + ->method('setMapping') + ->withConsecutive([1, 2], [3, 4]); + + $actualLocations = $this->locationService->loadLocationChildren($location); + + $location1 = $actualLocations->locations[0]; + self::assertInstanceOf(Location::class, $location1); + self::assertEquals(1, $location1->id); + self::assertEquals(2, $location1->contentId); + + $location2 = $actualLocations->locations[1]; + self::assertInstanceOf(Location::class, $location2); + self::assertEquals(3, $location2->id); + self::assertEquals(4, $location2->contentId); + } + + public function testLoadAllLocations(): void + { + $locations = [ + new Location([ + 'id' => 1, + 'contentInfo' => new ContentInfo([ + 'id' => 2, + ]), + ]), + new Location([ + 'id' => 3, + 'contentInfo' => new ContentInfo([ + 'id' => 4, + ]), + ]), + ]; + + $this->innerLocationService + ->method('loadAllLocations') + ->willReturn($locations); + + $this->mapper + ->expects($this->atLeastOnce()) + ->method('setMapping') + ->withConsecutive([1, 2], [3, 4]); + + $actualLocations = $this->locationService->loadAllLocations(); + + $location1 = $actualLocations[0]; + self::assertInstanceOf(Location::class, $location1); + self::assertEquals(1, $location1->id); + self::assertEquals(2, $location1->contentId); + + $location2 = $actualLocations[1]; + self::assertInstanceOf(Location::class, $location2); + self::assertEquals(3, $location2->id); + self::assertEquals(4, $location2->contentId); + } +} diff --git a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php b/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php new file mode 100644 index 0000000000..48945279f7 --- /dev/null +++ b/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php @@ -0,0 +1,60 @@ + 2, + 3 => 4, + 5 => 6, + ]; + $this->mapper = new InMemoryContentLocationMapper($map); + } + + public function testGetMapping(): void + { + self::assertEquals(2, $this->mapper->getMapping(1)); + } + + public function testHasMapping(): void + { + self::assertTrue($this->mapper->hasMapping(5)); + self::assertFalse($this->mapper->hasMapping(7)); + } + + public function testSetMapping(): void + { + self::assertFalse($this->mapper->hasMapping(7)); + + $this->mapper->setMapping(7, 8); + + self::assertTrue($this->mapper->hasMapping(7)); + self::assertEquals(8, $this->mapper->getMapping(7)); + } + + public function testRemoveMapping(): void + { + self::assertTrue($this->mapper->hasMapping(3)); + + $this->mapper->removeMapping(3); + + self::assertFalse($this->mapper->hasMapping(3)); + } +} diff --git a/eZ/Publish/Core/settings/containerBuilder.php b/eZ/Publish/Core/settings/containerBuilder.php index 95809e3a2c..4b77f3cb00 100644 --- a/eZ/Publish/Core/settings/containerBuilder.php +++ b/eZ/Publish/Core/settings/containerBuilder.php @@ -47,6 +47,7 @@ $loader->load('policies.yml'); $loader->load('events.yml'); $loader->load('thumbnails.yml'); +$loader->load('content_location_mapper.yml'); // Cache settings (takes same env variables as ezplatform does, only supports "singleredis" setup) if (getenv('CUSTOM_CACHE_POOL') === 'singleredis') { diff --git a/eZ/Publish/Core/settings/content_location_mapper.yml b/eZ/Publish/Core/settings/content_location_mapper.yml new file mode 100644 index 0000000000..ccbbbdd314 --- /dev/null +++ b/eZ/Publish/Core/settings/content_location_mapper.yml @@ -0,0 +1,14 @@ +services: + _defaults: + autoconfigure: true + autowire: true + public: true + + eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper: ~ + + eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper: '@eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper' + + eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService: + decorates: ezpublish.api.service.inner_location + arguments: + $innerService: '@.inner' From db2e63ed5f9718ea783f4a91ca00dea82ef806a4 Mon Sep 17 00:00:00 2001 From: Maciej Kobus Date: Tue, 9 Nov 2021 08:33:23 +0100 Subject: [PATCH 2/2] IBX-843: Aligned changes to 3.3 --- eZ/Publish/Core/settings/content_location_mapper.yml | 6 +++--- .../ContentLocationMapper/ContentLocationMapper.php | 2 +- .../ContentLocationMapper/DecoratedLocationService.php | 4 ++-- .../InMemoryContentLocationMapper.php | 2 +- .../DecoratedLocationServiceTest.php | 10 +++++----- .../InMemoryContentLocationMapperTest.php | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) rename {eZ/Publish/Core => src/lib}/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php (89%) rename {eZ/Publish/Core => src/lib}/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php (95%) rename {eZ/Publish/Core => src/lib}/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php (95%) rename {eZ/Publish/Core/Repository/Tests => tests/lib/Repository}/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php (94%) rename {eZ/Publish/Core/Repository/Tests => tests/lib/Repository}/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php (83%) diff --git a/eZ/Publish/Core/settings/content_location_mapper.yml b/eZ/Publish/Core/settings/content_location_mapper.yml index ccbbbdd314..53e78118c6 100644 --- a/eZ/Publish/Core/settings/content_location_mapper.yml +++ b/eZ/Publish/Core/settings/content_location_mapper.yml @@ -4,11 +4,11 @@ services: autowire: true public: true - eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper: ~ + Ibexa\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper: ~ - eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper: '@eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper' + Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper: '@Ibexa\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper' - eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService: + Ibexa\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService: decorates: ezpublish.api.service.inner_location arguments: $innerService: '@.inner' diff --git a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php b/src/lib/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php similarity index 89% rename from eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php rename to src/lib/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php index 15294944c3..5744d06cc2 100644 --- a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php +++ b/src/lib/Repository/Mapper/ContentLocationMapper/ContentLocationMapper.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace eZ\Publish\Core\Repository\Mapper\ContentLocationMapper; +namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper; /** * @internal For internal use by Ibexa packages only diff --git a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php b/src/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php similarity index 95% rename from eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php rename to src/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php index cfc6847327..98bed1c577 100644 --- a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php +++ b/src/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationService.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace eZ\Publish\Core\Repository\Mapper\ContentLocationMapper; +namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper; use eZ\Publish\API\Repository\LocationService as RepositoryLocationService; use eZ\Publish\API\Repository\Values\Content\ContentInfo; @@ -21,7 +21,7 @@ */ final class DecoratedLocationService extends LocationServiceDecorator { - /** @var \eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */ + /** @var \Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */ private $contentLocationMapper; public function __construct( diff --git a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php b/src/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php similarity index 95% rename from eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php rename to src/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php index bd731dfe45..0df0775d36 100644 --- a/eZ/Publish/Core/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php +++ b/src/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapper.php @@ -6,7 +6,7 @@ */ declare(strict_types=1); -namespace eZ\Publish\Core\Repository\Mapper\ContentLocationMapper; +namespace Ibexa\Core\Repository\Mapper\ContentLocationMapper; /** * Retrieves Content ID from Location ID. diff --git a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php b/tests/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php similarity index 94% rename from eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php rename to tests/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php index 0e967ba16e..6479417ba5 100644 --- a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php +++ b/tests/lib/Repository/Mapper/ContentLocationMapper/DecoratedLocationServiceTest.php @@ -6,25 +6,25 @@ */ declare(strict_types=1); -namespace eZ\Publish\Core\Repository\Tests\Mapper\ContentLocationMapper; +namespace Ibexa\Tests\Core\Repository\Mapper\ContentLocationMapper; use eZ\Publish\API\Repository\LocationService as ApiLocationService; use eZ\Publish\API\Repository\Values\Content\ContentInfo; use eZ\Publish\API\Repository\Values\Content\LocationList; -use eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper; -use eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService; use eZ\Publish\Core\Repository\Values\Content\Location; +use Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper; +use Ibexa\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService; use PHPUnit\Framework\TestCase; class DecoratedLocationServiceTest extends TestCase { - /** @var \eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\DecoratedLocationService */ + /** @var DecoratedLocationService */ private $locationService; /** @var ApiLocationService */ private $innerLocationService; - /** @var \eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */ + /** @var ContentLocationMapper */ private $mapper; protected function setUp(): void diff --git a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php b/tests/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php similarity index 83% rename from eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php rename to tests/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php index 48945279f7..516b201ed4 100644 --- a/eZ/Publish/Core/Repository/Tests/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php +++ b/tests/lib/Repository/Mapper/ContentLocationMapper/InMemoryContentLocationMapperTest.php @@ -6,14 +6,14 @@ */ declare(strict_types=1); -namespace eZ\Publish\Core\Repository\Tests\Mapper\ContentLocationMapper; +namespace Ibexa\Tests\Core\Repository\Mapper\ContentLocationMapper; -use eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper; +use Ibexa\Core\Repository\Mapper\ContentLocationMapper\InMemoryContentLocationMapper; use PHPUnit\Framework\TestCase; class InMemoryContentLocationMapperTest extends TestCase { - /** @var \eZ\Publish\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */ + /** @var \Ibexa\Core\Repository\Mapper\ContentLocationMapper\ContentLocationMapper */ private $mapper; protected function setUp(): void