feat: Gestion des matières scolaires
Les établissements ont besoin de définir leur référentiel de matières pour pouvoir ensuite les associer aux enseignants et aux classes. Cette fonctionnalité permet aux administrateurs de créer, modifier et archiver les matières avec leurs propriétés (nom, code court, couleur). L'architecture suit le pattern DDD avec des Value Objects utilisant les property hooks PHP 8.5 pour garantir l'immutabilité et la validation. L'isolation multi-tenant est assurée par vérification dans les handlers.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Unit\Administration\Domain\Model\Subject;
|
||||
|
||||
use App\Administration\Domain\Exception\SubjectCodeInvalideException;
|
||||
use App\Administration\Domain\Model\Subject\SubjectCode;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class SubjectCodeTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function constructWithValidCode(): void
|
||||
{
|
||||
$code = new SubjectCode('MATH');
|
||||
|
||||
self::assertSame('MATH', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function constructNormalizesToUppercase(): void
|
||||
{
|
||||
$code = new SubjectCode('math');
|
||||
|
||||
self::assertSame('MATH', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function constructTrimsWhitespace(): void
|
||||
{
|
||||
$code = new SubjectCode(' MATH ');
|
||||
|
||||
self::assertSame('MATH', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function constructWithMinimumLength(): void
|
||||
{
|
||||
$code = new SubjectCode('FR');
|
||||
|
||||
self::assertSame('FR', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function constructWithMaximumLength(): void
|
||||
{
|
||||
$code = new SubjectCode('HISTGEO123');
|
||||
|
||||
self::assertSame('HISTGEO123', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function constructWithDigits(): void
|
||||
{
|
||||
$code = new SubjectCode('EPS1');
|
||||
|
||||
self::assertSame('EPS1', $code->value);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('invalidCodesProvider')]
|
||||
public function constructThrowsExceptionForInvalidCode(string $invalidCode): void
|
||||
{
|
||||
$this->expectException(SubjectCodeInvalideException::class);
|
||||
|
||||
new SubjectCode($invalidCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return iterable<string, array{string}>
|
||||
*/
|
||||
public static function invalidCodesProvider(): iterable
|
||||
{
|
||||
yield 'empty string' => [''];
|
||||
yield 'single character' => ['M'];
|
||||
yield 'whitespace only' => [' '];
|
||||
yield 'too long' => ['MATHEMATICS']; // 11 chars
|
||||
yield 'with special characters' => ['MATH-1'];
|
||||
yield 'with spaces' => ['MA TH'];
|
||||
yield 'lowercase with special' => ['math!'];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function equalsReturnsTrueForSameValue(): void
|
||||
{
|
||||
$code1 = new SubjectCode('MATH');
|
||||
$code2 = new SubjectCode('MATH');
|
||||
|
||||
self::assertTrue($code1->equals($code2));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function equalsReturnsTrueForDifferentCase(): void
|
||||
{
|
||||
$code1 = new SubjectCode('MATH');
|
||||
$code2 = new SubjectCode('math');
|
||||
|
||||
self::assertTrue($code1->equals($code2));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function equalsReturnsFalseForDifferentValue(): void
|
||||
{
|
||||
$code1 = new SubjectCode('MATH');
|
||||
$code2 = new SubjectCode('FR');
|
||||
|
||||
self::assertFalse($code1->equals($code2));
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toStringReturnsValue(): void
|
||||
{
|
||||
$code = new SubjectCode('MATH');
|
||||
|
||||
self::assertSame('MATH', (string) $code);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user