瀏覽代碼

complete unit tests

Olivier Massot 11 月之前
父節點
當前提交
2a821c5779
共有 2 個文件被更改,包括 185 次插入5 次删除
  1. 9 3
      src/Service/Utils/EntityUtils.php
  2. 176 2
      tests/Unit/Service/Utils/EntityUtilsTest.php

+ 9 - 3
src/Service/Utils/EntityUtils.php

@@ -14,6 +14,11 @@ use Doctrine\ORM\EntityManagerInterface;
  */
 class EntityUtils
 {
+    /**
+     * Cache of the mapping between entity names and fully qualified names
+     *
+     * @var array<string, string>
+     */
     protected array $entityNamesMappingCache = [];
 
     public function __construct(
@@ -84,7 +89,7 @@ class EntityUtils
             $this->populateEntityNamesMappingCache();
         }
         if (!isset($this->entityNamesMappingCache[$entityName])) {
-            throw new \LogicException('No entity found for name '.$entityName);
+            throw new \LogicException('No entity found for name `'.$entityName.'`');
         }
         return $this->entityNamesMappingCache[$entityName];
 
@@ -96,6 +101,7 @@ class EntityUtils
      * @return void
      */
     protected function populateEntityNamesMappingCache() : void {
+        $this->entityNamesMappingCache = [];
         $metadata = $this->entityManager->getMetadataFactory()->getAllMetadata();
         foreach ($metadata as $entityMetadata) {
             $baseName = $this->getEntityNameFromFullName($entityMetadata->getName());
@@ -105,7 +111,7 @@ class EntityUtils
 
     /**
      * Get the namespace from a fully qualified name
-     * Ex: '\App\Entity\Core\File' => '\App\Entity\Core'
+     * Ex: '\App\Entity\Core\File' => 'App\Entity\Core'
      *
      * @param string $entityName
      * @return string|null
@@ -114,6 +120,6 @@ class EntityUtils
     {
         $parts = explode('\\', $entityName);
         array_pop($parts);
-        return implode('\\', $parts);
+        return ltrim(implode('\\', $parts), '\\');
     }
 }

+ 176 - 2
tests/Unit/Service/Utils/EntityUtilsTest.php

@@ -9,12 +9,21 @@ use App\Entity\Education\EducationTiming;
 use App\Entity\Organization\Organization;
 use App\Service\Utils\EntityUtils;
 use Doctrine\ORM\EntityManagerInterface;
+use Doctrine\Persistence\Mapping\ClassMetadata;
+use Doctrine\Persistence\Mapping\ClassMetadataFactory;
 use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
-use Symfony\Component\Mercure\HubInterface;
 
 class TestableEntityUtils extends EntityUtils
 {
+    public function getEntityNamesMappingCache(): array {
+        return $this->entityNamesMappingCache;
+    }
+
+    public function setEntityNamesMappingCache(array $entityNamesMappingCache) {
+        $this->entityNamesMappingCache = $entityNamesMappingCache;
+    }
+
     public function organizationDefaultValue($entity, Access $access): void
     {
         parent::organizationDefaultValue($entity, $access);
@@ -24,6 +33,11 @@ class TestableEntityUtils extends EntityUtils
     {
         parent::billingSettingDefaultValueDefaultValue($entity, $access);
     }
+
+    public function populateEntityNamesMappingCache(): void
+    {
+        parent::populateEntityNamesMappingCache();
+    }
 }
 
 class EntityUtilsTest extends TestCase
@@ -38,7 +52,7 @@ class EntityUtilsTest extends TestCase
     {
         return $this->getMockBuilder(TestableEntityUtils::class)
             ->setConstructorArgs([$this->entityManager])
-            ->setMethodsExcept([$method])
+            ->setMethodsExcept(['getEntityNamesMappingCache', 'setEntityNamesMappingCache', $method])
             ->getMock();
     }
 
@@ -98,4 +112,164 @@ class EntityUtilsTest extends TestCase
 
         $this->assertEquals($billingSetting, $entity->getBillingSetting());
     }
+
+    public function testGetEntityNameFromFullName(): void {
+        $utils = $this->getEntityUtilsMockFor('getEntityNameFromFullName');
+
+        $this->assertEquals(
+            'File',
+            $utils->getEntityNameFromFullName('\App\Entity\Core\File')
+        );
+        $this->assertEquals(
+            'File',
+            $utils->getEntityNameFromFullName('\File')
+        );
+        $this->assertEquals(
+            'File',
+            $utils->getEntityNameFromFullName('File')
+        );
+    }
+
+    public function testGetFullNameFromEntityName(): void {
+        $utils = $this->getEntityUtilsMockFor('getFullNameFromEntityName');
+
+        $utils->setEntityNamesMappingCache(['File' => '\App\Entity\Core\File']);
+
+        $utils->expects(self::never())->method('populateEntityNamesMappingCache');
+
+        $this->assertEquals(
+            '\App\Entity\Core\File',
+            $utils->getFullNameFromEntityName('File')
+        );
+    }
+
+    public function testGetFullNameFromEntityNameEmptyCache(): void {
+        $utils = $this->getEntityUtilsMockFor('getFullNameFromEntityName');
+
+        $utils->setEntityNamesMappingCache([]);
+
+        $utils
+            ->expects(self::once())
+            ->method('populateEntityNamesMappingCache')
+            ->willReturnCallback(function () use ($utils) {
+                $utils->setEntityNamesMappingCache(['File' => '\App\Entity\Core\File']);})
+        ;
+
+        $this->assertEquals(
+            '\App\Entity\Core\File',
+            $utils->getFullNameFromEntityName('File')
+        );
+    }
+
+    public function testGetFullNameFromEntityNameNonExistingEntity(): void {
+        $utils = $this->getEntityUtilsMockFor('getFullNameFromEntityName');
+
+        $utils->setEntityNamesMappingCache(['File' => '\App\Entity\Core\File']);
+
+        $utils->expects(self::never())->method('populateEntityNamesMappingCache');
+
+        $this->expectException(\LogicException::class);
+        $this->expectExceptionMessage('No entity found for name `Foo`');
+
+        $utils->getFullNameFromEntityName('Foo');
+    }
+
+    public function testPopulateEntityNamesMappingCache(): void {
+        $utils = $this->getEntityUtilsMockFor('populateEntityNamesMappingCache');
+
+        $metadataFactory = $this->getMockBuilder(ClassMetadataFactory::class)->getMock();
+
+        $this->entityManager
+            ->expects(self::once())
+            ->method('getMetadataFactory')
+            ->willReturn($metadataFactory);
+
+        $entityMetadata1 = $this->getMockBuilder(ClassMetadata::class)->getMock();
+        $entityMetadata1->method('getName')->willReturn('/Namespace/Entity1');
+
+        $entityMetadata2 = $this->getMockBuilder(ClassMetadata::class)->getMock();
+        $entityMetadata2->method('getName')->willReturn('/Namespace/Entity2');
+
+        $entityMetadata3 = $this->getMockBuilder(ClassMetadata::class)->getMock();
+        $entityMetadata3->method('getName')->willReturn('/Namespace/Entity3');
+
+        $metadataFactory
+            ->method('getAllMetadata')
+            ->willReturn([$entityMetadata1, $entityMetadata2, $entityMetadata3]);
+
+        $utils->method('getEntityNameFromFullName')->willReturnMap(
+            [
+                ['/Namespace/Entity1', 'Entity1'],
+                ['/Namespace/Entity2', 'Entity2'],
+                ['/Namespace/Entity3', 'Entity3'],
+            ]
+        );
+
+        $this->assertEquals(
+            [],
+            $utils->getEntityNamesMappingCache()
+        );
+
+        $utils->populateEntityNamesMappingCache();
+
+        $this->assertEquals(
+            [
+                'Entity1' => '/Namespace/Entity1',
+                'Entity2' => '/Namespace/Entity2',
+                'Entity3' => '/Namespace/Entity3',
+            ],
+            $utils->getEntityNamesMappingCache()
+        );
+    }
+
+    public function testPopulateEntityNamesMappingCacheWithExistingCache(): void {
+        $utils = $this->getEntityUtilsMockFor('populateEntityNamesMappingCache');
+
+        $metadataFactory = $this->getMockBuilder(ClassMetadataFactory::class)->getMock();
+
+        $this->entityManager
+            ->expects(self::once())
+            ->method('getMetadataFactory')
+            ->willReturn($metadataFactory);
+
+        $entityMetadata1 = $this->getMockBuilder(ClassMetadata::class)->getMock();
+        $entityMetadata1->method('getName')->willReturn('/Namespace/Entity');
+
+        $metadataFactory
+            ->method('getAllMetadata')
+            ->willReturn([$entityMetadata1]);
+
+        $utils->method('getEntityNameFromFullName')->willReturnMap(
+            [
+                ['/Namespace/Entity', 'Entity'],
+            ]
+        );
+
+        $utils->setEntityNamesMappingCache(['OtherEntity' => '/Namespace/OtherEntity']);
+
+        $this->assertEquals(
+            ['OtherEntity' => '/Namespace/OtherEntity',],
+            $utils->getEntityNamesMappingCache()
+        );
+
+        $utils->populateEntityNamesMappingCache();
+
+        $this->assertEquals(
+            ['Entity' => '/Namespace/Entity'],
+            $utils->getEntityNamesMappingCache()
+        );
+    }
+
+    public function testGetNamespaceFromName(): void {
+        $utils = $this->getEntityUtilsMockFor('getNamespaceFromName');
+
+        $this->assertEquals(
+            'App\Entity\Core',
+            $utils->getNamespaceFromName('\App\Entity\Core\File')
+        );
+        $this->assertEquals(
+            '',
+            $utils->getNamespaceFromName('\File')
+        );
+    }
 }