Kaynağa Gözat

add unit tests and minor fixes to Tree services

Olivier Massot 2 ay önce
ebeveyn
işleme
db402f3f1e

+ 1 - 1
src/Service/Utils/Tree/BaseResourceTree.php

@@ -4,7 +4,7 @@ declare(strict_types=1);
 
 namespace App\Service\Utils\Tree;
 
-class BaseResourceTree implements ResourceTreeInterface
+abstract class BaseResourceTree implements ResourceTreeInterface
 {
     /**
      * @var array<string> | array<string, array<string, string>> | array<string, array<string, array<string, string>>>>>

+ 3 - 13
src/Service/Utils/Tree/ResourceTreeBuilder.php

@@ -65,11 +65,6 @@ class ResourceTreeBuilder
                 }
             }
 
-            if ($level2PropName === null) {
-                // Si pas de niveau 2, on passe à l'item suivant
-                continue;
-            }
-
             $level2Value = self::callGetter($item, $level2PropName);
 
             if (!array_key_exists($level2Value, $content[$level1Value])) {
@@ -83,15 +78,10 @@ class ResourceTreeBuilder
                 }
             }
 
-            if ($level3PropName === null) {
-                // Si pas de niveau 3, on passe à l'item suivant
-                continue;
-            }
-
             $level3Value = self::callGetter($item, $level3PropName);
 
-            if (!array_key_exists($level3PropName, $content[$level1Value][$level2Value])) {
-                $content[$level1Value][$level2Value][] = $level1Value;
+            if (!in_array($level3Value, $content[$level1Value][$level2Value])) {
+                $content[$level1Value][$level2Value][] = $level3Value;
             }
         }
 
@@ -108,7 +98,7 @@ class ResourceTreeBuilder
 
         $value = $object->$getterName();
 
-        if ((new \ReflectionClass($value))->isEnum()) {
+        if (is_object($value) && (new \ReflectionClass($value))->isEnum()) {
             return $value->value;
         }
 

+ 220 - 0
tests/Unit/Service/Utils/Tree/ResourceTreeBuilderTest.php

@@ -0,0 +1,220 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Tests\Unit\Service\Utils\Tree;
+
+use App\Service\Utils\Tree\ResourceTreeBuilder;
+use PHPUnit\Framework\TestCase;
+use PHPUnit\Framework\MockObject\MockObject;
+
+// Classes de test pour simuler les objets avec des getters
+class TestResource
+{
+    public function __construct(
+        private string $category,
+        private string $subCategory,
+        private string $value,
+        private string $name = 'default'
+    ) {
+    }
+
+    public function getCategory(): string
+    {
+        return $this->category;
+    }
+
+    public function getSubCategory(): string
+    {
+        return $this->subCategory;
+    }
+
+    public function getValue(): string
+    {
+        return $this->value;
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+}
+
+class TestResourceWithEnum
+{
+    public function __construct(
+        private TestEnum $category,
+        private string $name = 'default'
+    ) {
+    }
+
+    public function getCategory(): TestEnum
+    {
+        return $this->category;
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+}
+
+enum TestEnum: string
+{
+    case CATEGORY_A = 'category-a';
+    case CATEGORY_B = 'category-b';
+}
+
+// Classe testable pour accéder aux méthodes protected
+class TestableResourceTreeBuilder extends ResourceTreeBuilder
+{
+    public static function callGetterPublic($object, $propName): string
+    {
+        return parent::callGetter($object, $propName);
+    }
+}
+
+class ResourceTreeBuilderTest extends TestCase
+{
+    private function getResourceTreeBuilderMockFor(string $methodName): TestableResourceTreeBuilder|MockObject
+    {
+        return $this->getMockBuilder(TestableResourceTreeBuilder::class)
+            ->setMethodsExcept([$methodName])
+            ->getMock();
+    }
+
+    /**
+     * @see ResourceTreeBuilder::makeTree()
+     */
+    public function testMakeTree(): void
+    {
+        $data = [
+            new TestResource('category1', 'sub1', 'item1'),
+            new TestResource('category1', 'sub1', 'item2'),
+            new TestResource('category1', 'sub2', 'item3'),
+            new TestResource('category2', 'sub3', 'item4'),
+        ];
+
+        $result = ResourceTreeBuilder::makeTree($data, 'category', 'subCategory', 'value');
+
+        $expected = [
+            'category1' => [
+                'sub1' => ['item1', 'item2'],
+                'sub2' => ['item3'],
+            ],
+            'category2' => [
+                'sub3' => ['item4'],
+            ],
+        ];
+
+        self::assertEquals($expected, $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::makeTree()
+     */
+    public function testMakeTreeWithOneLevel(): void
+    {
+        $data = [
+            new TestResource('category1', 'sub1', 'item1', 'name1'),
+            new TestResource('category2', 'sub2', 'item2', 'name2'),
+            new TestResource('category1', 'sub3', 'item3', 'name3'),
+        ];
+
+        $result = ResourceTreeBuilder::makeTree($data);
+
+        $expected = ['name1', 'name2', 'name3'];
+
+        self::assertEquals($expected, $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::makeTree()
+     */
+    public function testMakeTreeWithTwoLevels(): void
+    {
+        $data = [
+            new TestResource('category1', 'sub1', 'item1'),
+            new TestResource('category1', 'sub2', 'item2'),
+            new TestResource('category2', 'sub1', 'item3'),
+        ];
+
+        $result = ResourceTreeBuilder::makeTree($data, 'category', 'subCategory');
+
+        $expected = [
+            'category1' => ['sub1', 'sub2'],
+            'category2' => ['sub1'],
+        ];
+
+        self::assertEquals($expected, $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::makeTree()
+     */
+    public function testMakeTreeWithEmptyData(): void
+    {
+        $result = ResourceTreeBuilder::makeTree([]);
+
+        self::assertEquals([], $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::callGetter()
+     */
+    public function testCallGetter(): void
+    {
+        $resource = new TestResource('cat1', 'sub1', 'val1');
+
+        $result = TestableResourceTreeBuilder::callGetterPublic($resource, 'category');
+
+        self::assertEquals('cat1', $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::callGetter()
+     */
+    public function testCallGetterWithEnum(): void
+    {
+        $resource = new TestResourceWithEnum(TestEnum::CATEGORY_A);
+
+        $result = TestableResourceTreeBuilder::callGetterPublic($resource, 'category');
+
+        self::assertEquals('category-a', $result);
+    }
+
+    /**
+     * @see ResourceTreeBuilder::callGetter()
+     */
+    public function testCallGetterWithInvalidProperty(): void
+    {
+        $resource = new TestResource('cat1', 'sub1', 'val1');
+
+        $this->expectException(\InvalidArgumentException::class);
+        $this->expectExceptionMessage('Invalid property name');
+
+        TestableResourceTreeBuilder::callGetterPublic($resource, 'invalidProperty');
+    }
+
+    /**
+     * @see ResourceTreeBuilder::makeTree()
+     */
+    public function testMakeTreeWithDuplicateEntries(): void
+    {
+        $data = [
+            new TestResource('category1', 'sub1', 'item1'),
+            new TestResource('category1', 'sub1', 'item1'), // Duplicate
+            new TestResource('category1', 'sub1', 'item2'),
+        ];
+
+        $result = ResourceTreeBuilder::makeTree($data, 'category', 'subCategory', 'value');
+
+        $expected = [
+            'category1' => [
+                'sub1' => ['item1', 'item2'],
+            ],
+        ];
+
+        self::assertEquals($expected, $result);
+    }
+}