test and impl that only one root node exists per text

in practice this means only one node with a null parentNode
This commit is contained in:
Yisroel Baum 2026-02-21 22:44:18 +02:00
parent 4f83ae7926
commit d1eb648b73
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
2 changed files with 37 additions and 0 deletions

View file

@ -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');
}
}
}

View file

@ -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,
));
}
}