Attainly/backend/tests/Unit/Set/UseCases/GetSetLayoutTest.php

144 lines
4.2 KiB
PHP

<?php
namespace Tests\Unit\Set\UseCases;
use App\Element\CreateElementDto;
use App\Exceptions\NotFoundException;
use App\Set\CreateSetDto;
use App\Set\UseCases\GetSetLayout\ElementLayoutNode;
use App\Set\UseCases\GetSetLayout\GetSetLayout;
use App\Set\UseCases\GetSetLayout\GetSetLayoutRequest;
use App\Shared\ValueObject\EmailAddress;
use App\User\User;
use PHPUnit\Framework\TestCase;
use Tests\Fakes\FakeElementRepository;
use Tests\Fakes\FakeSetRepository;
class GetSetLayoutTest extends TestCase
{
public function test_it_builds_an_ordered_element_tree(): void
{
$creator = new User(
id: 7,
email: new EmailAddress('creator@example.com'),
passwordHash: 'hashed-password',
);
$setRepository = new FakeSetRepository;
$elementRepository = new FakeElementRepository;
$bible = $setRepository->create(new CreateSetDto(
name: 'Bible',
creator: $creator,
));
$course = $setRepository->create(new CreateSetDto(
name: 'Course',
creator: $creator,
));
$genesis = $elementRepository->create(new CreateElementDto(
set: $bible,
name: 'Genesis',
kind: 'book',
parentElement: null,
));
$elementRepository->create(new CreateElementDto(
set: $bible,
name: 'Exodus',
kind: 'book',
parentElement: null,
));
$creation = $elementRepository->create(new CreateElementDto(
set: $bible,
name: 'Creation',
kind: 'portion',
parentElement: $genesis,
));
$elementRepository->create(new CreateElementDto(
set: $bible,
name: 'Noah',
kind: 'portion',
parentElement: $genesis,
));
$elementRepository->create(new CreateElementDto(
set: $bible,
name: 'Chapter 1',
kind: 'chapter',
parentElement: $creation,
));
$elementRepository->create(new CreateElementDto(
set: $course,
name: 'Foundations',
kind: 'module',
parentElement: null,
));
$layout = (new GetSetLayout(
$setRepository,
$elementRepository,
))->execute(new GetSetLayoutRequest(
setId: $bible->getId(),
));
$this->assertSame('Bible', $layout->getSet()->getName());
$this->assertSame(
['Genesis', 'Exodus'],
$this->nodeNames($layout->getElements()),
);
$genesisNode = $layout->getElements()[0];
$this->assertSame(
['Creation', 'Noah'],
$this->nodeNames($genesisNode->getChildren()),
);
$this->assertSame(
['Chapter 1'],
$this->nodeNames(
$genesisNode->getChildren()[0]->getChildren(),
),
);
}
public function test_it_returns_an_empty_layout(): void
{
$creator = new User(
id: 7,
email: new EmailAddress('creator@example.com'),
passwordHash: 'hashed-password',
);
$setRepository = new FakeSetRepository;
$set = $setRepository->create(new CreateSetDto(
name: 'Empty set',
creator: $creator,
));
$layout = (new GetSetLayout(
$setRepository,
new FakeElementRepository,
))->execute(new GetSetLayoutRequest(
setId: $set->getId(),
));
$this->assertSame([], $layout->getElements());
}
public function test_it_rejects_an_unknown_set(): void
{
$this->expectException(NotFoundException::class);
$this->expectExceptionMessage('set not found');
(new GetSetLayout(
new FakeSetRepository,
new FakeElementRepository,
))->execute(new GetSetLayoutRequest(
setId: 999,
));
}
/**
* @param list<ElementLayoutNode> $nodes
* @return list<string>
*/
private function nodeNames(array $nodes): array
{
return array_map(function ($node): string {
return $node->getElement()->getName();
}, $nodes);
}
}