test enforced element levels

This commit is contained in:
Yisroel Baum 2026-08-11 22:48:53 +03:00
parent 0d102fcee0
commit 25495b6c4d
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
2 changed files with 100 additions and 36 deletions

View file

@ -5,7 +5,10 @@ namespace Tests\Feature\Element;
use App\Element\CreateElementDto; use App\Element\CreateElementDto;
use App\Element\ElementRepository; use App\Element\ElementRepository;
use App\Set\CreateSetDto; use App\Set\CreateSetDto;
use App\Set\CreateSetLevelDto;
use App\Set\Set; use App\Set\Set;
use App\Set\SetLevel;
use App\Set\SetLevelRepository;
use App\Set\SetRepository; use App\Set\SetRepository;
use App\Shared\ValueObject\EmailAddress; use App\Shared\ValueObject\EmailAddress;
use App\User\CreateUserDto; use App\User\CreateUserDto;
@ -22,28 +25,26 @@ class EloquentElementRepositoryTest extends TestCase
{ {
$set = $this->createSet('Bible'); $set = $this->createSet('Bible');
$repository = app(ElementRepository::class); $repository = app(ElementRepository::class);
$bookLevel = $this->createLevel($set, 'book');
$portionLevel = $this->createLevel($set, 'portion');
$genesisBook = $repository->create(new CreateElementDto( $genesisBook = $repository->create(new CreateElementDto(
set: $set,
name: 'Genesis', name: 'Genesis',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
$exodusBook = $repository->create(new CreateElementDto( $exodusBook = $repository->create(new CreateElementDto(
set: $set,
name: 'Exodus', name: 'Exodus',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
$genesisPortion = $repository->create(new CreateElementDto( $genesisPortion = $repository->create(new CreateElementDto(
set: $set,
name: 'Genesis', name: 'Genesis',
kind: 'portion', level: $portionLevel,
parentElement: $genesisBook, parentElement: $genesisBook,
)); ));
$noahPortion = $repository->create(new CreateElementDto( $noahPortion = $repository->create(new CreateElementDto(
set: $set,
name: 'Noah', name: 'Noah',
kind: 'portion', level: $portionLevel,
parentElement: $genesisBook, parentElement: $genesisBook,
)); ));
@ -53,9 +54,8 @@ class EloquentElementRepositoryTest extends TestCase
$this->assertSame(2, $noahPortion->getPosition()); $this->assertSame(2, $noahPortion->getPosition());
$this->assertDatabaseHas('elements', [ $this->assertDatabaseHas('elements', [
'id' => $genesisPortion->getId(), 'id' => $genesisPortion->getId(),
'set_id' => $set->getId(), 'set_level_id' => $portionLevel->getId(),
'name' => 'Genesis', 'name' => 'Genesis',
'kind' => 'portion',
'parent_element_id' => $genesisBook->getId(), 'parent_element_id' => $genesisBook->getId(),
'position' => 1, 'position' => 1,
]); ]);
@ -65,6 +65,10 @@ class EloquentElementRepositoryTest extends TestCase
$this->assertNotNull($foundElement); $this->assertNotNull($foundElement);
$this->assertSame('Noah', $foundElement->getName()); $this->assertSame('Noah', $foundElement->getName());
$this->assertSame('portion', $foundElement->getKind()); $this->assertSame('portion', $foundElement->getKind());
$this->assertSame(
$portionLevel->getId(),
$foundElement->getLevel()->getId(),
);
$this->assertSame($set->getId(), $foundElement->getSet()->getId()); $this->assertSame($set->getId(), $foundElement->getSet()->getId());
$this->assertSame( $this->assertSame(
$genesisBook->getId(), $genesisBook->getId(),
@ -77,10 +81,11 @@ class EloquentElementRepositoryTest extends TestCase
$bible = $this->createSet('Bible'); $bible = $this->createSet('Bible');
$course = $this->createSet('Course'); $course = $this->createSet('Course');
$repository = app(ElementRepository::class); $repository = app(ElementRepository::class);
$bookLevel = $this->createLevel($bible, 'book');
$moduleLevel = $this->createLevel($course, 'module');
$book = $repository->create(new CreateElementDto( $book = $repository->create(new CreateElementDto(
set: $bible,
name: 'Genesis', name: 'Genesis',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
@ -90,9 +95,51 @@ class EloquentElementRepositoryTest extends TestCase
); );
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $course,
name: 'Invalid lesson', name: 'Invalid lesson',
kind: 'lesson', level: $moduleLevel,
parentElement: $book,
));
}
public function testItRejectsARootOutsideTheFirstLevel(): void
{
$set = $this->createSet('Bible');
$this->createLevel($set, 'book');
$portionLevel = $this->createLevel($set, 'portion');
$this->expectException(DomainException::class);
$this->expectExceptionMessage(
'root element must use the first set level',
);
app(ElementRepository::class)->create(new CreateElementDto(
name: 'Creation',
level: $portionLevel,
parentElement: null,
));
}
public function testItRejectsAChildOutsideTheNextLevel(): void
{
$set = $this->createSet('Bible');
$bookLevel = $this->createLevel($set, 'book');
$this->createLevel($set, 'portion');
$chapterLevel = $this->createLevel($set, 'chapter');
$repository = app(ElementRepository::class);
$book = $repository->create(new CreateElementDto(
name: 'Genesis',
level: $bookLevel,
parentElement: null,
));
$this->expectException(DomainException::class);
$this->expectExceptionMessage(
'child element must use the next set level',
);
$repository->create(new CreateElementDto(
name: 'Chapter 1',
level: $chapterLevel,
parentElement: $book, parentElement: $book,
)); ));
} }
@ -102,40 +149,37 @@ class EloquentElementRepositoryTest extends TestCase
$bible = $this->createSet('Bible'); $bible = $this->createSet('Bible');
$course = $this->createSet('Course'); $course = $this->createSet('Course');
$repository = app(ElementRepository::class); $repository = app(ElementRepository::class);
$bookLevel = $this->createLevel($bible, 'book');
$portionLevel = $this->createLevel($bible, 'portion');
$moduleLevel = $this->createLevel($course, 'module');
$genesisBook = $repository->create(new CreateElementDto( $genesisBook = $repository->create(new CreateElementDto(
set: $bible,
name: 'Genesis', name: 'Genesis',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
$exodusBook = $repository->create(new CreateElementDto( $exodusBook = $repository->create(new CreateElementDto(
set: $bible,
name: 'Exodus', name: 'Exodus',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $course,
name: 'Module 1', name: 'Module 1',
kind: 'module', level: $moduleLevel,
parentElement: null, parentElement: null,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $bible,
name: 'Genesis', name: 'Genesis',
kind: 'portion', level: $portionLevel,
parentElement: $genesisBook, parentElement: $genesisBook,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $bible,
name: 'Noah', name: 'Noah',
kind: 'portion', level: $portionLevel,
parentElement: $genesisBook, parentElement: $genesisBook,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $bible,
name: 'Shemot', name: 'Shemot',
kind: 'portion', level: $portionLevel,
parentElement: $exodusBook, parentElement: $exodusBook,
)); ));
@ -161,22 +205,22 @@ class EloquentElementRepositoryTest extends TestCase
$bible = $this->createSet('Bible'); $bible = $this->createSet('Bible');
$course = $this->createSet('Course'); $course = $this->createSet('Course');
$repository = app(ElementRepository::class); $repository = app(ElementRepository::class);
$bookLevel = $this->createLevel($bible, 'book');
$portionLevel = $this->createLevel($bible, 'portion');
$moduleLevel = $this->createLevel($course, 'module');
$genesis = $repository->create(new CreateElementDto( $genesis = $repository->create(new CreateElementDto(
set: $bible,
name: 'Genesis', name: 'Genesis',
kind: 'book', level: $bookLevel,
parentElement: null, parentElement: null,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $bible,
name: 'Creation', name: 'Creation',
kind: 'portion', level: $portionLevel,
parentElement: $genesis, parentElement: $genesis,
)); ));
$repository->create(new CreateElementDto( $repository->create(new CreateElementDto(
set: $course,
name: 'Foundations', name: 'Foundations',
kind: 'module', level: $moduleLevel,
parentElement: null, parentElement: null,
)); ));
@ -207,4 +251,12 @@ class EloquentElementRepositoryTest extends TestCase
creator: $creator, creator: $creator,
)); ));
} }
private function createLevel(Set $set, string $kind): SetLevel
{
return app(SetLevelRepository::class)->create(new CreateSetLevelDto(
set: $set,
kind: $kind,
));
}
} }

View file

@ -4,6 +4,7 @@ namespace Tests\Unit\Element;
use App\Element\Element; use App\Element\Element;
use App\Set\Set; use App\Set\Set;
use App\Set\SetLevel;
use App\Shared\ValueObject\EmailAddress; use App\Shared\ValueObject\EmailAddress;
use App\User\User; use App\User\User;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -22,19 +23,29 @@ class ElementTest extends TestCase
name: 'Bible', name: 'Bible',
creator: $creator, creator: $creator,
); );
$bookLevel = new SetLevel(
id: 31,
set: $set,
kind: 'book',
depth: 0,
);
$portionLevel = new SetLevel(
id: 32,
set: $set,
kind: 'portion',
depth: 1,
);
$parentElement = new Element( $parentElement = new Element(
id: 21, id: 21,
name: 'Genesis', name: 'Genesis',
kind: 'book', level: $bookLevel,
set: $set,
parentElement: null, parentElement: null,
position: 1, position: 1,
); );
$element = new Element( $element = new Element(
id: 22, id: 22,
name: 'Genesis', name: 'Genesis',
kind: 'portion', level: $portionLevel,
set: $set,
parentElement: $parentElement, parentElement: $parentElement,
position: 2, position: 2,
); );
@ -42,6 +53,7 @@ class ElementTest extends TestCase
$this->assertSame(22, $element->getId()); $this->assertSame(22, $element->getId());
$this->assertSame('Genesis', $element->getName()); $this->assertSame('Genesis', $element->getName());
$this->assertSame('portion', $element->getKind()); $this->assertSame('portion', $element->getKind());
$this->assertSame($portionLevel, $element->getLevel());
$this->assertSame($set, $element->getSet()); $this->assertSame($set, $element->getSet());
$this->assertSame($parentElement, $element->getParentElement()); $this->assertSame($parentElement, $element->getParentElement());
$this->assertSame(2, $element->getPosition()); $this->assertSame(2, $element->getPosition());