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; } }