From d1eb648b73d26a65f37c9597532c8085f24c3059 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Sat, 21 Feb 2026 22:44:18 +0200 Subject: [PATCH] test and impl that only one root node exists per text in practice this means only one node with a null parentNode --- app/Node/UseCases/CreateNode.php | 21 +++++++++++++++++++++ tests/Unit/Node/UseCases/CreateNodeTest.php | 16 ++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/app/Node/UseCases/CreateNode.php b/app/Node/UseCases/CreateNode.php index 25882f0..dcb8afa 100644 --- a/app/Node/UseCases/CreateNode.php +++ b/app/Node/UseCases/CreateNode.php @@ -15,6 +15,9 @@ class CreateNode private TextRepository $textRepo, ) {} + /** + * @throws DomainException + */ public function execute(CreateNodeRequest $request): Node { $textId = $request->textId; @@ -23,6 +26,7 @@ class CreateNode throw new DomainException("Text with id: $textId doesnt exist"); } if ($request->parentNodeId === null) { + $this->validateNoOtherRootNodeExists($textId); return $this->nodeRepo->create(new CreateNodeDto( text: $text, title: $request->title, @@ -41,4 +45,21 @@ class CreateNode parentNode: $parentNode, )); } + + /** + * @throws DomainException + */ + private function validateNoOtherRootNodeExists(int $textId): void + { + $nodesOfText = $this->nodeRepo->findByTextId($textId); + $exists = array_find( + $nodesOfText, + function (Node $node) { + return $node->getParentNode() === null; + } + ); + if ($exists) { + throw new DomainException('A root node already exists for this text'); + } + } } diff --git a/tests/Unit/Node/UseCases/CreateNodeTest.php b/tests/Unit/Node/UseCases/CreateNodeTest.php index 38ae268..e617079 100644 --- a/tests/Unit/Node/UseCases/CreateNodeTest.php +++ b/tests/Unit/Node/UseCases/CreateNodeTest.php @@ -95,4 +95,20 @@ class CreateNodeTest extends TestCase parentNodeId: 0, )); } + + public function test_one_root_node_per_text(): void + { + $this->expectException(DomainException::class); + $this->expectExceptionMessage('A root node already exists for this text'); + $this->useCase->execute(new CreateNodeRequest( + textId: 0, + title: 'test', + parentNodeId: null, + )); + $this->useCase->execute(new CreateNodeRequest( + textId: 0, + title: 'test', + parentNodeId: null, + )); + } }