From 1ec4266f960df52b14b40d371a47001ad1fae5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 23 Jul 2023 01:01:29 +0200 Subject: [PATCH] Fixed sorting for element choice type and added tests --- ...ttachmentContainingDBElementRepository.php | 3 +- src/Repository/DBElementRepository.php | 19 +++- src/Services/Trees/NodesListBuilder.php | 2 +- ...hmentContainingDBElementRepositoryTest.php | 56 +++++++++++ tests/Repository/DBElementRepositoryTest.php | 92 +++++++++++++++++++ 5 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 tests/Repository/AttachmentContainingDBElementRepositoryTest.php create mode 100644 tests/Repository/DBElementRepositoryTest.php diff --git a/src/Repository/AttachmentContainingDBElementRepository.php b/src/Repository/AttachmentContainingDBElementRepository.php index 6b58ca05..de4d61cb 100644 --- a/src/Repository/AttachmentContainingDBElementRepository.php +++ b/src/Repository/AttachmentContainingDBElementRepository.php @@ -62,8 +62,7 @@ class AttachmentContainingDBElementRepository extends NamedDBElementRepository $q->setFetchMode($this->getEntityName(), 'master_picture_attachment', ClassMetadataInfo::FETCH_EAGER); $result = $q->getResult(); - $result = array_combine($ids, $result); - $result = array_map(fn ($id) => $result[$id], $ids); + $this->sortResultArrayByIDArray($result, $ids); //Cache the result $this->elementsAndPreviewAttachmentCache[$cache_key] = $result; diff --git a/src/Repository/DBElementRepository.php b/src/Repository/DBElementRepository.php index f187714b..534f3963 100644 --- a/src/Repository/DBElementRepository.php +++ b/src/Repository/DBElementRepository.php @@ -116,8 +116,9 @@ class DBElementRepository extends EntityRepository ->getQuery(); $result = $q->getResult(); - $result = array_combine($ids, $result); - $result = array_map(fn ($id) => $result[$id], $ids); + + //Sort the result so that the elements are in the same order as the input array + $this->sortResultArrayByIDArray($result, $ids); //Cache the result $this->find_elements_by_id_cache[$cache_key] = $result; @@ -125,6 +126,20 @@ class DBElementRepository extends EntityRepository return $result; } + /** + * The elements in the result array will be sorted, so that their order of their IDs matches the order of the IDs in the input array. + * @param array $result_array + * @phpstan-param list $result_array + * @param int[] $ids + * @return void + */ + protected function sortResultArrayByIDArray(array &$result_array, array $ids): void + { + usort($result_array, static function (AbstractDBElement $a, AbstractDBElement $b) use ($ids) { + return array_search($a->getID(), $ids, true) <=> array_search($b->getID(), $ids, true); + }); + } + protected function setField(AbstractDBElement $element, string $field, int $new_value): void { $reflection = new ReflectionClass($element::class); diff --git a/src/Services/Trees/NodesListBuilder.php b/src/Services/Trees/NodesListBuilder.php index b74f67c8..66299185 100644 --- a/src/Services/Trees/NodesListBuilder.php +++ b/src/Services/Trees/NodesListBuilder.php @@ -73,7 +73,7 @@ class NodesListBuilder return $repo->getElementsAndPreviewAttachmentByIDs($ids); } - return $repo->getElementsFromIDArray($ids); + return $repo->findByIDInMatchingOrder($ids); } /** diff --git a/tests/Repository/AttachmentContainingDBElementRepositoryTest.php b/tests/Repository/AttachmentContainingDBElementRepositoryTest.php new file mode 100644 index 00000000..e11bd138 --- /dev/null +++ b/tests/Repository/AttachmentContainingDBElementRepositoryTest.php @@ -0,0 +1,56 @@ +. + */ + +namespace App\Tests\Repository; + +use App\Entity\Parts\Category; +use App\Repository\AttachmentContainingDBElementRepository; +use Doctrine\ORM\EntityManagerInterface; +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; + +class AttachmentContainingDBElementRepositoryTest extends KernelTestCase +{ + + private EntityManagerInterface $entityManager; + + protected function setUp(): void + { + $kernel = self::bootKernel(); + + $this->entityManager = $kernel->getContainer() + ->get('doctrine')->getManager(); + } + + + public function testGetElementsAndPreviewAttachmentByIDs(): void + { + $repo = $this->entityManager->getRepository(Category::class); + + $elements = $repo->getElementsAndPreviewAttachmentByIDs([2, 1, 5, 3]); + + //Elements are ordered the same way as the ID array + $this->assertCount(4, $elements); + $this->assertSame(2, $elements[0]->getId()); + $this->assertSame(1, $elements[1]->getId()); + $this->assertSame(5, $elements[2]->getId()); + $this->assertSame(3, $elements[3]->getId()); + } +} diff --git a/tests/Repository/DBElementRepositoryTest.php b/tests/Repository/DBElementRepositoryTest.php new file mode 100644 index 00000000..c803302b --- /dev/null +++ b/tests/Repository/DBElementRepositoryTest.php @@ -0,0 +1,92 @@ +. + */ + +namespace App\Tests\Repository; + +use App\Entity\Attachments\Attachment; +use App\Entity\Attachments\PartAttachment; +use App\Entity\Parts\Category; +use App\Entity\Parts\Part; +use App\Entity\UserSystem\Group; +use App\Entity\UserSystem\User; +use App\Repository\DBElementRepository; +use Doctrine\ORM\EntityManagerInterface; +use PHPUnit\Framework\TestCase; +use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; + +class DBElementRepositoryTest extends KernelTestCase +{ + + private EntityManagerInterface $entityManager; + + protected function setUp(): void + { + $kernel = self::bootKernel(); + + $this->entityManager = $kernel->getContainer() + ->get('doctrine')->getManager(); + } + + public function testFindByIDInMatchingOrder(): void + { + $repo = $this->entityManager->getRepository(Category::class); + + $elements = $repo->findByIDInMatchingOrder([2, 1, 5, 3]); + + //Elements are ordered the same way as the ID array + $this->assertCount(4, $elements); + $this->assertSame(2, $elements[0]->getId()); + $this->assertSame(1, $elements[1]->getId()); + $this->assertSame(5, $elements[2]->getId()); + $this->assertSame(3, $elements[3]->getId()); + } + + public function testChangeID(): void + { + $repo = $this->entityManager->getRepository(User::class); + + $noread_user = $repo->findOneBy(['name' => 'noread']); + + $this->assertNotNull($noread_user); + $old_id = $noread_user->getId(); + + $repo->changeID($noread_user, 999999); + $this->assertSame(999999, $noread_user->getId()); + $this->assertNotSame($old_id, $noread_user->getId()); + + + //ID should be persistent + $this->entityManager->refresh($noread_user); + $this->assertSame(999999, $noread_user->getId()); + } + + public function testGetElementsFromIDArray(): void + { + $repo = $this->entityManager->getRepository(Category::class); + + $elements = $repo->getElementsFromIDArray([2, 1, 3]); + + //Elements are ordered by ID or + $this->assertCount(3, $elements); + $this->assertSame(1, $elements[0]->getId()); + $this->assertSame(2, $elements[1]->getId()); + $this->assertSame(3, $elements[2]->getId()); + } +}