Goal-Calibration/tests/Unit/Node/UseCases/CreateNodeTest.php
Yisroel Baum cbbbc80326
update downstream tests for text user requirement
Text now requires a User on construction. seed a user in
each test setUp that creates a Text directly or through the
fake repository so the suite remains green.
2026-05-02 21:27:55 +03:00

149 lines
4.3 KiB
PHP

<?php
namespace Tests\Unit\Node\UseCases;
use App\Exceptions\BadRequestException;
use App\Node\Node;
use App\Node\NodeRepository;
use App\Node\UseCases\CreateNode;
use App\Node\UseCases\CreateNodeRequest;
use App\Text\CreateTextDto;
use App\Text\Text;
use App\User\UseCases\CreateUserDto;
use App\ValueObjects\EmailAddress;
use DomainException;
use PHPUnit\Framework\TestCase;
use Tests\Fakes\FakeNodeRepository;
use Tests\Fakes\FakeTextRepository;
use Tests\Fakes\FakeUserRepository;
class CreateNodeTest extends TestCase
{
private FakeTextRepository $textRepo;
private FakeNodeRepository $nodeRepo;
private CreateNode $useCase;
public function setUp(): void
{
$userRepo = new FakeUserRepository();
$user = $userRepo->create(new CreateUserDto(
email: new EmailAddress('a@b.com'),
passwordHash: '',
isAdmin: false,
));
$this->textRepo = new FakeTextRepository();
$this->textRepo->create(new CreateTextDto(
name: 'text',
user: $user,
));
$this->nodeRepo = new FakeNodeRepository();
$this->useCase = new CreateNode(
nodeRepo: $this->nodeRepo,
textRepo: $this->textRepo,
);
}
public function test_create_node(): void
{
$node = $this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: 'test',
parentNodeId: null,
));
$this->assertInstanceOf(NodeRepository::class, $this->nodeRepo);
$this->assertInstanceOf(Node::class, $node);
$this->assertEquals('test', $node->getTitle());
$this->assertEquals(0, $node->getId());
$this->assertEquals(null, $node->getParentNode());
}
public function test_node_belongs_to_text(): void
{
$node = $this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: 'test',
parentNodeId: null,
));
$this->assertInstanceOf(Text::class, $node->getText());
}
public function test_throws_if_text_doesnt_exist(): void
{
$this->expectException(DomainException::class);
$this->expectExceptionMessage("Text with id: 1 doesnt exist");
$this->useCase->execute(new CreateNodeRequest(
textId: 1,
title: 'test',
parentNodeId: null,
));
}
public function test_has_parent_node(): void
{
$node1 = $this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: 'test',
parentNodeId: null,
));
$node2 = $this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: 'test',
parentNodeId: $node1->getId(),
));
$this->assertEquals(
$node1->getId(),
$node2->getParentNode()->getId()
);
}
public function test_nonexistant_parent_id_throws(): void
{
$this->expectException(DomainException::class);
$this->expectExceptionMessage("Node with id: 0 doesnt exist");
$this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: 'test',
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,
));
}
public function test_throws_if_text_id_is_null(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('textId is required');
$this->useCase->execute(new CreateNodeRequest(
textId: null,
title: 'test',
parentNodeId: null,
));
}
public function test_throws_if_title_is_null(): void
{
$this->expectException(BadRequestException::class);
$this->expectExceptionMessage('title is required');
$this->useCase->execute(new CreateNodeRequest(
textId: 0,
title: null,
parentNodeId: null,
));
}
}