diff --git a/Content/Application/ContentDataMapper/ContentDataMapper.php b/Content/Application/ContentDataMapper/ContentDataMapper.php index 81e29d3d..d654912b 100644 --- a/Content/Application/ContentDataMapper/ContentDataMapper.php +++ b/Content/Application/ContentDataMapper/ContentDataMapper.php @@ -32,11 +32,23 @@ public function __construct(iterable $dataMappers) } public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentCollectionInterface $dimensionContentCollection, + array $dimensionAttributes, + array $data ): void { + $localizedDimensionAttributes = $dimensionAttributes; + $unlocalizedDimensionAttributes = $dimensionAttributes; + $unlocalizedDimensionAttributes['locale'] = null; + $unlocalizedDimensionContent = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); + $localizedDimensionContent = $dimensionContentCollection->getDimensionContent($localizedDimensionAttributes); + + if (!$unlocalizedDimensionContent || !$localizedDimensionContent) { + // TODO see https://github.com/sulu/SuluContentBundle/pull/204 + throw new \RuntimeException('Create unlocalized and localized dimension content.'); + } + foreach ($this->dataMappers as $mapper) { - $mapper->map($data, $dimensionContentCollection); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); } } } diff --git a/Content/Application/ContentDataMapper/ContentDataMapperInterface.php b/Content/Application/ContentDataMapper/ContentDataMapperInterface.php index 4f7db9c7..098568b6 100644 --- a/Content/Application/ContentDataMapper/ContentDataMapperInterface.php +++ b/Content/Application/ContentDataMapper/ContentDataMapperInterface.php @@ -19,9 +19,11 @@ interface ContentDataMapperInterface { /** * @param array $data + * @param mixed[] $dimensionAttributes */ public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentCollectionInterface $dimensionContentCollection, + array $dimensionAttributes, + array $data ): void; } diff --git a/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapper.php index 594456bd..a01e64e1 100644 --- a/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapper.php @@ -15,7 +15,7 @@ use Sulu\Bundle\ContentBundle\Content\Domain\Factory\ContactFactoryInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\AuthorInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; class AuthorDataMapper implements DataMapperInterface { @@ -30,30 +30,15 @@ public function __construct(ContactFactoryInterface $contactFactory) } public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$unlocalizedObject instanceof AuthorInterface) { - return; - } - - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - if ($localizedObject) { - if (!$localizedObject instanceof AuthorInterface) { - throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', AuthorInterface::class, \get_class($localizedObject))); - } - - $this->setAuthorData($localizedObject, $data); - + if (!$localizedDimensionContent instanceof AuthorInterface) { return; } - $this->setAuthorData($unlocalizedObject, $data); + $this->setAuthorData($localizedDimensionContent, $data); } /** @@ -61,11 +46,11 @@ public function map( */ private function setAuthorData(AuthorInterface $dimensionContent, array $data): void { - if (isset($data['author'])) { + if (\array_key_exists('author', $data)) { $dimensionContent->setAuthor($this->contactFactory->create($data['author'])); } - if (isset($data['authored'])) { + if (\array_key_exists('authored', $data)) { $dimensionContent->setAuthored(new \DateTimeImmutable($data['authored'])); } } diff --git a/Content/Application/ContentDataMapper/DataMapper/DataMapperInterface.php b/Content/Application/ContentDataMapper/DataMapper/DataMapperInterface.php index 0b732abc..00ab44c5 100644 --- a/Content/Application/ContentDataMapper/DataMapper/DataMapperInterface.php +++ b/Content/Application/ContentDataMapper/DataMapper/DataMapperInterface.php @@ -13,7 +13,7 @@ namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; interface DataMapperInterface { @@ -21,7 +21,8 @@ interface DataMapperInterface * @param array $data */ public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void; } diff --git a/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapper.php index ea6d52eb..8894f559 100644 --- a/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapper.php @@ -15,7 +15,7 @@ use Sulu\Bundle\ContentBundle\Content\Domain\Factory\CategoryFactoryInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Factory\TagFactoryInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface; class ExcerptDataMapper implements DataMapperInterface @@ -37,30 +37,15 @@ public function __construct(TagFactoryInterface $tagFactory, CategoryFactoryInte } public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$unlocalizedObject instanceof ExcerptInterface) { - return; - } - - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - if ($localizedObject) { - if (!$localizedObject instanceof ExcerptInterface) { - throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', ExcerptInterface::class, \get_class($localizedObject))); - } - - $this->setExcerptData($localizedObject, $data); - + if (!$localizedDimensionContent instanceof ExcerptInterface) { return; } - $this->setExcerptData($unlocalizedObject, $data); + $this->setExcerptData($localizedDimensionContent, $data); } /** @@ -68,14 +53,28 @@ public function map( */ private function setExcerptData(ExcerptInterface $dimensionContent, array $data): void { - $dimensionContent->setExcerptTitle($data['excerptTitle'] ?? null); - $dimensionContent->setExcerptDescription($data['excerptDescription'] ?? null); - $dimensionContent->setExcerptMore($data['excerptMore'] ?? null); - $dimensionContent->setExcerptImage($data['excerptImage'] ?? null); - $dimensionContent->setExcerptIcon($data['excerptIcon'] ?? null); - $dimensionContent->setExcerptTags($this->tagFactory->create($data['excerptTags'] ?? [])); - $dimensionContent->setExcerptCategories( - $this->categoryFactory->create($data['excerptCategories'] ?? []) - ); + if (\array_key_exists('excerptTitle', $data)) { + $dimensionContent->setExcerptTitle($data['excerptTitle']); + } + if (\array_key_exists('excerptDescription', $data)) { + $dimensionContent->setExcerptDescription($data['excerptDescription']); + } + if (\array_key_exists('excerptMore', $data)) { + $dimensionContent->setExcerptMore($data['excerptMore']); + } + if (\array_key_exists('excerptImage', $data)) { + $dimensionContent->setExcerptImage($data['excerptImage']); + } + if (\array_key_exists('excerptIcon', $data)) { + $dimensionContent->setExcerptIcon($data['excerptIcon']); + } + if (\array_key_exists('excerptTags', $data)) { + $dimensionContent->setExcerptTags($this->tagFactory->create($data['excerptTags'] ?: [])); + } + if (\array_key_exists('excerptCategories', $data)) { + $dimensionContent->setExcerptCategories( + $this->categoryFactory->create($data['excerptCategories'] ?: []) + ); + } } } diff --git a/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapper.php index db36c749..2b8f262a 100644 --- a/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapper.php @@ -13,11 +13,10 @@ namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\RoutableInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface; use Sulu\Bundle\RouteBundle\Generator\RouteGeneratorInterface; -use Sulu\Bundle\RouteBundle\Manager\ConflictResolverInterface; use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface; use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface; use Sulu\Component\Content\Metadata\PropertyMetadata; @@ -40,11 +39,6 @@ class RoutableDataMapper implements DataMapperInterface */ private $routeManager; - /** - * @var ConflictResolverInterface - */ - private $conflictResolver; - /** * @var array */ @@ -63,37 +57,34 @@ public function __construct( StructureMetadataFactoryInterface $factory, RouteGeneratorInterface $routeGenerator, RouteManagerInterface $routeManager, - ConflictResolverInterface $conflictResolver, array $structureDefaultTypes, array $routeMappings ) { $this->factory = $factory; $this->routeGenerator = $routeGenerator; $this->routeManager = $routeManager; - $this->conflictResolver = $conflictResolver; $this->structureDefaultTypes = $structureDefaultTypes; $this->routeMappings = $routeMappings; } public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$localizedObject || !$localizedObject instanceof RoutableInterface) { + if (!$localizedDimensionContent instanceof RoutableInterface) { return; } - if (!$localizedObject instanceof TemplateInterface) { - throw new \RuntimeException('LocalizedObject needs to extend the TemplateInterface'); + if (!$localizedDimensionContent instanceof TemplateInterface) { + throw new \RuntimeException('LocalizedDimensionContent needs to extend the TemplateInterface.'); } - $type = $localizedObject::getTemplateType(); + if (DimensionContentInterface::STAGE_LIVE !== $localizedDimensionContent->getStage()) { + // return; + } + + $type = $localizedDimensionContent::getTemplateType(); /** @var string|null $template */ $template = $data['template'] ?? null; @@ -112,32 +103,28 @@ public function map( } $property = $this->getRouteProperty($metadata); - if (!$property) { - return; - } - - if (!$localizedObject->getResourceId()) { - // FIXME the code only works if the entity is flushed once and has a valid id + if (!$property) { return; } - $locale = $localizedObject->getLocale(); + $locale = $localizedDimensionContent->getLocale(); if (!$locale) { - return; + throw new \RuntimeException('Expected a LocalizedDimensionContent with a locale.'); } /** @var string $name */ $name = $property->getName(); - $currentRoutePath = $localizedObject->getTemplateData()[$name] ?? null; + $currentRoutePath = $localizedDimensionContent->getTemplateData()[$name] ?? null; if (!\array_key_exists($name, $data) && null !== $currentRoutePath) { return; } $entityClass = null; $routeSchema = null; - $resourceKey = $localizedObject::getResourceKey(); + $resourceKey = $localizedDimensionContent::getResourceKey(); + foreach ($this->routeMappings as $key => $mapping) { if ($resourceKey === $mapping['resource_key']) { $entityClass = $mapping['entityClass'] ?? $key; @@ -147,18 +134,18 @@ public function map( } if (null === $entityClass || null === $routeSchema) { - // TODO FIXME add test case for this - return; // @codeCoverageIgnore + throw new \RuntimeException(\sprintf('No route mapping found for "%s".', $resourceKey)); } $routePath = $data[$name] ?? null; + if (!$routePath) { /** @var mixed $routeGenerationData */ $routeGenerationData = \array_merge( $data, [ - '_unlocalizedObject' => $unlocalizedObject, - '_localizedObject' => $localizedObject, + '_unlocalizedObject' => $unlocalizedDimensionContent, + '_localizedObject' => $localizedDimensionContent, ] ); @@ -166,26 +153,36 @@ public function map( $routeGenerationData, $routeSchema ); + } - if ('/' === $routePath) { - return; - } + if ('/' === $routePath) { + throw new \RuntimeException('Not allowed url "/" given or generated.'); } - $route = $this->routeManager->createOrUpdateByAttributes( - $entityClass, - (string) $localizedObject->getResourceId(), - $locale, - $routePath - ); + if (DimensionContentInterface::STAGE_LIVE === $localizedDimensionContent->getStage()) { + if (!$localizedDimensionContent->getResourceId()) { + // TODO route bundle should work to update the entity later with a resourceId over UPDATE SQL statement + throw new \RuntimeException('Expected a LocalizedDimensionContent with a resourceId.'); + } - $this->conflictResolver->resolve($route); + // route should only be updated in live dimension + $route = $this->routeManager->createOrUpdateByAttributes( + $entityClass, + (string) $localizedDimensionContent->getResourceId(), + $locale, + $routePath, + true + ); + + $routePath = $route->getPath(); + } - if (($data[$name] ?? null) !== $route->getPath()) { - $localizedObject->setTemplateData( + $oldData = $localizedDimensionContent->getTemplateData(); + if (($oldData[$name] ?? null) !== $routePath) { + $localizedDimensionContent->setTemplateData( \array_merge( - $localizedObject->getTemplateData(), - [$name => $route->getPath()] + $oldData, + [$name => $routePath] ) ); } diff --git a/Content/Application/ContentDataMapper/DataMapper/SeoDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/SeoDataMapper.php index 53a2165f..e0ccec17 100644 --- a/Content/Application/ContentDataMapper/DataMapper/SeoDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/SeoDataMapper.php @@ -13,36 +13,21 @@ namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface; class SeoDataMapper implements DataMapperInterface { public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$unlocalizedObject instanceof SeoInterface) { - return; - } - - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - if ($localizedObject) { - if (!$localizedObject instanceof SeoInterface) { - throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', SeoInterface::class, \get_class($localizedObject))); - } - - $this->setSeoData($localizedObject, $data); - + if (!$localizedDimensionContent instanceof SeoInterface) { return; } - $this->setSeoData($unlocalizedObject, $data); + $this->setSeoData($localizedDimensionContent, $data); } /** diff --git a/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapper.php index 040b3e11..4fcd7249 100644 --- a/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapper.php @@ -13,7 +13,7 @@ namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface; use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface; @@ -39,18 +39,17 @@ public function __construct(StructureMetadataFactoryInterface $factory, array $s } public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$unlocalizedObject instanceof TemplateInterface) { + if (!$localizedDimensionContent instanceof TemplateInterface + || !$unlocalizedDimensionContent instanceof TemplateInterface + ) { return; } - $type = $unlocalizedObject::getTemplateType(); + $type = $localizedDimensionContent::getTemplateType(); /** @var string|null $template */ $template = $data['template'] ?? null; @@ -63,31 +62,22 @@ public function map( throw new \RuntimeException('Expected "template" to be set in the data array.'); } - list($unlocalizedData, $localizedData) = $this->getTemplateData( + list($unlocalizedData, $localizedData, $hasAnyValue) = $this->getTemplateData( $data, $type, $template ); - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - if ($localizedObject) { - if (!$localizedObject instanceof TemplateInterface) { - throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', TemplateInterface::class, \get_class($localizedObject))); - } - - $localizedObject->setTemplateKey($template); - $localizedObject->setTemplateData($localizedData); + if (!isset($data['template']) && !$hasAnyValue) { + // do nothing when no data was given + return; } - if (!$localizedObject) { - // Only set templateKey to unlocalizedDimension when no localizedDimension exist - $unlocalizedObject->setTemplateKey($template); - } + $localizedDimensionContent->setTemplateKey($template); + $localizedDimensionContent->setTemplateData($localizedData); - // Unlocalized dimensions can contain data of different templates so we need to merge them together - $unlocalizedObject->setTemplateData(\array_merge( - $unlocalizedObject->getTemplateData(), + $unlocalizedDimensionContent->setTemplateData(\array_merge( + $unlocalizedDimensionContent->getTemplateData(), $unlocalizedData )); } @@ -95,7 +85,11 @@ public function map( /** * @param mixed[] $data * - * @return mixed[] + * @return array{ + * 0: mixed[], + * 1: mixed[], + * 2: bool, + * } */ private function getTemplateData(array $data, string $type, string $template): array { @@ -107,6 +101,7 @@ private function getTemplateData(array $data, string $type, string $template): a $unlocalizedData = []; $localizedData = []; + $hasAnyValue = false; foreach ($metadata->getProperties() as $property) { $value = null; @@ -118,6 +113,7 @@ private function getTemplateData(array $data, string $type, string $template): a } if (\array_key_exists($name, $data)) { + $hasAnyValue = true; $value = $data[$name]; } @@ -129,6 +125,6 @@ private function getTemplateData(array $data, string $type, string $template): a $unlocalizedData[$name] = $value; } - return [$unlocalizedData, $localizedData]; + return [$unlocalizedData, $localizedData, $hasAnyValue]; } } diff --git a/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapper.php b/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapper.php index 36cffc34..61f83182 100644 --- a/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapper.php +++ b/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapper.php @@ -13,40 +13,25 @@ namespace Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\WorkflowInterface; class WorkflowDataMapper implements DataMapperInterface { public function map( - array $data, - DimensionContentCollectionInterface $dimensionContentCollection + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data ): void { - $dimensionAttributes = $dimensionContentCollection->getDimensionAttributes(); - $unlocalizedDimensionAttributes = \array_merge($dimensionAttributes, ['locale' => null]); - $unlocalizedObject = $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes); - - if (!$unlocalizedObject instanceof WorkflowInterface) { - return; - } - - $localizedObject = $dimensionContentCollection->getDimensionContent($dimensionAttributes); - - if ($localizedObject) { - if (!$localizedObject instanceof WorkflowInterface) { - throw new \RuntimeException(\sprintf('Expected "$localizedObject" from type "%s" but "%s" given.', WorkflowInterface::class, \get_class($localizedObject))); - } - - $this->setWorkflowData($localizedObject, $data); - + if (!$localizedDimensionContent instanceof WorkflowInterface) { return; } - $this->setWorkflowData($unlocalizedObject, $data); + $this->setWorkflowData($localizedDimensionContent, $data); } /** + * @param WorkflowInterface&DimensionContentInterface $object * @param mixed[] $data */ private function setWorkflowData(WorkflowInterface $object, array $data): void @@ -56,6 +41,7 @@ private function setWorkflowData(WorkflowInterface $object, array $data): void } /** + * @param WorkflowInterface&DimensionContentInterface $object * @param mixed[] $data */ private function setInitialPlaceToDraftDimension(WorkflowInterface $object, array $data): void @@ -64,8 +50,7 @@ private function setInitialPlaceToDraftDimension(WorkflowInterface $object, arra // after the place was set by this mapper initially, the place should only be changed by the ContentWorkflow // see: https://github.com/sulu/SuluContentBundle/issues/92 - if (!$object instanceof DimensionContentInterface - || DimensionContentInterface::STAGE_DRAFT !== $object->getStage()) { + if (DimensionContentInterface::STAGE_DRAFT !== $object->getStage()) { return; } @@ -76,6 +61,7 @@ private function setInitialPlaceToDraftDimension(WorkflowInterface $object, arra } /** + * @param WorkflowInterface&DimensionContentInterface $object * @param mixed[] $data */ private function setPublishedToLiveDimension(WorkflowInterface $object, array $data): void @@ -83,8 +69,7 @@ private function setPublishedToLiveDimension(WorkflowInterface $object, array $d // the published property of the draft dimension should only be changed by a ContentWorkflow subscriber // therefore we only want to copy the published property from the draft to the live dimension - if (!$object instanceof DimensionContentInterface - || DimensionContentInterface::STAGE_LIVE !== $object->getStage()) { + if (DimensionContentInterface::STAGE_LIVE !== $object->getStage()) { return; } diff --git a/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactory.php b/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactory.php index d9dd7f81..18964c14 100644 --- a/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactory.php +++ b/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactory.php @@ -99,7 +99,7 @@ public function create( $dimensionContentCollection->getDimensionContentClass() ); - $this->contentDataMapper->map($data, $dimensionContentCollection); + $this->contentDataMapper->map($dimensionContentCollection, $dimensionAttributes, $data); return $dimensionContentCollection; } diff --git a/Content/Infrastructure/Sulu/Preview/ContentObjectProvider.php b/Content/Infrastructure/Sulu/Preview/ContentObjectProvider.php index 56c257d4..5a07d5ee 100644 --- a/Content/Infrastructure/Sulu/Preview/ContentObjectProvider.php +++ b/Content/Infrastructure/Sulu/Preview/ContentObjectProvider.php @@ -102,7 +102,11 @@ public function getId($object) public function setValues($object, $locale, array $data): void { $previewDimensionContentCollection = new PreviewDimensionContentCollection($object, $locale); - $this->contentDataMapper->map($data, $previewDimensionContentCollection); + $this->contentDataMapper->map( + $previewDimensionContentCollection, + $previewDimensionContentCollection->getDimensionAttributes(), + $data + ); } /** diff --git a/Resources/config/data-mapper.xml b/Resources/config/data-mapper.xml index 87ba3465..3d68c42d 100644 --- a/Resources/config/data-mapper.xml +++ b/Resources/config/data-mapper.xml @@ -36,7 +36,6 @@ - %sulu.content.structure.default_types% %sulu_route.mappings% diff --git a/Tests/Application/ExampleTestBundle/Entity/ExampleDimensionContent.php b/Tests/Application/ExampleTestBundle/Entity/ExampleDimensionContent.php index 46891199..36a6d439 100644 --- a/Tests/Application/ExampleTestBundle/Entity/ExampleDimensionContent.php +++ b/Tests/Application/ExampleTestBundle/Entity/ExampleDimensionContent.php @@ -37,7 +37,6 @@ class ExampleDimensionContent implements DimensionContentInterface, ExcerptInter use RoutableTrait; use SeoTrait; use TemplateTrait { - getTemplateData as parentGetTemplateData; setTemplateData as parentSetTemplateData; } use WorkflowTrait; @@ -77,23 +76,12 @@ public function getTitle(): ?string return $this->title; } - public function setTitle(?string $title): void - { - $this->title = $title; - } - - public function getTemplateData(): array - { - $data = $this->parentGetTemplateData(); - $data['title'] = $this->getTitle(); - - return $data; - } - public function setTemplateData(array $templateData): void { - $this->setTitle($templateData['title']); - unset($templateData['title']); + if (\array_key_exists('title', $templateData)) { + $this->title = $templateData['title'] ?? null; + } + $this->parentSetTemplateData($templateData); } diff --git a/Tests/Functional/Integration/ExampleControllerTest.php b/Tests/Functional/Integration/ExampleControllerTest.php index a8bda539..cfeac399 100644 --- a/Tests/Functional/Integration/ExampleControllerTest.php +++ b/Tests/Functional/Integration/ExampleControllerTest.php @@ -194,6 +194,9 @@ public function testPut(int $id): void $response = $this->client->getResponse(); + $routeRepository = $this->getContainer()->get('sulu.repository.route'); + $this->assertCount(0, $routeRepository->findAll()); + $this->assertResponseSnapshot('example_put.json', $response, 200); } diff --git a/Tests/Functional/Traits/CreateExampleTrait.php b/Tests/Functional/Traits/CreateExampleTrait.php index d28688be..102ba8f7 100644 --- a/Tests/Functional/Traits/CreateExampleTrait.php +++ b/Tests/Functional/Traits/CreateExampleTrait.php @@ -56,7 +56,6 @@ public function createExampleContent(Example $example, array $data = []): void $localizedDimensionContent = $example->createDimensionContent(); $localizedDimensionContent->setLocale($locale); $localizedDimensionContent->setStage($stage); - $localizedDimensionContent->setTitle($data['title'] ?? null); $templateKey = $data['templateKey'] ?? null; if ($templateKey) { diff --git a/Tests/Traits/CreateExampleTrait.php b/Tests/Traits/CreateExampleTrait.php index 759d1152..cc923078 100644 --- a/Tests/Traits/CreateExampleTrait.php +++ b/Tests/Traits/CreateExampleTrait.php @@ -97,7 +97,11 @@ protected static function createExample(array $dataSet = [], array $options = [] ['stage' => DimensionContentInterface::STAGE_DRAFT, 'locale' => $locale], ExampleDimensionContent::class ); - $contentDataMapper->map($fillWithdefaultData($draftData), $draftDimensionContentCollection); + $contentDataMapper->map( + $draftDimensionContentCollection, + $draftDimensionContentCollection->getDimensionAttributes(), + $fillWithdefaultData($draftData) + ); $draftLocalizedDimension->setWorkflowPlace(WorkflowInterface::WORKFLOW_PLACE_DRAFT); if ($liveData) { @@ -134,7 +138,11 @@ protected static function createExample(array $dataSet = [], array $options = [] ExampleDimensionContent::class ); $liveData['published'] = \date('Y-m-d H:i:s'); - $contentDataMapper->map($fillWithdefaultData($liveData), $liveDimensionContentCollection); + $contentDataMapper->map( + $liveDimensionContentCollection, + $liveDimensionContentCollection->getDimensionAttributes(), + $fillWithdefaultData($liveData) + ); if ($options['create_route'] ?? false) { $route = new Route(); diff --git a/Tests/Traits/SetGetPrivatePropertyTrait.php b/Tests/Traits/SetGetPrivatePropertyTrait.php new file mode 100644 index 00000000..65824b77 --- /dev/null +++ b/Tests/Traits/SetGetPrivatePropertyTrait.php @@ -0,0 +1,41 @@ +getProperty($propertyName); + $propertyReflection->setAccessible(true); + + return $propertyReflection->getValue($object); + } + + /** + * @param mixed $value + */ + protected static function setPrivateProperty(object $object, string $propertyName, $value): void + { + $reflection = new \ReflectionClass($object); + $propertyReflection = $reflection->getProperty($propertyName); + $propertyReflection->setAccessible(true); + + $propertyReflection->setValue($object, $value); + } +} diff --git a/Tests/Unit/Content/Application/ContentDataMapper/ContentDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/ContentDataMapperTest.php index 68567063..25362af1 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/ContentDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/ContentDataMapperTest.php @@ -18,6 +18,7 @@ use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\ContentDataMapperInterface; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\DataMapperInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; +use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; class ContentDataMapperTest extends TestCase { @@ -40,12 +41,46 @@ public function testMap(): void $dataMapper2->reveal(), ]); + $unlocalizedDimensionAttributes = ['stage' => 'draft', 'locale' => null]; + $localizedDimensionAttributes = ['stage' => 'draft', 'locale' => 'en']; + $data = ['test-key' => 'test-value']; $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); + $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes) + ->willReturn($unlocalizedDimensionContent->reveal()) + ->shouldBeCalled(); + $dimensionContentCollection->getDimensionContent($localizedDimensionAttributes) + ->willReturn($localizedDimensionContent->reveal()) + ->shouldBeCalled(); + + $dataMapper1->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data) + ->shouldBeCalled(); + $dataMapper2->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data) + ->shouldBeCalled(); - $dataMapper1->map($data, $dimensionContentCollection->reveal())->shouldBeCalled(); - $dataMapper2->map($data, $dimensionContentCollection->reveal())->shouldBeCalled(); + $contentDataMapper->map($dimensionContentCollection->reveal(), $localizedDimensionAttributes, $data); + } + + public function testMapNoLocalized(): void + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Create unlocalized and localized dimension content.'); + + $unlocalizedDimensionAttributes = ['stage' => 'draft', 'locale' => null]; + $localizedDimensionAttributes = ['stage' => 'draft', 'locale' => 'en']; + + $data = ['test-key' => 'test-value']; + $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); + $dimensionContentCollection->getDimensionContent($unlocalizedDimensionAttributes) + ->willReturn(null) + ->shouldBeCalled(); + $dimensionContentCollection->getDimensionContent($localizedDimensionAttributes) + ->willReturn(null) + ->shouldBeCalled(); - $contentDataMapper->map($data, $dimensionContentCollection->reveal()); + $contentDataMapper = $this->createContentDataMapperInstance([]); + $contentDataMapper->map($dimensionContentCollection->reveal(), $localizedDimensionAttributes, $data); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapperTest.php index d6352db0..f578c267 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/AuthorDataMapperTest.php @@ -13,24 +13,34 @@ namespace Sulu\Bundle\ContentBundle\Tests\Unit\Content\Application\ContentDataMapper\DataMapper; -use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Prophecy\Argument; -use Sulu\Bundle\ContactBundle\Entity\ContactInterface; +use Prophecy\Prophecy\ObjectProphecy; +use Sulu\Bundle\ContactBundle\Entity\Contact; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\AuthorDataMapper; use Sulu\Bundle\ContentBundle\Content\Domain\Factory\ContactFactoryInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\AuthorInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; class AuthorDataMapperTest extends TestCase { - protected function createAuthorDataMapperInstance(ContactFactoryInterface $contactFactory): AuthorDataMapper + /** + * @var ObjectProphecy|ContactFactoryInterface + */ + private $contactFactory; + + protected function setUp(): void + { + $this->contactFactory = $this->prophesize(ContactFactoryInterface::class); + } + + protected function createAuthorDataMapperInstance(): AuthorDataMapper { - return new AuthorDataMapper($contactFactory); + return new AuthorDataMapper($this->contactFactory->reveal()); } - public function testMapNoAuthor(): void + public function testMapNoAuthorInterface(): void { $data = [ 'author' => 1, @@ -38,123 +48,56 @@ public function testMapNoAuthor(): void ]; $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes() - ->shouldBeCalled() - ->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->shouldBeCalled() - ->willReturn($unlocalizedDimensionContent); + $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); $contactFactory = $this->prophesize(ContactFactoryInterface::class); + $contactFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $authorMapper = $this->createAuthorDataMapperInstance($contactFactory->reveal()); - $authorMapper->map($data, $dimensionContentCollection->reveal()); + $authorMapper = $this->createAuthorDataMapperInstance(); + $authorMapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); } - public function testMapLocalizedNoAuthor(): void + public function testMapAuthorNoData(): void { - $data = [ - 'author' => 1, - 'authored' => '2020-05-08T00:00:00+00:00', - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(AuthorInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $data = []; - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes() - ->shouldBeCalled() - ->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent->reveal()); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $contactFactory = $this->prophesize(ContactFactoryInterface::class); + $this->contactFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Expected "$localizedObject" from type "Sulu\Bundle\ContentBundle\Content\Domain\Model\AuthorInterface" but "Double\DimensionContentInterface\P3" given.'); + $authorMapper = $this->createAuthorDataMapperInstance(); + $authorMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $authorMapper = $this->createAuthorDataMapperInstance($contactFactory->reveal()); - $authorMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($localizedDimensionContent->getAuthor()); + $this->assertNull($localizedDimensionContent->getAuthored()); } - public function testMapUnlocalizedAuthor(): void + public function testMapData(): void { $data = [ 'author' => 1, 'authored' => '2020-05-08T00:00:00+00:00', ]; - $contact = $this->prophesize(ContactInterface::class); - $contactFactory = $this->prophesize(ContactFactoryInterface::class); - $contactFactory->create(1) - ->shouldBeCalled() - ->willReturn($contact->reveal()); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(AuthorInterface::class); - - $unlocalizedDimensionContent->setAuthor($contact->reveal()) - ->shouldBeCalled(); - $unlocalizedDimensionContent->setAuthored(Argument::that( - function(DateTimeImmutable $date) { - return $date->getTimestamp() === (new \DateTimeImmutable('2020-05-08T00:00:00+00:00'))->getTimestamp(); - }) - )->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes() - ->shouldBeCalled() - ->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent->reveal()); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $authorMapper = $this->createAuthorDataMapperInstance($contactFactory->reveal()); - $authorMapper->map($data, $dimensionContentCollection->reveal()); - } + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - public function testMapLocalizedAuthor(): void - { - $data = [ - 'author' => 1, - 'authored' => '2020-05-08T00:00:00+00:00', - ]; - $contact = $this->prophesize(ContactInterface::class); - $contactFactory = $this->prophesize(ContactFactoryInterface::class); - $contactFactory->create(1) + $contact = new Contact(); + $this->contactFactory->create(1) ->shouldBeCalled() - ->willReturn($contact->reveal()); + ->willReturn($contact); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(AuthorInterface::class); + $authorMapper = $this->createAuthorDataMapperInstance(); + $authorMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(AuthorInterface::class); - - $localizedDimensionContent->setAuthor($contact->reveal()) - ->shouldBeCalled(); - $localizedDimensionContent->setAuthored(Argument::that( - function(DateTimeImmutable $date) { - return $date->getTimestamp() === (new \DateTimeImmutable('2020-05-08T00:00:00+00:00'))->getTimestamp(); - }) - )->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes() - ->shouldBeCalled() - ->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent->reveal()); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent->reveal()); - - $authorMapper = $this->createAuthorDataMapperInstance($contactFactory->reveal()); - $authorMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame($contact, $localizedDimensionContent->getAuthor()); + $authored = $localizedDimensionContent->getAuthored(); + $this->assertNotNull($authored); + $this->assertSame('2020-05-08T00:00:00+00:00', $authored->format('c')); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapperTest.php index 8cbe5e5e..3c4696a4 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/ExcerptDataMapperTest.php @@ -14,54 +14,42 @@ namespace Sulu\Bundle\ContentBundle\Tests\Unit\Content\Application\ContentDataMapper\DataMapper; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Prophecy\Prophecy\ObjectProphecy; +use Sulu\Bundle\CategoryBundle\Entity\Category; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\ExcerptDataMapper; use Sulu\Bundle\ContentBundle\Content\Domain\Factory\CategoryFactoryInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Factory\TagFactoryInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\ExcerptInterface; -use Sulu\Bundle\TagBundle\Tag\TagInterface; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; +use Sulu\Bundle\TagBundle\Entity\Tag; class ExcerptDataMapperTest extends TestCase { - protected function createExcerptDataMapperInstance( - TagFactoryInterface $tagFactory, - CategoryFactoryInterface $categoryFactory - ): ExcerptDataMapper { - return new ExcerptDataMapper($tagFactory, $categoryFactory); - } - - public function testMapUnlocalizedNoExcerpt(): void - { - $data = [ - 'excerptTitle' => 'Excerpt Title', - 'excerptDescription' => 'Excerpt Description', - 'excerptMore' => 'Excerpt More', - 'excerptImage' => ['id' => 1], - 'excerptIcon' => ['id' => 2], - 'excerptTags' => ['Tag 1', 'Tag 2'], - 'excerptCategories' => [3, 4], - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + /** + * @var ObjectProphecy|TagFactoryInterface + */ + private $tagFactory; - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); + /** + * @var ObjectProphecy|CategoryFactoryInterface + */ + private $categoryFactory; - $tagFactory = $this->prophesize(TagFactoryInterface::class); - $categoryFactory = $this->prophesize(CategoryFactoryInterface::class); - - $excerptMapper = $this->createExcerptDataMapperInstance($tagFactory->reveal(), $categoryFactory->reveal()); - $excerptMapper->map($data, $dimensionContentCollection->reveal()); - $this->assertTrue(true); // Avoid risky test as this is an early return test + protected function setUp(): void + { + $this->tagFactory = $this->prophesize(TagFactoryInterface::class); + $this->categoryFactory = $this->prophesize(CategoryFactoryInterface::class); } - public function testMapLocalizedNoExcerpt(): void + protected function createExcerptDataMapperInstance(): ExcerptDataMapper { - $this->expectException(\RuntimeException::class); + return new ExcerptDataMapper($this->tagFactory->reveal(), $this->categoryFactory->reveal()); + } + public function testMapNoExcerptInterface(): void + { $data = [ 'excerptTitle' => 'Excerpt Title', 'excerptDescription' => 'Excerpt Description', @@ -73,71 +61,44 @@ public function testMapLocalizedNoExcerpt(): void ]; $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(ExcerptInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $tagFactory = $this->prophesize(TagFactoryInterface::class); - $categoryFactory = $this->prophesize(CategoryFactoryInterface::class); + $this->tagFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $excerptMapper = $this->createExcerptDataMapperInstance($tagFactory->reveal(), $categoryFactory->reveal()); + $this->categoryFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $excerptMapper->map($data, $dimensionContentCollection->reveal()); + $excerptMapper = $this->createExcerptDataMapperInstance(); + $excerptMapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); } - public function testMapUnlocalizedExcerpt(): void + public function testMapNoData(): void { - $data = [ - 'excerptTitle' => 'Excerpt Title', - 'excerptDescription' => 'Excerpt Description', - 'excerptMore' => 'Excerpt More', - 'excerptImage' => ['id' => 1], - 'excerptIcon' => ['id' => 2], - 'excerptTags' => ['Tag 1', 'Tag 2'], - 'excerptCategories' => [3, 4], - ]; + $data = []; - $tag1 = $this->prophesize(TagInterface::class); - $tag2 = $this->prophesize(TagInterface::class); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $tagFactory = $this->prophesize(TagFactoryInterface::class); - $tagFactory->create(['Tag 1', 'Tag 2'])->willReturn([$tag1->reveal(), $tag2->reveal()])->shouldBeCalled(); + $this->tagFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $categoryFactory = $this->prophesize(CategoryFactoryInterface::class); - $category1 = $this->prophesize(TagInterface::class); - $category2 = $this->prophesize(TagInterface::class); - $categoryFactory->create([3, 4])->willReturn([$category1->reveal(), $category2->reveal()])->shouldBeCalled(); + $this->categoryFactory->create(Argument::any()) + ->shouldNotBeCalled(); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(ExcerptInterface::class); - $unlocalizedDimensionContent->setExcerptTitle('Excerpt Title')->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptDescription('Excerpt Description')->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptMore('Excerpt More')->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptImage(['id' => 1])->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptIcon(['id' => 2])->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptTags([$tag1->reveal(), $tag2->reveal()])->shouldBeCalled(); - $unlocalizedDimensionContent->setExcerptCategories([$category1->reveal(), $category2->reveal()])->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $excerptMapper = $this->createExcerptDataMapperInstance($tagFactory->reveal(), $categoryFactory->reveal()); - - $excerptMapper->map($data, $dimensionContentCollection->reveal()); + $excerptMapper = $this->createExcerptDataMapperInstance(); + $excerptMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); + + $this->assertNull($localizedDimensionContent->getExcerptTitle()); + $this->assertNull($localizedDimensionContent->getExcerptDescription()); + $this->assertNull($localizedDimensionContent->getExcerptIcon()); + $this->assertNull($localizedDimensionContent->getExcerptImage()); + $this->assertCount(0, $localizedDimensionContent->getExcerptTagNames()); + $this->assertCount(0, $localizedDimensionContent->getExcerptCategoryIds()); } - public function testMapLocalizedExcerpt(): void + public function testMapUnlocalizedExcerpt(): void { $data = [ 'excerptTitle' => 'Excerpt Title', @@ -149,39 +110,31 @@ public function testMapLocalizedExcerpt(): void 'excerptCategories' => [3, 4], ]; - $tag1 = $this->prophesize(TagInterface::class); - $tag2 = $this->prophesize(TagInterface::class); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $tagFactory = $this->prophesize(TagFactoryInterface::class); - $tagFactory->create(['Tag 1', 'Tag 2'])->willReturn([$tag1->reveal(), $tag2->reveal()])->shouldBeCalled(); + $tag1 = new Tag(); + $tag1->setName('Tag 1'); + $tag2 = new Tag(); + $tag2->setName('Tag 2'); - $categoryFactory = $this->prophesize(CategoryFactoryInterface::class); - $category1 = $this->prophesize(TagInterface::class); - $category2 = $this->prophesize(TagInterface::class); - $categoryFactory->create([3, 4])->willReturn([$category1->reveal(), $category2->reveal()])->shouldBeCalled(); + $this->tagFactory->create(['Tag 1', 'Tag 2'])->willReturn([$tag1, $tag2])->shouldBeCalled(); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(ExcerptInterface::class); + $category1 = new Category(); + $category1->setId(3); + $category2 = new Category(); + $category2->setId(4); + $this->categoryFactory->create([3, 4])->willReturn([$category1, $category2])->shouldBeCalled(); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(ExcerptInterface::class); - $localizedDimensionContent->setExcerptTitle('Excerpt Title')->shouldBeCalled(); - $localizedDimensionContent->setExcerptDescription('Excerpt Description')->shouldBeCalled(); - $localizedDimensionContent->setExcerptMore('Excerpt More')->shouldBeCalled(); - $localizedDimensionContent->setExcerptImage(['id' => 1])->shouldBeCalled(); - $localizedDimensionContent->setExcerptIcon(['id' => 2])->shouldBeCalled(); - $localizedDimensionContent->setExcerptTags([$tag1->reveal(), $tag2->reveal()])->shouldBeCalled(); - $localizedDimensionContent->setExcerptCategories([$category1->reveal(), $category2->reveal()])->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $excerptMapper = $this->createExcerptDataMapperInstance($tagFactory->reveal(), $categoryFactory->reveal()); - - $excerptMapper->map($data, $dimensionContentCollection->reveal()); + $excerptMapper = $this->createExcerptDataMapperInstance(); + $excerptMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); + + $this->assertSame('Excerpt Title', $localizedDimensionContent->getExcerptTitle()); + $this->assertSame('Excerpt Description', $localizedDimensionContent->getExcerptDescription()); + $this->assertSame(['id' => 1], $localizedDimensionContent->getExcerptImage()); + $this->assertSame(['id' => 2], $localizedDimensionContent->getExcerptIcon()); + $this->assertSame(['Tag 1', 'Tag 2'], $localizedDimensionContent->getExcerptTagNames()); + $this->assertSame([3, 4], $localizedDimensionContent->getExcerptCategoryIds()); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapperTest.php index dfb4eabd..7a8afabe 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/RoutableDataMapperTest.php @@ -17,144 +17,94 @@ use Prophecy\Argument; use Prophecy\Prophecy\ObjectProphecy; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\RoutableDataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\RoutableInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\DimensionContentMockWrapperTrait; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\MockWrapper; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\RoutableMockWrapperTrait; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\TemplateMockWrapperTrait; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; +use Sulu\Bundle\ContentBundle\Tests\Traits\SetGetPrivatePropertyTrait; +use Sulu\Bundle\RouteBundle\Entity\Route; use Sulu\Bundle\RouteBundle\Generator\RouteGeneratorInterface; -use Sulu\Bundle\RouteBundle\Manager\ConflictResolverInterface; use Sulu\Bundle\RouteBundle\Manager\RouteManagerInterface; -use Sulu\Bundle\RouteBundle\Model\RouteInterface; use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface; use Sulu\Component\Content\Metadata\PropertyMetadata; use Sulu\Component\Content\Metadata\StructureMetadata; class RoutableDataMapperTest extends TestCase { + use SetGetPrivatePropertyTrait; + + /** + * @var ObjectProphecy|StructureMetadataFactoryInterface + */ + private $structureMetadataFactory; + + /** + * @var ObjectProphecy|RouteGeneratorInterface + */ + private $routeGenerator; + + /** + * @var ObjectProphecy|RouteManagerInterface + */ + private $routeManager; + + protected function setUp(): void + { + $this->structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); + $this->routeGenerator = $this->prophesize(RouteGeneratorInterface::class); + $this->routeManager = $this->prophesize(RouteManagerInterface::class); + } + /** * @param array $structureDefaultTypes * @param array> $resourceKeyMappings */ protected function createRouteDataMapperInstance( - StructureMetadataFactoryInterface $factory, - RouteGeneratorInterface $routeGenerator, - RouteManagerInterface $routeManager, - ConflictResolverInterface $conflictResolver, array $structureDefaultTypes = [], - array $resourceKeyMappings = [] + ?array $resourceKeyMappings = null ): RoutableDataMapper { - if (empty($resourceKeyMappings)) { + if (!\is_array($resourceKeyMappings)) { $resourceKeyMappings = [ - 'mock-resource-key' => [ + 'examples' => [ 'generator' => 'schema', 'options' => [ 'route_schema' => '/{object["title"]}', ], - 'resource_key' => 'mock-resource-key', - 'entityClass' => 'mock-content-class', + 'resource_key' => 'examples', + 'entityClass' => Example::class, ], ]; } - return new RoutableDataMapper($factory, $routeGenerator, $routeManager, $conflictResolver, $structureDefaultTypes, $resourceKeyMappings); - } - - /** - * @param ObjectProphecy $routableMock - */ - protected function wrapRoutableMock(ObjectProphecy $routableMock): RoutableInterface - { - return new class($routableMock) extends MockWrapper implements - DimensionContentInterface, - TemplateInterface, - RoutableInterface { - use DimensionContentMockWrapperTrait, RoutableMockWrapperTrait { - RoutableMockWrapperTrait::getLocale insteadof DimensionContentMockWrapperTrait; - RoutableMockWrapperTrait::getResourceKey insteadof DimensionContentMockWrapperTrait; - } - use TemplateMockWrapperTrait; - }; - } - - public function testMapNoRoutable(): void - { - $data = []; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $factory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - - $routeGenerator->generate(Argument::cetera()) - ->shouldNotBeCalled(); - - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() + return new RoutableDataMapper( + $this->structureMetadataFactory->reveal(), + $this->routeGenerator->reveal(), + $this->routeManager->reveal(), + $structureDefaultTypes, + $resourceKeyMappings ); - - $mapper->map($data, $dimensionContentCollection->reveal()); } - public function testMapNoLocalizedDimension(): void + public function testMapNoRoutableInterface(): void { $data = []; $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $factory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - - $routeGenerator->generate(Argument::cetera()) + $this->structureMetadataFactory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); - - $mapper->map($data, $dimensionContentCollection->reveal()); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); } public function testMapNoTemplateInterface(): void { $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('LocalizedObject needs to extend the TemplateInterface'); + $this->expectExceptionMessage('LocalizedDimensionContent needs to extend the TemplateInterface.'); $data = []; @@ -163,76 +113,32 @@ public function testMapNoTemplateInterface(): void $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); $localizedDimensionContent->willImplement(RoutableInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $factory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->getResourceId()->shouldNotBeCalled(); - - $routeGenerator->generate(Argument::cetera()) - ->shouldNotBeCalled(); - - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); - - $mapper->map($data, $dimensionContentCollection->reveal()); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); } - public function testMapNoTemplate(): void + public function testMapNoTemplateGiven(): void { $this->expectException(\RuntimeException::class); $data = []; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $factory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->getResourceId()->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $routeGenerator->generate(Argument::cetera()) + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); + + $this->structureMetadataFactory->getStructureMetadata(Argument::cetera())->shouldNotBeCalled(); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance([], []); + + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } public function testMapNoMetadata(): void @@ -241,40 +147,23 @@ public function testMapNoMetadata(): void 'template' => 'default', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn(null)->shouldBeCalled(); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); - $routeGenerator->generate(Argument::cetera()) + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn(null); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } public function testMapNoRouteProperty(): void @@ -283,515 +172,389 @@ public function testMapNoRouteProperty(): void 'template' => 'default', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createTextLineStructureMetadata()); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('text_line'); - $property->getName()->willReturn('url'); - - $metadata->getProperties()->WillReturn([$property->reveal()]); - - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getLocale()->willReturn('de'); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); - - $routeGenerator->generate(Argument::cetera()) + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } - public function testMapNoRoutePropertyData(): void + public function testMapNoLocale(): void { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Expected a LocalizedDimensionContent with a locale.'); + $data = [ 'template' => 'default', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); + } - $metadata->getProperties()->WillReturn([$property->reveal()]); + public function testMapNoRoutePropertyValue(): void + { + // see https://github.com/sulu/SuluContentBundle/pull/55 + $this->markTestSkipped( + 'This is currently handled the same way as "testMapNoNewAndOldUrl". But should be handle differently to avoid patch creates.' + ); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getTemplateData()->willReturn(['url' => '/test']); - $localizedDimensionContent->getLocale()->willReturn('de'); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + /** @phpstan-ignore-next-line */ + $data = [ + 'template' => 'default', + ]; - $routeGenerator->generate(Argument::cetera()) + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); + + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); + + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } - public function testMapNoRoutePropertyDataAndNoOldRoute(): void + public function testMapNoRouteMapping(): void { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('No route mapping found for "examples".'); + $data = [ 'template' => 'default', + 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContentMock = $this->wrapRoutableMock($localizedDimensionContent); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContentMock); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); - $metadata->getProperties()->WillReturn([$property->reveal()]); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getTemplateData()->willReturn([]); - $localizedDimensionContent->getLocale()->willReturn('en'); - $localizedDimensionContent->setTemplateData(['url' => '/test'])->shouldBeCalled(); - - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); - - $routeGenerator->generate( - \array_merge($data, [ - '_unlocalizedObject' => $unlocalizedDimensionContent->reveal(), - '_localizedObject' => $localizedDimensionContentMock, - ]), - ['route_schema' => '/{object["title"]}'] - )->willReturn('/test'); - - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/test'); - $routeManager->createOrUpdateByAttributes( - 'mock-content-class', - '123-123-123', - 'en', - '/test' - )->willReturn($route->reveal()); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['url' => '/test'])->shouldBeCalled(); + $mapper = $this->createRouteDataMapperInstance([], []); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); - - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } - public function testMapNoRoutePropertyDataAndNoOldRouteIgnoreSlash(): void + public function testMapNoResourceId(): void { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Expected a LocalizedDimensionContent with a resourceId.'); + $data = [ 'template' => 'default', + 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContentMock = $this->wrapRoutableMock($localizedDimensionContent); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContentMock); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); - - $metadata->getProperties()->WillReturn([$property->reveal()]); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getTemplateData()->willReturn([]); - $localizedDimensionContent->getLocale()->willReturn('en'); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $routeGenerator->generate( - \array_merge($data, [ - '_unlocalizedObject' => $unlocalizedDimensionContent->reveal(), - '_localizedObject' => $localizedDimensionContentMock, - ]), - ['route_schema' => '/{object["title"]}'] - )->willReturn('/'); - - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } - public function testMapNoContentId(): void + public function testMapRouteProperty(): void { $data = [ 'template' => 'default', + 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $route = new Route(); + $route->setPath('/test-1'); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - - $metadata->getProperties()->WillReturn([$property->reveal()]); - - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $this->routeManager->createOrUpdateByAttributes( + Example::class, + '1', + 'en', + '/test', + true + ) + ->shouldBeCalled() + ->willReturn($route); - $localizedDimensionContent->getResourceId()->willReturn(null); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/test-1', + ], $localizedDimensionContent->getTemplateData()); } - public function testMapNoLocale(): void + public function testMapRouteDraftDimension(): void { $data = [ 'template' => 'default', + 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $routeManager->createOrUpdateByAttributes(Argument::cetera())->shouldNotBeCalled(); - $conflictResolver->resolve(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - - $metadata->getProperties()->WillReturn([$property->reveal()]); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera()) + ->shouldNotBeCalled(); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getLocale()->willReturn(null); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); - - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/test', + ], $localizedDimensionContent->getTemplateData()); } - public function testMapNoRoutePath(): void + public function testMapNoNewAndOldUrl(): void { $data = [ 'template' => 'default', - 'url' => null, ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContentMock = $this->wrapRoutableMock($localizedDimensionContent); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContentMock); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); + $route = new Route(); + $route->setPath('/test'); - $metadata->getProperties()->WillReturn([$property->reveal()]); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getTemplateData()->willReturn(['title' => 'Test', 'url' => null]); - $localizedDimensionContent->getLocale()->willReturn('en'); + $this->routeGenerator->generate(Argument::cetera())->willReturn('/test'); - $routeGenerator->generate( - \array_merge($data, [ - '_unlocalizedObject' => $unlocalizedDimensionContent->reveal(), - '_localizedObject' => $localizedDimensionContentMock, - ]), - ['route_schema' => '/{object["title"]}'] - )->willReturn('/test'); - - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/test'); - $routeManager->createOrUpdateByAttributes( - 'mock-content-class', - '123-123-123', + $this->routeManager->createOrUpdateByAttributes( + Example::class, + '1', 'en', - '/test' - )->willReturn($route->reveal()); + '/test', + true + ) + ->shouldBeCalled() + ->willReturn($route); - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['title' => 'Test', 'url' => '/test'])->shouldBeCalled(); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); - - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/test', + ], $localizedDimensionContent->getTemplateData()); } - public function testMap(): void + public function testMapWithNoUrlButOldUrl(): void { $data = [ 'template' => 'default', - 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); - - $metadata->getProperties()->WillReturn([$property->reveal()]); - - $localizedDimensionContent->getTemplateData()->willReturn([]); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $route = new Route(); + $route->setPath('/test-1'); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getLocale()->willReturn('en'); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); + $localizedDimensionContent->setTemplateData(['url' => '/example']); - $routeGenerator->generate(Argument::any())->shouldNotBeCalled(); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/test'); - $routeManager->createOrUpdateByAttributes( - 'mock-content-class', - '123-123-123', - 'en', - '/test' - )->willReturn($route->reveal()); + $this->routeManager->createOrUpdateByAttributes(Argument::cetera()) + ->shouldNotBeCalled(); - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/example', + ], $localizedDimensionContent->getTemplateData()); } - public function testMapConflictingRoute(): void + public function testMapGenerate(): void { $data = [ 'template' => 'default', - 'url' => '/test', + 'url' => null, ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); + $route = new Route(); + $route->setPath('/custom/testEntity-123'); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $example = new Example(); + static::setPrivateProperty($example, 'id', 123); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); + $localizedDimensionContent->setTemplateData(['title' => 'Test', 'url' => null]); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); + $this->routeGenerator->generate( + \array_merge($data, [ + '_unlocalizedObject' => $unlocalizedDimensionContent, + '_localizedObject' => $localizedDimensionContent, + ]), + ['route_schema' => 'custom/{object["_localizedObject"].getTitle()}-{object["_unlocalizedObject"].getResourceId()}'] + )->willReturn('/custom/testEntity-123'); - $metadata->getProperties()->WillReturn([$property->reveal()]); + $this->routeManager->createOrUpdateByAttributes( + Example::class, + '123', + 'en', + '/custom/testEntity-123', + true + ) + ->shouldBeCalled() + ->willReturn($route); + + $mapper = $this->createRouteDataMapperInstance([], [ + 'examples' => [ + 'generator' => 'schema', + 'options' => [ + 'route_schema' => 'custom/{object["_localizedObject"].getTitle()}-{object["_unlocalizedObject"].getResourceId()}', + ], + 'resource_key' => 'examples', + 'entityClass' => Example::class, + ], + ]); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); + + $this->assertSame([ + 'title' => 'Test', + 'url' => '/custom/testEntity-123', + ], $localizedDimensionContent->getTemplateData()); + } - $localizedDimensionContent->getTemplateData()->willReturn([]); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + public function testMapOnlySlash(): void + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Not allowed url "/" given or generated.'); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getLocale()->willReturn('en'); + $data = [ + 'template' => 'default', + 'url' => null, + ]; - $routeGenerator->generate(Argument::any())->shouldNotBeCalled(); + $route = new Route(); + $route->setPath('/custom/testEntity-123'); - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/test-1'); + $example = new Example(); + static::setPrivateProperty($example, 'id', 123); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setLocale('en'); + $localizedDimensionContent->setTemplateData(['title' => 'Test', 'url' => null]); - $routeManager->createOrUpdateByAttributes( - 'mock-content-class', - '123-123-123', - 'en', - '/test' - )->willReturn($route->reveal()); + $this->structureMetadataFactory->getStructureMetadata('example', 'default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['url' => '/test-1'])->shouldBeCalled(); + $this->routeGenerator->generate(Argument::cetera())->willReturn('/'); - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal() - ); + $mapper = $this->createRouteDataMapperInstance(); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/custom/testEntity-123', + 'title' => 'Test', + ], $localizedDimensionContent->getTemplateData()); } public function testMapNoTemplateWithDefaultTemplate(): void @@ -800,137 +563,69 @@ public function testMapNoTemplateWithDefaultTemplate(): void 'url' => '/test', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapRoutableMock($localizedDimensionContent)); + $route = new Route(); + $route->setPath('/test-1'); - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); + $example = new Example(); + static::setPrivateProperty($example, 'id', 1); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage('live'); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage('live'); + $localizedDimensionContent->setLocale('en'); - $metadata = $this->prophesize(StructureMetadata::class); - $property = $this->prophesize(PropertyMetadata::class); - $property->getType()->willReturn('route'); - $property->getName()->willReturn('url'); + $this->structureMetadataFactory->getStructureMetadata('example', 'new-default') + ->shouldBeCalled() + ->willReturn($this->createRouteStructureMetadata()); - $metadata->getProperties()->willReturn([$property->reveal()]); - - $localizedDimensionContent->getTemplateData()->willReturn([]); - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); - - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getLocale()->willReturn('en'); + $this->routeManager->createOrUpdateByAttributes( + Example::class, + '1', + 'en', + '/test', + true + ) + ->shouldBeCalled() + ->willReturn($route); - $routeGenerator->generate(Argument::any())->shouldNotBeCalled(); + $this->routeGenerator->generate(Argument::cetera()) + ->shouldNotBeCalled(); - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/test'); - $routeManager->createOrUpdateByAttributes( - 'mock-content-class', - '123-123-123', - 'en', - '/test' - )->willReturn($route->reveal()); - - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(Argument::cetera())->shouldNotBeCalled(); - - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal(), - ['mock-template-type' => 'default'] - ); + $mapper = $this->createRouteDataMapperInstance([ + 'example' => 'new-default', + ]); + $mapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $mapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame([ + 'url' => '/test-1', + ], $localizedDimensionContent->getTemplateData()); } - public function testMapCustomRoute(): void + private function createRouteStructureMetadata(): StructureMetadata { - $data = [ - 'template' => 'default', - 'url' => null, - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(RoutableInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContentMock = $this->wrapRoutableMock($localizedDimensionContent); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContentMock); - - $factory = $this->prophesize(StructureMetadataFactoryInterface::class); - $routeGenerator = $this->prophesize(RouteGeneratorInterface::class); - $routeManager = $this->prophesize(RouteManagerInterface::class); - $conflictResolver = $this->prophesize(ConflictResolverInterface::class); - - $metadata = $this->prophesize(StructureMetadata::class); $property = $this->prophesize(PropertyMetadata::class); $property->getType()->willReturn('route'); $property->getName()->willReturn('url'); - $metadata->getProperties()->WillReturn([$property->reveal()]); - - $factory->getStructureMetadata('mock-template-type', 'default')->willReturn($metadata->reveal())->shouldBeCalled(); + $structureMetadata = $this->prophesize(StructureMetadata::class); + $structureMetadata->getProperties()->willReturn([ + $property->reveal(), + ])->shouldBeCalled(); - $localizedDimensionContent->getResourceId()->willReturn('123-123-123'); - $localizedDimensionContent->getTemplateData()->willReturn(['title' => 'Test', 'url' => null]); - $localizedDimensionContent->getLocale()->willReturn('en'); + return $structureMetadata->reveal(); + } - $routeGenerator->generate( - \array_merge($data, [ - '_unlocalizedObject' => $unlocalizedDimensionContent->reveal(), - '_localizedObject' => $localizedDimensionContentMock, - ]), - ['route_schema' => 'custom/{object["_localizedObject"].getName()}-{object["_unlocalizedObject"].getResourceId()}'] - )->willReturn('/custom/testEntity-123'); + private function createTextLineStructureMetadata(): StructureMetadata + { + $property = $this->prophesize(PropertyMetadata::class); + $property->getType()->willReturn('text_line'); + $property->getName()->willReturn('url'); - $route = $this->prophesize(RouteInterface::class); - $route->getPath()->willReturn('/custom/testEntity-123'); - $routeManager->createOrUpdateByAttributes( - 'Sulu/Test/TestEntity', - '123-123-123', - 'en', - '/custom/testEntity-123' - )->willReturn($route->reveal()); - - $conflictResolver->resolve($route->reveal())->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['title' => 'Test', 'url' => '/custom/testEntity-123'])->shouldBeCalled(); - - $mapper = $this->createRouteDataMapperInstance( - $factory->reveal(), - $routeGenerator->reveal(), - $routeManager->reveal(), - $conflictResolver->reveal(), - [], - [ - 'mock-resource-key' => [ - 'generator' => 'schema', - 'options' => [ - 'route_schema' => 'custom/{object["_localizedObject"].getName()}-{object["_unlocalizedObject"].getResourceId()}', - ], - 'resource_key' => 'mock-resource-key', - 'entityClass' => 'Sulu/Test/TestEntity', - ], - ] - ); + $structureMetadata = $this->prophesize(StructureMetadata::class); + $structureMetadata->getProperties()->willReturn([ + $property->reveal(), + ])->shouldBeCalled(); - $mapper->map($data, $dimensionContentCollection->reveal()); + return $structureMetadata->reveal(); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/SeoDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/SeoDataMapperTest.php index 5976ead9..e6320535 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/SeoDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/SeoDataMapperTest.php @@ -15,9 +15,9 @@ use PHPUnit\Framework\TestCase; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\SeoDataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\SeoInterface; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; class SeoDataMapperTest extends TestCase { @@ -26,7 +26,7 @@ protected function createSeoDataMapperInstance(): SeoDataMapper return new SeoDataMapper(); } - public function testMapNoSeo(): void + public function testMapNoSeoInterface(): void { $data = [ 'seoTitle' => 'Seo Title', @@ -41,84 +41,33 @@ public function testMapNoSeo(): void $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - $seoMapper = $this->createSeoDataMapperInstance(); - $seoMapper->map($data, $dimensionContentCollection->reveal()); + $seoMapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); $this->assertTrue(true); // Avoid risky test as this is an early return test } - public function testMapLocalizedNoSeo(): void + public function testMapNoData(): void { - $this->expectException(\RuntimeException::class); - - $data = [ - 'seoTitle' => 'Seo Title', - 'seoDescription' => 'Seo Description', - 'seoKeywords' => 'Seo Keyword 1, Seo Keyword 2', - 'seoCanonicalUrl' => 'http://example.localhost', - 'seoHideInSitemap' => true, - 'seoNoIndex' => true, - 'seoNoFollow' => true, - ]; + $data = []; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(SeoInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); $seoMapper = $this->createSeoDataMapperInstance(); - $seoMapper->map($data, $dimensionContentCollection->reveal()); - } + $seoMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - public function testMapUnlocalizedSeo(): void - { - $data = [ - 'seoTitle' => 'Seo Title', - 'seoDescription' => 'Seo Description', - 'seoKeywords' => 'Seo Keyword 1, Seo Keyword 2', - 'seoCanonicalUrl' => 'http://example.localhost', - 'seoHideInSitemap' => true, - 'seoNoIndex' => true, - 'seoNoFollow' => true, - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(SeoInterface::class); - $unlocalizedDimensionContent->setSeoTitle('Seo Title')->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoDescription('Seo Description')->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoKeywords('Seo Keyword 1, Seo Keyword 2')->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoCanonicalUrl('http://example.localhost')->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoHideInSitemap(true)->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoNoIndex(true)->shouldBeCalled(); - $unlocalizedDimensionContent->setSeoNoFollow(true)->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $seoMapper = $this->createSeoDataMapperInstance(); - - $seoMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($localizedDimensionContent->getSeoTitle()); + $this->assertNull($localizedDimensionContent->getSeoDescription()); + $this->assertNull($localizedDimensionContent->getSeoKeywords()); + $this->assertNull($localizedDimensionContent->getSeoCanonicalUrl()); + $this->assertFalse($localizedDimensionContent->getSeoHideInSitemap()); + $this->assertFalse($localizedDimensionContent->getSeoNoFollow()); + $this->assertFalse($localizedDimensionContent->getSeoNoIndex()); } - public function testMapLocalizedSeo(): void + public function testMapData(): void { $data = [ 'seoTitle' => 'Seo Title', @@ -130,28 +79,20 @@ public function testMapLocalizedSeo(): void 'seoNoFollow' => true, ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(SeoInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(SeoInterface::class); - $localizedDimensionContent->setSeoTitle('Seo Title')->shouldBeCalled(); - $localizedDimensionContent->setSeoDescription('Seo Description')->shouldBeCalled(); - $localizedDimensionContent->setSeoKeywords('Seo Keyword 1, Seo Keyword 2')->shouldBeCalled(); - $localizedDimensionContent->setSeoCanonicalUrl('http://example.localhost')->shouldBeCalled(); - $localizedDimensionContent->setSeoHideInSitemap(true)->shouldBeCalled(); - $localizedDimensionContent->setSeoNoIndex(true)->shouldBeCalled(); - $localizedDimensionContent->setSeoNoFollow(true)->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); $seoMapper = $this->createSeoDataMapperInstance(); - $seoMapper->map($data, $dimensionContentCollection->reveal()); + $seoMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); + + $this->assertSame('Seo Title', $localizedDimensionContent->getSeoTitle()); + $this->assertSame('Seo Description', $localizedDimensionContent->getSeoDescription()); + $this->assertSame('Seo Keyword 1, Seo Keyword 2', $localizedDimensionContent->getSeoKeywords()); + $this->assertSame('http://example.localhost', $localizedDimensionContent->getSeoCanonicalUrl()); + $this->assertTrue($localizedDimensionContent->getSeoHideInSitemap()); + $this->assertTrue($localizedDimensionContent->getSeoNoFollow()); + $this->assertTrue($localizedDimensionContent->getSeoNoIndex()); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapperTest.php index 45b441ce..5ece9b10 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/TemplateDataMapperTest.php @@ -16,12 +16,9 @@ use PHPUnit\Framework\TestCase; use Prophecy\Prophecy\ObjectProphecy; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\TemplateDataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\TemplateInterface; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\DimensionContentMockWrapperTrait; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\MockWrapper; -use Sulu\Bundle\ContentBundle\Tests\Unit\Mocks\TemplateMockWrapperTrait; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; use Sulu\Component\Content\Metadata\Factory\StructureMetadataFactoryInterface; use Sulu\Component\Content\Metadata\PropertyMetadata; use Sulu\Component\Content\Metadata\StructureMetadata; @@ -29,26 +26,22 @@ class TemplateDataMapperTest extends TestCase { /** - * @param array $structureDefaultTypes + * @var ObjectProphecy|StructureMetadataFactoryInterface */ - protected function createTemplateDataMapperInstance( - StructureMetadataFactoryInterface $structureMetadataFactory, - array $structureDefaultTypes = [] - ): TemplateDataMapper { - return new TemplateDataMapper($structureMetadataFactory, $structureDefaultTypes); + private $structureMetadataFactory; + + protected function setUp(): void + { + $this->structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); } /** - * @param ObjectProphecy $tempplateMock + * @param array $structureDefaultTypes */ - protected function wrapTemplateMock(ObjectProphecy $tempplateMock): TemplateInterface - { - return new class($tempplateMock) extends MockWrapper implements - DimensionContentInterface, - TemplateInterface { - use DimensionContentMockWrapperTrait; - use TemplateMockWrapperTrait; - }; + protected function createTemplateDataMapperInstance( + array $structureDefaultTypes = [] + ): TemplateDataMapper { + return new TemplateDataMapper($this->structureMetadataFactory->reveal(), $structureDefaultTypes); } public function testMapNoTemplateInstance(): void @@ -56,309 +49,177 @@ public function testMapNoTemplateInstance(): void $data = [ 'template' => 'template-key', 'unlocalizedField' => 'Test Unlocalized', - 'localizedField' => 'Test Localized', + 'title' => 'Test Localized', ]; - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $templateMapper = $this->createTemplateDataMapperInstance(); + $templateMapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); $this->assertTrue(true); // Avoid risky test as this is an early return test } - public function testMapLocalizedNoTemplateKey(): void + public function testMapNoTemplateKey(): void { $this->expectException(\RuntimeException::class); - $data = []; - - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $data = [ + 'unlocalizedField' => 'Test Unlocalized', + 'title' => 'Test Localized', + ]; - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $templateMapper = $this->createTemplateDataMapperInstance(); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); } - public function testMapLocalizedNoTemplateInstance(): void + public function testMapNoStructureFound(): void { - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage(\sprintf( - 'Expected "$localizedObject" from type "%s" but "%s" given.', - TemplateInterface::class, - \get_class($localizedDimensionContent->reveal()) - )); $data = [ - 'template' => 'template-key', + 'template' => 'none-exist-template', + 'unlocalizedField' => 'Test Unlocalized', + 'title' => 'Test Localized', ]; - $structureMetadata = $this->prophesize(StructureMetadata::class); - $structureMetadata->getProperties()->willReturn([])->shouldBeCalled(); - - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', - 'template-key' - )->willReturn($structureMetadata->reveal())->shouldBeCalled(); - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); - - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $templateMapper = $this->createTemplateDataMapperInstance(); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); } - public function testMapLocalizedNoStructureFound(): void + public function testMapNoData(): void { - $this->expectException(\RuntimeException::class); - $this->expectExceptionMessage('Could not find structure "template-key" of type "mock-template-type".'); + $data = []; - $data = [ - 'template' => 'template-key', - ]; + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', + $this->structureMetadataFactory->getStructureMetadata( + 'example', 'template-key' - )->willReturn(null)->shouldBeCalled(); + )->willReturn($this->createStructureMetadata())->shouldBeCalled(); - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $templateMapper = $this->createTemplateDataMapperInstance(['example' => 'template-key']); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); - - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($unlocalizedDimensionContent->getTemplateKey()); + $this->assertNull($localizedDimensionContent->getTemplateKey()); + $this->assertSame([], $unlocalizedDimensionContent->getTemplateData()); + $this->assertSame([], $localizedDimensionContent->getTemplateData()); } - public function testMapUnlocalizedTemplate(): void + public function testMapData(): void { $data = [ 'template' => 'template-key', 'unlocalizedField' => 'Test Unlocalized', + 'title' => 'Test Localized', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - $unlocalizedDimensionContent->getTemplateData()->willReturn([])->shouldBeCalled(); - $unlocalizedDimensionContent->setTemplateKey('template-key')->shouldBeCalled(); - $unlocalizedDimensionContent->setTemplateData(['unlocalizedField' => 'Test Unlocalized'])->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $unlocalizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $unlocalizedPropertyMetadata->getName()->willReturn('unlocalizedField')->shouldBeCalled(); - $unlocalizedPropertyMetadata->isLocalized()->willReturn(false)->shouldBeCalled(); - - $structureMetadata = $this->prophesize(StructureMetadata::class); - $structureMetadata->getProperties()->willReturn([ - $unlocalizedPropertyMetadata->reveal(), - ])->shouldBeCalled(); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', + $this->structureMetadataFactory->getStructureMetadata( + 'example', 'template-key' - )->willReturn($structureMetadata->reveal())->shouldBeCalled(); + )->willReturn($this->createStructureMetadata())->shouldBeCalled(); - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); + $templateMapper = $this->createTemplateDataMapperInstance(); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($unlocalizedDimensionContent->getTemplateKey()); + $this->assertSame('template-key', $localizedDimensionContent->getTemplateKey()); + $this->assertSame(['unlocalizedField' => 'Test Unlocalized'], $unlocalizedDimensionContent->getTemplateData()); + $this->assertSame(['title' => 'Test Localized'], $localizedDimensionContent->getTemplateData()); } - public function testMapLocalizedTemplate(): void + public function testMapFloatData(): void { $data = [ 'template' => 'template-key', 'unlocalizedField' => 'Test Unlocalized', - 'localizedField' => 'Test Localized', + 'title' => 'Test Localized', + '1.1' => 'Test Float', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - $unlocalizedDimensionContent->getTemplateData()->willReturn([])->shouldBeCalled(); - $unlocalizedDimensionContent->setTemplateData(['unlocalizedField' => 'Test Unlocalized'])->shouldBeCalled(); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContent->setTemplateKey('template-key')->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['localizedField' => 'Test Localized'])->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapTemplateMock($localizedDimensionContent)); - - $unlocalizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $unlocalizedPropertyMetadata->getName()->willReturn('unlocalizedField')->shouldBeCalled(); - $unlocalizedPropertyMetadata->isLocalized()->willReturn(false)->shouldBeCalled(); - $localizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $localizedPropertyMetadata->getName()->willReturn('localizedField')->shouldBeCalled(); - $localizedPropertyMetadata->isLocalized()->willReturn(true)->shouldBeCalled(); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $structureMetadata = $this->prophesize(StructureMetadata::class); - $structureMetadata->getProperties()->willReturn([ - $unlocalizedPropertyMetadata->reveal(), - $localizedPropertyMetadata->reveal(), - ])->shouldBeCalled(); + $floatPropertyMetadata = $this->prophesize(PropertyMetadata::class); + $floatPropertyMetadata->getName()->willReturn(1.1)->shouldBeCalled(); + $floatPropertyMetadata->isLocalized()->willReturn(true)->shouldBeCalled(); - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', + $this->structureMetadataFactory->getStructureMetadata( + 'example', 'template-key' - )->willReturn($structureMetadata->reveal())->shouldBeCalled(); + )->willReturn($this->createStructureMetadata([$floatPropertyMetadata->reveal()]))->shouldBeCalled(); - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); + $templateMapper = $this->createTemplateDataMapperInstance(); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($unlocalizedDimensionContent->getTemplateKey()); + $this->assertSame('template-key', $localizedDimensionContent->getTemplateKey()); + $this->assertSame(['unlocalizedField' => 'Test Unlocalized'], $unlocalizedDimensionContent->getTemplateData()); + $this->assertSame(['title' => 'Test Localized', '1.1' => 'Test Float'], $localizedDimensionContent->getTemplateData()); } - public function testMapLocalizedNoTemplateKeyWithDefaultTemplate(): void + public function testMapWithDefaultTemplate(): void { $data = [ 'unlocalizedField' => 'Test Unlocalized', - 'localizedField' => 'Test Localized', + 'title' => 'Test Localized', ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - $unlocalizedDimensionContent->getTemplateData()->willReturn([])->shouldBeCalled(); - $unlocalizedDimensionContent->setTemplateData(['unlocalizedField' => 'Test Unlocalized'])->shouldBeCalled(); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContent->setTemplateKey('template-key')->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['localizedField' => 'Test Localized'])->shouldBeCalled(); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapTemplateMock($localizedDimensionContent)); - - $unlocalizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $unlocalizedPropertyMetadata->getName()->willReturn('unlocalizedField')->shouldBeCalled(); - $unlocalizedPropertyMetadata->isLocalized()->willReturn(false)->shouldBeCalled(); - $localizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $localizedPropertyMetadata->getName()->willReturn('localizedField')->shouldBeCalled(); - $localizedPropertyMetadata->isLocalized()->willReturn(true)->shouldBeCalled(); - - $structureMetadata = $this->prophesize(StructureMetadata::class); - $structureMetadata->getProperties()->willReturn([ - $unlocalizedPropertyMetadata->reveal(), - $localizedPropertyMetadata->reveal(), - ])->shouldBeCalled(); - - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', + $this->structureMetadataFactory->getStructureMetadata( + 'example', 'template-key' - )->willReturn($structureMetadata->reveal())->shouldBeCalled(); + )->willReturn($this->createStructureMetadata())->shouldBeCalled(); - $templateMapper = $this->createTemplateDataMapperInstance( - $structureMetadataFactory->reveal(), - ['mock-template-type' => 'template-key'] - ); + $templateMapper = $this->createTemplateDataMapperInstance([ + 'example' => 'template-key', + ]); + $templateMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($unlocalizedDimensionContent->getTemplateKey()); + $this->assertSame('template-key', $localizedDimensionContent->getTemplateKey()); + $this->assertSame(['unlocalizedField' => 'Test Unlocalized'], $unlocalizedDimensionContent->getTemplateData()); + $this->assertSame(['title' => 'Test Localized'], $localizedDimensionContent->getTemplateData()); } - public function testMapFloatValueTemplate(): void + /** + * @param PropertyMetadata[] $properties + */ + private function createStructureMetadata(array $properties = []): StructureMetadata { - $data = [ - 'template' => 'template-key', - '1.1' => 'Test Unlocalized', - 'localizedField' => 'Test Localized', - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(TemplateInterface::class); - $unlocalizedDimensionContent->getTemplateData()->willReturn([])->shouldBeCalled(); - $unlocalizedDimensionContent->setTemplateData(['1.1' => 'Test Unlocalized'])->shouldBeCalled(); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(TemplateInterface::class); - $localizedDimensionContent->setTemplateKey('template-key')->shouldBeCalled(); - $localizedDimensionContent->setTemplateData(['localizedField' => 'Test Localized'])->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($this->wrapTemplateMock($unlocalizedDimensionContent)); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($this->wrapTemplateMock($localizedDimensionContent)); - $unlocalizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $unlocalizedPropertyMetadata->getName()->willReturn(1.1)->shouldBeCalled(); + $unlocalizedPropertyMetadata->getName()->willReturn('unlocalizedField')->shouldBeCalled(); $unlocalizedPropertyMetadata->isLocalized()->willReturn(false)->shouldBeCalled(); $localizedPropertyMetadata = $this->prophesize(PropertyMetadata::class); - $localizedPropertyMetadata->getName()->willReturn('localizedField')->shouldBeCalled(); + $localizedPropertyMetadata->getName()->willReturn('title')->shouldBeCalled(); $localizedPropertyMetadata->isLocalized()->willReturn(true)->shouldBeCalled(); $structureMetadata = $this->prophesize(StructureMetadata::class); - $structureMetadata->getProperties()->willReturn([ + $structureMetadata->getProperties()->willReturn(\array_merge([ $unlocalizedPropertyMetadata->reveal(), $localizedPropertyMetadata->reveal(), - ])->shouldBeCalled(); - - $structureMetadataFactory = $this->prophesize(StructureMetadataFactoryInterface::class); - $structureMetadataFactory->getStructureMetadata( - 'mock-template-type', - 'template-key' - )->willReturn($structureMetadata->reveal())->shouldBeCalled(); - - $templateMapper = $this->createTemplateDataMapperInstance($structureMetadataFactory->reveal()); + ], $properties))->shouldBeCalled(); - $templateMapper->map($data, $dimensionContentCollection->reveal()); + return $structureMetadata->reveal(); } } diff --git a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapperTest.php b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapperTest.php index 875b99b8..616d4ddb 100644 --- a/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapperTest.php +++ b/Tests/Unit/Content/Application/ContentDataMapper/DataMapper/WorkflowDataMapperTest.php @@ -14,11 +14,10 @@ namespace Sulu\Bundle\ContentBundle\Tests\Unit\Content\Application\ContentDataMapper\DataMapper; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; use Sulu\Bundle\ContentBundle\Content\Application\ContentDataMapper\DataMapper\WorkflowDataMapper; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentCollectionInterface; use Sulu\Bundle\ContentBundle\Content\Domain\Model\DimensionContentInterface; -use Sulu\Bundle\ContentBundle\Content\Domain\Model\WorkflowInterface; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; class WorkflowDataMapperTest extends TestCase { @@ -27,10 +26,8 @@ protected function createWorkflowDataMapperInstance(): WorkflowDataMapper return new WorkflowDataMapper(); } - public function testMapNoWorkflow(): void + public function testMapNoWorkflowInterface(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - $data = [ 'published' => (new \DateTime())->format('c'), ]; @@ -38,264 +35,120 @@ public function testMapNoWorkflow(): void $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent->reveal(), $localizedDimensionContent->reveal(), $data); $this->assertTrue(true); // Avoid risky test as this is an early return test } - public function testMapLocalizedNoWorkflow(): void + public function testMapNoData(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - - $data = [ - 'published' => (new \DateTime())->format('c'), - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); + $data = []; - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $this->expectException(\RuntimeException::class); + $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame('unpublished', $localizedDimensionContent->getWorkflowPlace()); + $this->assertNull($localizedDimensionContent->getWorkflowPublished()); } - public function testMapUnlocalizedDraft(): void + public function testMapStageData(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - + $publishedDate = (new \DateTime())->format('c'); $data = [ - 'published' => (new \DateTime())->format('c'), + 'published' => $publishedDate, ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - $unlocalizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_DRAFT); - $unlocalizedDimensionContent->getWorkflowPlace()->willReturn(null); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $unlocalizedDimensionContent->setWorkflowPlace(WorkflowInterface::WORKFLOW_PLACE_UNPUBLISHED)->shouldBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); + $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame('unpublished', $localizedDimensionContent->getWorkflowPlace()); + $workflowPublished = $localizedDimensionContent->getWorkflowPublished(); + $this->assertNull($workflowPublished); } - public function testMapUnlocalizedDraftPlaceAlreadySet(): void + public function testMapLiveData(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - + $publishedDate = (new \DateTime())->format('c'); $data = [ - 'published' => (new \DateTime())->format('c'), + 'published' => $publishedDate, ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - $unlocalizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_DRAFT); - $unlocalizedDimensionContent->getWorkflowPlace()->willReturn(WorkflowInterface::WORKFLOW_PLACE_UNPUBLISHED); - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); - } + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage(DimensionContentInterface::STAGE_LIVE); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage(DimensionContentInterface::STAGE_LIVE); - public function testMapUnlocalizedLive(): void - { $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $data = [ - 'published' => (new \DateTime())->format('c'), - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - $unlocalizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_LIVE); - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::type(\DateTimeInterface::class))->shouldBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertNull($localizedDimensionContent->getWorkflowPlace()); + $workflowPublished = $localizedDimensionContent->getWorkflowPublished(); + $this->assertNotNull($workflowPublished); + $this->assertSame($publishedDate, $workflowPublished->format('c')); } - public function testMapUnlocalizedLivePublishedNotSet(): void + public function testMapWorkflowPlaceAlreadySet(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - $data = []; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - $unlocalizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_LIVE); - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn(null); - - $this->expectException(\RuntimeException::class); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $workflowMapper->map($data, $dimensionContentCollection->reveal()); - } + $localizedDimensionContent->setWorkflowPlace('something-else'); - public function testMapLocalizedDraft(): void - { $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $data = [ - 'published' => (new \DateTime())->format('c'), - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(WorkflowInterface::class); - $localizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_DRAFT); - $localizedDimensionContent->getWorkflowPlace()->willReturn(null); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $localizedDimensionContent->setWorkflowPlace(WorkflowInterface::WORKFLOW_PLACE_UNPUBLISHED)->shouldBeCalled(); - $localizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame('something-else', $localizedDimensionContent->getWorkflowPlace()); } - public function testMapLocalizedDraftPlaceAlreadySet(): void + public function testMapDataPublishedAlreadySet(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); - $data = [ 'published' => (new \DateTime())->format('c'), ]; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(WorkflowInterface::class); - $localizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_DRAFT); - $localizedDimensionContent->getWorkflowPlace()->willReturn(WorkflowInterface::WORKFLOW_PLACE_UNPUBLISHED); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent = new ExampleDimensionContent($example); - $localizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); + $localizedDimensionContent->setWorkflowPlace('something-else'); + $localizedDimensionContent->setWorkflowPublished(new \DateTimeImmutable('2021-01-01 00:00:00')); - $workflowMapper->map($data, $dimensionContentCollection->reveal()); - } - - public function testMapLocalizedLive(): void - { $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); - $data = [ - 'published' => (new \DateTime())->format('c'), - ]; - - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(WorkflowInterface::class); - $localizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_LIVE); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); - - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $localizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setWorkflowPublished(Argument::type(\DateTimeInterface::class))->shouldBeCalled(); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $this->assertSame('something-else', $localizedDimensionContent->getWorkflowPlace()); + $workflowPublished = $localizedDimensionContent->getWorkflowPublished(); + $this->assertNotNull($workflowPublished); + $this->assertSame('2021-01-01 00:00:00', $workflowPublished->format('Y-m-d H:i:s')); } public function testMapLocalizedLivePublishedNotSet(): void { - $workflowMapper = $this->createWorkflowDataMapperInstance(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Expected "published" to be set in the data array.'); $data = []; - $unlocalizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $unlocalizedDimensionContent->willImplement(WorkflowInterface::class); - - $localizedDimensionContent = $this->prophesize(DimensionContentInterface::class); - $localizedDimensionContent->willImplement(WorkflowInterface::class); - $localizedDimensionContent->getStage()->willReturn(DimensionContentInterface::STAGE_LIVE); - - $dimensionContentCollection = $this->prophesize(DimensionContentCollectionInterface::class); - $dimensionContentCollection->getDimensionAttributes()->willReturn(['stage' => 'draft', 'locale' => 'de']); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => null]) - ->willReturn($unlocalizedDimensionContent); - $dimensionContentCollection->getDimensionContent(['stage' => 'draft', 'locale' => 'de']) - ->willReturn($localizedDimensionContent); + $example = new Example(); + $unlocalizedDimensionContent = new ExampleDimensionContent($example); + $unlocalizedDimensionContent->setStage(DimensionContentInterface::STAGE_LIVE); + $localizedDimensionContent = new ExampleDimensionContent($example); + $localizedDimensionContent->setStage(DimensionContentInterface::STAGE_LIVE); - $unlocalizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $unlocalizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $localizedDimensionContent->setWorkflowPlace(Argument::cetera())->shouldNotBeCalled(); - $localizedDimensionContent->setWorkflowPublished(Argument::cetera())->shouldNotBeCalled(); - - $this->expectException(\RuntimeException::class); - - $workflowMapper->map($data, $dimensionContentCollection->reveal()); + $workflowMapper = $this->createWorkflowDataMapperInstance(); + $workflowMapper->map($unlocalizedDimensionContent, $localizedDimensionContent, $data); } } diff --git a/Tests/Unit/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactoryTest.php b/Tests/Unit/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactoryTest.php index 4217c637..fa48971c 100644 --- a/Tests/Unit/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactoryTest.php +++ b/Tests/Unit/Content/Application/DimensionContentCollectionFactory/DimensionContentCollectionFactoryTest.php @@ -74,12 +74,13 @@ public function testCreateWithExistingDimensionContent(): void $contentDataMapper = $this->prophesize(ContentDataMapperInterface::class); $contentDataMapper->map( - $data, Argument::that( function(DimensionContentCollectionInterface $collection) use ($dimensionContent1, $dimensionContent2) { return [$dimensionContent1->reveal(), $dimensionContent2->reveal()] === \iterator_to_array($collection); } - ) + ), + $attributes, + $data )->shouldBeCalled(); $dimensionContentCollectionFactoryInstance = $this->createDimensionContentCollectionFactoryInstance( @@ -140,12 +141,13 @@ public function testCreateWithoutExistingDimensionContent(): void $contentDataMapper = $this->prophesize(ContentDataMapperInterface::class); $contentDataMapper->map( - $data, Argument::that( function(DimensionContentCollectionInterface $collection) use ($dimensionContent1, $dimensionContent2) { return [$dimensionContent1->reveal(), $dimensionContent2->reveal()] === \iterator_to_array($collection); } - ) + ), + $attributes, + $data )->shouldBeCalled(); $dimensionContentCollectionFactoryInstance = $this->createDimensionContentCollectionFactoryInstance( @@ -198,12 +200,13 @@ public function testCreateWithoutExistingLocalizedDimensionContent(): void $contentDataMapper = $this->prophesize(ContentDataMapperInterface::class); $contentDataMapper->map( - $data, Argument::that( function(DimensionContentCollectionInterface $collection) use ($dimensionContent1, $dimensionContent2) { return [$dimensionContent1->reveal(), $dimensionContent2->reveal()] === \iterator_to_array($collection); } - ) + ), + $attributes, + $data )->shouldBeCalled(); $dimensionContentCollectionFactoryInstance = $this->createDimensionContentCollectionFactoryInstance( $attributes, diff --git a/Tests/Unit/Content/Infrastructure/Sulu/Preview/ContentObjectProviderTest.php b/Tests/Unit/Content/Infrastructure/Sulu/Preview/ContentObjectProviderTest.php index 897d1c37..44194ae2 100644 --- a/Tests/Unit/Content/Infrastructure/Sulu/Preview/ContentObjectProviderTest.php +++ b/Tests/Unit/Content/Infrastructure/Sulu/Preview/ContentObjectProviderTest.php @@ -29,6 +29,7 @@ use Sulu\Bundle\ContentBundle\Content\Infrastructure\Sulu\Preview\ContentObjectProvider; use Sulu\Bundle\ContentBundle\Content\Infrastructure\Sulu\Preview\PreviewDimensionContentCollection; use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\Example; +use Sulu\Bundle\ContentBundle\Tests\Application\ExampleTestBundle\Entity\ExampleDimensionContent; class ContentObjectProviderTest extends TestCase { @@ -193,17 +194,19 @@ public function testSetValues( 'excerptIcon' => ['id' => 4], ] ): void { - $dimensionContent = $this->prophesize(DimensionContentInterface::class); + $example = new Example(); + $exampleDimensionContent = new ExampleDimensionContent($example); - $this->contentObjectProvider->setValues($dimensionContent->reveal(), $locale, $data); + $this->contentObjectProvider->setValues($exampleDimensionContent, $locale, $data); $this->contentDataMapper->map( - $data, Argument::that( - function(PreviewDimensionContentCollection $dimensionContentCollection) use ($dimensionContent) { - return $dimensionContent->reveal() === $dimensionContentCollection->getDimensionContent([]); + function(PreviewDimensionContentCollection $dimensionContentCollection) use ($exampleDimensionContent) { + return $exampleDimensionContent === $dimensionContentCollection->getDimensionContent([]); } - ) + ), + ['locale' => 'de', 'stage' => 'draft'], + $data )->shouldBeCalledTimes(1); } diff --git a/UPGRADE.md b/UPGRADE.md index 594ec93e..62a49bec 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -1,5 +1,53 @@ # Upgrade +## 0.7.0 + +### ContentMapperInterface changed + +The `ContentMapperInterface` was changed as a preparation for refactoring the `DimensionContentCollection`: + +**Before** + +```php + public function map( + array $data, + DimensionContentCollectionInterface $dimensionContentCollection + ): void; +``` + +**After** + +```php + public function map( + DimensionContentCollectionInterface $dimensionContentCollection, + array $dimensionAttributes, + array $data + ): void; +``` + +### DataMapperInterface changed + +The `DataMapperInterface` was changed to make it easier to set localized and unlocalized data: + +**Before** + +```php + public function map( + array $data, + DimensionContentCollectionInterface $dimensionContentCollection + ): void; +``` + +**After** + +```php + public function map( + DimensionContentInterface $unlocalizedDimensionContent, + DimensionContentInterface $localizedDimensionContent, + array $data + ): void; +``` + ## 0.6.0 ### Adjusted ContentDataMapper to accept DimensionContentCollection instead of separate objects