test child element ordering

This commit is contained in:
Yisroel Baum 2026-06-22 09:42:11 +03:00
parent 14de828b4b
commit 7323925319
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
3 changed files with 505 additions and 0 deletions

View file

@ -0,0 +1,237 @@
<?php
namespace Tests\Unit\Element\UseCases;
use App\Element\CreateElementDto;
use App\Element\Element;
use App\Element\UseCases\ReorderChildElements\ReorderChildElements;
use App\Element\UseCases\ReorderChildElements\ReorderChildElementsRequest;
use App\Exceptions\BadRequestException;
use App\Exceptions\NotFoundException;
use App\Set\Set as DomainSet;
use Tests\Fakes\FakeElementRepository;
use Tests\TestCase;
class ReorderChildElementsTest extends TestCase
{
private FakeElementRepository $elementRepository;
private ReorderChildElements $reorderChildElements;
protected function setUp(): void
{
$this->elementRepository = new FakeElementRepository();
$this->reorderChildElements = new ReorderChildElements(
$this->elementRepository,
);
}
public function testReordersDirectChildElements(): void
{
$set = $this->createSet(1, 'Baderech');
$parentElement = $this->createElement($set, 'Parent', null);
$firstChildElement = $this->createElement(
$set,
'First child',
$parentElement,
);
$secondChildElement = $this->createElement(
$set,
'Second child',
$parentElement,
);
$thirdChildElement = $this->createElement(
$set,
'Third child',
$parentElement,
);
$this->createElement($set, 'Nested child', $firstChildElement);
$childElements = $this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: $parentElement->getId(),
childElementIds: [
$thirdChildElement->getId(),
$firstChildElement->getId(),
$secondChildElement->getId(),
],
)
);
$this->assertSame(
[
$thirdChildElement->getId(),
$firstChildElement->getId(),
$secondChildElement->getId(),
],
$this->elementIds($childElements),
);
$this->assertSame(
[
$thirdChildElement->getId(),
$firstChildElement->getId(),
$secondChildElement->getId(),
],
$this->elementIds(
$this->elementRepository->findByParentElement($parentElement),
),
);
}
public function testThrowsWhenParentElementIsMissing(): void
{
$this->expectException(NotFoundException::class);
$this->expectExceptionMessage('Parent element not found');
$this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: 999,
childElementIds: [1, 2],
)
);
}
public function testThrowsWhenChildIdsAreMissing(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('childElementIds is required');
$this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: 1,
childElementIds: null,
)
);
}
public function testThrowsWhenChildOrderHasDuplicates(): void
{
$set = $this->createSet(1, 'Baderech');
$parentElement = $this->createElement($set, 'Parent', null);
$firstChildElement = $this->createElement(
$set,
'First child',
$parentElement,
);
$secondChildElement = $this->createElement(
$set,
'Second child',
$parentElement,
);
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('Child order contains duplicate ids');
$this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: $parentElement->getId(),
childElementIds: [
$firstChildElement->getId(),
$firstChildElement->getId(),
$secondChildElement->getId(),
],
)
);
}
public function testThrowsWhenChildOrderHasInvalidElement(): void
{
$set = $this->createSet(1, 'Baderech');
$parentElement = $this->createElement($set, 'Parent', null);
$firstChildElement = $this->createElement(
$set,
'First child',
$parentElement,
);
$secondChildElement = $this->createElement(
$set,
'Second child',
$parentElement,
);
$nestedChildElement = $this->createElement(
$set,
'Nested child',
$firstChildElement,
);
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('Child order contains invalid child');
$this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: $parentElement->getId(),
childElementIds: [
$firstChildElement->getId(),
$nestedChildElement->getId(),
$secondChildElement->getId(),
],
)
);
}
public function testThrowsWhenChildOrderOmitsDirectChild(): void
{
$set = $this->createSet(1, 'Baderech');
$parentElement = $this->createElement($set, 'Parent', null);
$firstChildElement = $this->createElement(
$set,
'First child',
$parentElement,
);
$this->createElement($set, 'Second child', $parentElement);
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage(
'Child order must include every direct child',
);
$this->reorderChildElements->execute(
new ReorderChildElementsRequest(
parentElementId: $parentElement->getId(),
childElementIds: [$firstChildElement->getId()],
)
);
}
private function createSet(int $id, string $name): DomainSet
{
return new DomainSet(
id: $id,
name: $name,
description: "$name description",
iconImageUrl: '/assets/baderech-icon.png',
);
}
private function createElement(
DomainSet $set,
string $title,
?Element $parentElement,
): Element {
return $this->elementRepository->create(new CreateElementDto(
set: $set,
title: $title,
description: "$title description",
iconImageUrl: null,
richText: '',
shortPdfPath: null,
longPdfPath: null,
youtubeUrl: null,
parentElement: $parentElement,
));
}
/**
* @param Element[] $elements
* @return int[]
*/
private function elementIds(array $elements): array
{
$elementIds = [];
foreach ($elements as $element) {
$elementIds[] = $element->getId();
}
return $elementIds;
}
}