From 521c6ca9cc2926a430e4ab159b3b31eb4a2ac14a Mon Sep 17 00:00:00 2001 From: Fran Moreno Date: Wed, 11 Dec 2019 11:22:52 +0100 Subject: [PATCH] Add tests to ModelManager and DateFilter --- src/Filter/AbstractDateFilter.php | 36 +- src/Filter/DateFilter.php | 6 + src/Filter/DateTimeFilter.php | 6 + src/Model/ModelManager.php | 15 +- tests/Filter/DateTimeFilterTest.php | 81 +++++ tests/Fixtures/Document/AbstractDocument.php | 16 + .../Fixtures/Document/AssociatedDocument.php | 29 ++ tests/Fixtures/Document/ContainerDocument.php | 30 ++ tests/Fixtures/Document/EmbeddedDocument.php | 20 ++ tests/Fixtures/Document/ProtectedDocument.php | 19 + tests/Fixtures/Document/SimpleDocument.php | 38 ++ tests/Model/ModelManagerTest.php | 329 +++++++++++++++++- 12 files changed, 621 insertions(+), 4 deletions(-) create mode 100644 tests/Filter/DateTimeFilterTest.php create mode 100644 tests/Fixtures/Document/AbstractDocument.php create mode 100644 tests/Fixtures/Document/AssociatedDocument.php create mode 100644 tests/Fixtures/Document/ContainerDocument.php create mode 100644 tests/Fixtures/Document/EmbeddedDocument.php create mode 100644 tests/Fixtures/Document/ProtectedDocument.php create mode 100644 tests/Fixtures/Document/SimpleDocument.php diff --git a/src/Filter/AbstractDateFilter.php b/src/Filter/AbstractDateFilter.php index a39c6812..53067e5d 100644 --- a/src/Filter/AbstractDateFilter.php +++ b/src/Filter/AbstractDateFilter.php @@ -49,12 +49,14 @@ public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data) $data['type'] = !isset($data['type']) || !is_numeric($data['type']) ? DateType::TYPE_EQUAL : $data['type']; // Some types do not require a value to be set (NULL, NOT NULL). - if (!$this->typeRequiresValue($data['type']) && !$data['value']) { + if (!($data['value'] ?? false) && !$this->typeRequiresValue($data['type'])) { return; } switch ($data['type']) { case DateType::TYPE_EQUAL: + $this->active = true; + return $this->applyTypeIsEqual($queryBuilder, $field, $data); case DateType::TYPE_GREATER_THAN: @@ -62,6 +64,8 @@ public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data) return; } + $this->active = true; + return $this->applyTypeIsGreaterThan($queryBuilder, $field, $data); case DateType::TYPE_LESS_EQUAL: @@ -69,14 +73,20 @@ public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data) return; } + $this->active = true; + return $this->applyTypeIsLessEqual($queryBuilder, $field, $data); case DateType::TYPE_NULL: case DateType::TYPE_NOT_NULL: + $this->active = true; + return $this->applyType($queryBuilder, $this->getOperator($data['type']), $field, null); case DateType::TYPE_GREATER_EQUAL: case DateType::TYPE_LESS_THAN: + $this->active = true; + return $this->applyType($queryBuilder, $this->getOperator($data['type']), $field, $data['value']); } } @@ -111,6 +121,30 @@ public function getRenderSettings() ]]; } + /** + * @param string $field + * @param array $data + */ + protected function applyTypeIsLessEqual(ProxyQueryInterface $queryBuilder, $field, $data) + { + } + + /** + * @param string $field + * @param array $data + */ + protected function applyTypeIsGreaterThan(ProxyQueryInterface $queryBuilder, $field, $data) + { + } + + /** + * @param string $field + * @param array $data + */ + protected function applyTypeIsEqual(ProxyQueryInterface $queryBuilder, $field, $data) + { + } + /** * @param string $operation * @param string $field diff --git a/src/Filter/DateFilter.php b/src/Filter/DateFilter.php index c2d1d0cf..3568798b 100644 --- a/src/Filter/DateFilter.php +++ b/src/Filter/DateFilter.php @@ -14,9 +14,15 @@ namespace Sonata\DoctrineMongoDBAdminBundle\Filter; use Sonata\AdminBundle\Datagrid\ProxyQueryInterface; +use Symfony\Component\Form\Extension\Core\Type\DateType; class DateFilter extends AbstractDateFilter { + public function getFieldType() + { + return $this->getOption('field_type', DateType::class); + } + /** * @param string $field * @param array $data diff --git a/src/Filter/DateTimeFilter.php b/src/Filter/DateTimeFilter.php index dc751390..e925667f 100644 --- a/src/Filter/DateTimeFilter.php +++ b/src/Filter/DateTimeFilter.php @@ -14,6 +14,7 @@ namespace Sonata\DoctrineMongoDBAdminBundle\Filter; use Sonata\AdminBundle\Datagrid\ProxyQueryInterface; +use Symfony\Component\Form\Extension\Core\Type\DateTimeType; class DateTimeFilter extends AbstractDateFilter { @@ -24,6 +25,11 @@ class DateTimeFilter extends AbstractDateFilter */ protected $time = true; + public function getFieldType() + { + return $this->getOption('field_type', DateTimeType::class); + } + /** * @param string $field * @param array $data diff --git a/src/Model/ModelManager.php b/src/Model/ModelManager.php index ad4c840d..cddc5459 100755 --- a/src/Model/ModelManager.php +++ b/src/Model/ModelManager.php @@ -359,6 +359,17 @@ public function getExportFields($class) */ public function getModelInstance($class) { + $r = new \ReflectionClass($class); + if ($r->isAbstract()) { + throw new \InvalidArgumentException(sprintf('Cannot initialize abstract class: %s', $class)); + } + + $constructor = $r->getConstructor(); + + if (null !== $constructor && (!$constructor->isPublic() || $constructor->getNumberOfRequiredParameters() > 0)) { + return $r->newInstanceWithoutConstructor(); + } + return new $class(); } @@ -443,7 +454,7 @@ public function modelReverseTransform($class, array $array = []) if ($reflClass->hasMethod($setter)) { if (!$reflClass->getMethod($setter)->isPublic()) { - throw new \RuntimeException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName())); + throw new \BadMethodCallException(sprintf('Method "%s()" is not public in class "%s"', $setter, $reflClass->getName())); } $instance->$setter($value); @@ -452,7 +463,7 @@ public function modelReverseTransform($class, array $array = []) $instance->$property = $value; } elseif ($reflClass->hasProperty($property)) { if (!$reflClass->getProperty($property)->isPublic()) { - throw new \RuntimeException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property))); + throw new \BadMethodCallException(sprintf('Property "%s" is not public in class "%s". Maybe you should create the method "set%s()"?', $property, $reflClass->getName(), ucfirst($property))); } $instance->$property = $value; diff --git a/tests/Filter/DateTimeFilterTest.php b/tests/Filter/DateTimeFilterTest.php new file mode 100644 index 00000000..61d71145 --- /dev/null +++ b/tests/Filter/DateTimeFilterTest.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Filter; + +use Sonata\AdminBundle\Form\Type\Filter\DateType; +use Sonata\DoctrineMongoDBAdminBundle\Datagrid\ProxyQuery; +use Sonata\DoctrineMongoDBAdminBundle\Filter\DateTimeFilter; +use Symfony\Component\Form\Extension\Core\Type\DateTimeType; + +final class DateTimeFilterTest extends FilterWithQueryBuilderTest +{ + public function testEmpty(): void + { + $filter = new DateTimeFilter(); + $filter->initialize('field_name', ['field_options' => ['class' => 'FooBar']]); + + $builder = new ProxyQuery($this->getQueryBuilder()); + + $builder->getQueryBuilder() + ->expects($this->never()) + ->method('field') + ; + + $filter->filter($builder, 'alias', 'field', null); + $filter->filter($builder, 'alias', 'field', 'all'); + $filter->filter($builder, 'alias', 'field', []); + + $this->assertFalse($filter->isActive()); + } + + public function testGetType(): void + { + $this->assertSame(DateTimeType::class, (new DateTimeFilter())->getFieldType()); + } + + /** + * @dataProvider getExamples + */ + public function testFilter(array $data, string $method): void + { + $filter = new DateTimeFilter(); + $filter->initialize('field_name', ['field_options' => ['class' => 'FooBar']]); + + $builder = new ProxyQuery($this->getQueryBuilder()); + + $builder->getQueryBuilder() + ->expects($this->once()) + ->method($method) + ->with($data['value'] ?? null) + ; + + $filter->filter($builder, 'alias', 'field', $data); + + $this->assertTrue($filter->isActive()); + } + + public function getExamples(): array + { + return [ + [['type' => DateType::TYPE_EQUAL, 'value' => new \DateTime('now')], 'range'], + [['type' => DateType::TYPE_GREATER_EQUAL, 'value' => new \DateTime('now')], 'gte'], + [['type' => DateType::TYPE_GREATER_THAN, 'value' => new \DateTime('now')], 'gt'], + [['type' => DateType::TYPE_LESS_EQUAL, 'value' => new \DateTime('now')], 'lte'], + [['type' => DateType::TYPE_LESS_THAN, 'value' => new \DateTime('now')], 'lt'], + [['type' => DateType::TYPE_NULL], 'equals'], + [['type' => DateType::TYPE_NOT_NULL], 'notEqual'], + [['value' => new \DateTime('now')], 'range'], + ]; + } +} diff --git a/tests/Fixtures/Document/AbstractDocument.php b/tests/Fixtures/Document/AbstractDocument.php new file mode 100644 index 00000000..e9631b17 --- /dev/null +++ b/tests/Fixtures/Document/AbstractDocument.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +abstract class AbstractDocument +{ +} diff --git a/tests/Fixtures/Document/AssociatedDocument.php b/tests/Fixtures/Document/AssociatedDocument.php new file mode 100644 index 00000000..082c0a4f --- /dev/null +++ b/tests/Fixtures/Document/AssociatedDocument.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +class AssociatedDocument +{ + private $plainField; + private $embeddedDocument; + + public function __construct(int $plainField, EmbeddedDocument $embeddedDocument) + { + $this->plainField = $plainField; + $this->embeddedDocument = $embeddedDocument; + } + + public function getPlainField(): int + { + return $this->plainField; + } +} diff --git a/tests/Fixtures/Document/ContainerDocument.php b/tests/Fixtures/Document/ContainerDocument.php new file mode 100644 index 00000000..9ddab480 --- /dev/null +++ b/tests/Fixtures/Document/ContainerDocument.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +class ContainerDocument +{ + private $plainField; + private $associatedDocument; + private $embeddedDocument; + + public function __construct(AssociatedDocument $associatedDocument, EmbeddedDocument $embeddedDocument) + { + $this->associatedDocument = $associatedDocument; + $this->embeddedDocument = $embeddedDocument; + } + + public function getAssociatedDocument(): AssociatedDocument + { + return $this->associatedDocument; + } +} diff --git a/tests/Fixtures/Document/EmbeddedDocument.php b/tests/Fixtures/Document/EmbeddedDocument.php new file mode 100644 index 00000000..bd6b13f0 --- /dev/null +++ b/tests/Fixtures/Document/EmbeddedDocument.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +class EmbeddedDocument +{ + /** + * @var bool + */ + protected $plainField; +} diff --git a/tests/Fixtures/Document/ProtectedDocument.php b/tests/Fixtures/Document/ProtectedDocument.php new file mode 100644 index 00000000..4bcc708a --- /dev/null +++ b/tests/Fixtures/Document/ProtectedDocument.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +class ProtectedDocument +{ + private function __construct() + { + } +} diff --git a/tests/Fixtures/Document/SimpleDocument.php b/tests/Fixtures/Document/SimpleDocument.php new file mode 100644 index 00000000..ee886d32 --- /dev/null +++ b/tests/Fixtures/Document/SimpleDocument.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document; + +class SimpleDocument +{ + private $schmeckles; + private $multiWordProperty; + + public function getSchmeckles() + { + return $this->schmeckles; + } + + public function setSchmeckles($value): void + { + $this->schmeckles = $value; + } + + public function getMultiWordProperty() + { + return $this->multiWordProperty; + } + + public function setMultiWordProperty($value): void + { + $this->multiWordProperty = $value; + } +} diff --git a/tests/Model/ModelManagerTest.php b/tests/Model/ModelManagerTest.php index 86903007..a97c9a40 100644 --- a/tests/Model/ModelManagerTest.php +++ b/tests/Model/ModelManagerTest.php @@ -13,16 +13,343 @@ namespace Sonata\DoctrineMongoDBAdminBundle\Tests\Model; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\ODM\MongoDB\DocumentManager; +use Doctrine\ODM\MongoDB\Mapping\ClassMetadata; use PHPUnit\Framework\TestCase; +use Sonata\AdminBundle\Datagrid\Datagrid; +use Sonata\AdminBundle\Datagrid\DatagridInterface; +use Sonata\AdminBundle\Filter\FilterInterface; +use Sonata\DoctrineMongoDBAdminBundle\Admin\FieldDescription; use Sonata\DoctrineMongoDBAdminBundle\Model\ModelManager; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\AbstractDocument; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\AssociatedDocument; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\ContainerDocument; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\EmbeddedDocument; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\ProtectedDocument; +use Sonata\DoctrineMongoDBAdminBundle\Tests\Fixtures\Document\SimpleDocument; use Symfony\Bridge\Doctrine\ManagerRegistry; class ModelManagerTest extends TestCase { - public function testFilterEmpty(): void + public function testSortParameters(): void { $registry = $this->createMock(ManagerRegistry::class); $manager = new ModelManager($registry); + + $datagrid1 = $this->createMock(Datagrid::class); + $datagrid2 = $this->createMock(Datagrid::class); + + $field1 = new FieldDescription(); + $field1->setName('field1'); + + $field2 = new FieldDescription(); + $field2->setName('field2'); + + $field3 = new FieldDescription(); + $field3->setName('field3'); + $field3->setOption('sortable', 'field3sortBy'); + + $datagrid1 + ->method('getValues') + ->willReturn([ + '_sort_by' => $field1, + '_sort_order' => 'ASC', + ]); + + $datagrid2 + ->method('getValues') + ->willReturn([ + '_sort_by' => $field3, + '_sort_order' => 'ASC', + ]); + + $parameters = $manager->getSortParameters($field1, $datagrid1); + + $this->assertSame('DESC', $parameters['filter']['_sort_order']); + $this->assertSame('field1', $parameters['filter']['_sort_by']); + + $parameters = $manager->getSortParameters($field2, $datagrid1); + + $this->assertSame('ASC', $parameters['filter']['_sort_order']); + $this->assertSame('field2', $parameters['filter']['_sort_by']); + + $parameters = $manager->getSortParameters($field3, $datagrid1); + + $this->assertSame('ASC', $parameters['filter']['_sort_order']); + $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']); + + $parameters = $manager->getSortParameters($field3, $datagrid2); + + $this->assertSame('DESC', $parameters['filter']['_sort_order']); + $this->assertSame('field3sortBy', $parameters['filter']['_sort_by']); + } + + public function testGetParentMetadataForProperty(): void + { + $containerDocumentClass = ContainerDocument::class; + $associatedDocumentClass = AssociatedDocument::class; + $embeddedDocumentClass = EmbeddedDocument::class; + + $dm = $this->createMock(DocumentManager::class); + + $registry = $this->createMock(ManagerRegistry::class); + + $modelManager = new ModelManager($registry); + + $registry + ->method('getManagerForClass') + ->willReturn($dm); + + $metadataFactory = $this->createMock(ClassMetadataFactory::class); + + $dm + ->method('getMetadataFactory') + ->willReturn($metadataFactory); + + $containerDocumentMetadata = $this->getMetadataForContainerDocument(); + $associatedDocumentMetadata = $this->getMetadataForAssociatedDocument(); + $embeddedDocumentMetadata = $this->getMetadataForEmbeddedDocument(); + + $metadataFactory->method('getMetadataFor') + ->willReturnMap( + + [ + [$containerDocumentClass, $containerDocumentMetadata], + [$embeddedDocumentClass, $embeddedDocumentMetadata], + [$associatedDocumentClass, $associatedDocumentMetadata], + ] + + ); + + /** @var ClassMetadata $metadata */ + [$metadata, $lastPropertyName] = $modelManager + ->getParentMetadataForProperty($containerDocumentClass, 'plainField'); + $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'integer'); + + [$metadata, $lastPropertyName] = $modelManager + ->getParentMetadataForProperty($containerDocumentClass, 'associatedDocument.plainField'); + $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'string'); + + [$metadata, $lastPropertyName] = $modelManager + ->getParentMetadataForProperty($containerDocumentClass, 'embeddedDocument.plainField'); + $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean'); + + $this->assertSame($metadata->fieldMappings[$lastPropertyName]['type'], 'boolean'); + } + + public function testModelReverseTransform(): void + { + $class = SimpleDocument::class; + + $metadataFactory = $this->createMock(ClassMetadataFactory::class); + $modelManager = $this->createMock(ObjectManager::class); + $registry = $this->createMock(ManagerRegistry::class); + + $classMetadata = new ClassMetadata($class); + $classMetadata->reflClass = new \ReflectionClass($class); + + $modelManager->expects($this->once()) + ->method('getMetadataFactory') + ->willReturn($metadataFactory); + $metadataFactory->expects($this->once()) + ->method('getMetadataFor') + ->with($class) + ->willReturn($classMetadata); + $registry->expects($this->once()) + ->method('getManagerForClass') + ->with($class) + ->willReturn($modelManager); + + $manager = new ModelManager($registry); + $this->assertInstanceOf($class, $object = $manager->modelReverseTransform( + $class, + [ + 'schmeckles' => 42, + 'multi_word_property' => 'hello', + ] + )); + $this->assertSame(42, $object->getSchmeckles()); + $this->assertSame('hello', $object->getMultiWordProperty()); + } + + public function testCollections(): void + { + $registry = $this->createMock(ManagerRegistry::class); + $model = new ModelManager($registry); + + $collection = $model->getModelCollectionInstance('whyDoWeEvenHaveThisParameter'); + $this->assertInstanceOf(ArrayCollection::class, $collection); + + $item1 = 'item1'; + $item2 = 'item2'; + $model->collectionAddElement($collection, $item1); + $model->collectionAddElement($collection, $item2); + + $this->assertTrue($model->collectionHasElement($collection, $item1)); + + $model->collectionRemoveElement($collection, $item1); + + $this->assertFalse($model->collectionHasElement($collection, $item1)); + + $model->collectionClear($collection); + + $this->assertTrue($collection->isEmpty()); + } + + public function testModelTransform(): void + { + $registry = $this->createMock(ManagerRegistry::class); + $model = new ModelManager($registry); + + $result = $model->modelTransform('thisIsNotUsed', 'doWeNeedThisMethod'); + + $this->assertSame('doWeNeedThisMethod', $result); + } + + public function testGetPaginationParameters(): void + { + $datagrid = $this->createMock(DatagridInterface::class); + $filter = $this->createMock(FilterInterface::class); + $registry = $this->createMock(ManagerRegistry::class); + + $datagrid->expects($this->once()) + ->method('getValues') + ->willReturn(['_sort_by' => $filter]); + + $filter->expects($this->once()) + ->method('getName') + ->willReturn($name = 'test'); + + $model = new ModelManager($registry); + + $result = $model->getPaginationParameters($datagrid, $page = 5); + + $this->assertSame($page, $result['filter']['_page']); + $this->assertSame($name, $result['filter']['_sort_by']); + } + + public function testGetModelInstanceException(): void + { + $registry = $this->createMock(ManagerRegistry::class); + + $model = new ModelManager($registry); + + $this->expectException(\InvalidArgumentException::class); + + $model->getModelInstance(AbstractDocument::class); + } + + public function testGetModelInstanceForProtectedDocument(): void + { + $registry = $this->createMock(ManagerRegistry::class); + + $model = new ModelManager($registry); + + $this->assertInstanceOf(ProtectedDocument::class, $model->getModelInstance(ProtectedDocument::class)); + } + + public function testFindBadId(): void + { + $registry = $this->createMock(ManagerRegistry::class); + + $model = new ModelManager($registry); + + $this->assertNull($model->find('notImportant', null)); + } + + public function testGetUrlsafeIdentifierException(): void + { + $registry = $this->createMock(ManagerRegistry::class); + + $model = new ModelManager($registry); + + $this->expectException(\RuntimeException::class); + + $model->getNormalizedIdentifier('test'); + } + + public function testGetUrlsafeIdentifierNull(): void + { + $registry = $this->createMock(ManagerRegistry::class); + + $model = new ModelManager($registry); + + $this->assertNull($model->getNormalizedIdentifier(null)); + } + + private function getMetadataForEmbeddedDocument(): ClassMetadata + { + $metadata = new ClassMetadata(EmbeddedDocument::class); + + $metadata->fieldMappings = [ + 'plainField' => [ + 'fieldName' => 'plainField', + 'columnName' => 'plainField', + 'type' => 'boolean', + ], + ]; + + return $metadata; + } + + private function getMetadataForAssociatedDocument(): ClassMetadata + { + $embeddedDocumentClass = EmbeddedDocument::class; + + $metadata = new ClassMetadata(AssociatedDocument::class); + + $metadata->fieldMappings = [ + 'plainField' => [ + 'fieldName' => 'plainField', + 'name' => 'plainField', + 'columnName' => 'plainField', + 'type' => 'string', + ], + ]; + + $metadata->mapOneEmbedded([ + 'fieldName' => 'embeddedDocument', + 'name' => 'embeddedDocument', + 'targetDocument' => $embeddedDocumentClass, + ]); + + return $metadata; + } + + private function getMetadataForContainerDocument(): ClassMetadata + { + $containerDocumentClass = ContainerDocument::class; + $associatedDocumentClass = AssociatedDocument::class; + $embeddedDocumentClass = EmbeddedDocument::class; + + $metadata = new ClassMetadata($containerDocumentClass); + + $metadata->fieldMappings = [ + 'plainField' => [ + 'fieldName' => 'plainField', + 'name' => 'plainField', + 'columnName' => 'plainField', + 'type' => 'integer', + ], + ]; + + $metadata->associationMappings['associatedDocument'] = [ + 'fieldName' => 'associatedDocument', + 'name' => 'associatedDocument', + 'targetDocument' => $associatedDocumentClass, + 'sourceDocument' => $containerDocumentClass, + ]; + + $metadata->mapOneEmbedded([ + 'fieldName' => 'embeddedDocument', + 'name' => 'embeddedDocument', + 'targetDocument' => $embeddedDocumentClass, + ]); + + return $metadata; } }