Rich-Model Mahlzeit (MahlzeitStatus, Wochentag) mit Invarianten und Zustandsübergängen; DTOs + MahlzeitFactory (reine Mapping-Funktionen); Manager (create hängt an Ende an: maxSortOrder+1, find → 404) und Create/Update/Delete-UseCases mit Transaktion + Events nach Commit. Data-Layer: MahlzeitEntity (Tabelle essens_mahlzeiten, wochentage als CSV), Mapper (CSV/Enum/null), Provider (find/list/maxSortOrder), Processor (create/save/delete). DI-Bindings in services.yaml. ClockInterface (Logic) + SystemClock (Data). Tests: Model/Factory/UseCase-Unit + Provider/Processor/Mapper-Integration (In-Mem-SQLite). composer test grün (53 Tests, 161 Assertions).
112 lines
3.8 KiB
PHP
112 lines
3.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Tests\Unit\Logic\Essen\Mapping;
|
|
|
|
use App\Logic\Common\Exception\BusinessRuleViolationException;
|
|
use App\Logic\Essen\Dto\MahlzeitCreateRequest;
|
|
use App\Logic\Essen\Dto\MahlzeitUpdateRequest;
|
|
use App\Logic\Essen\Mapping\MahlzeitFactory;
|
|
use App\Logic\Essen\Model\Mahlzeit;
|
|
use App\Logic\Essen\Model\MahlzeitStatus;
|
|
use App\Logic\Essen\Model\Wochentag;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class MahlzeitFactoryTest extends TestCase
|
|
{
|
|
private function factory(): MahlzeitFactory
|
|
{
|
|
return new MahlzeitFactory();
|
|
}
|
|
|
|
private function jetzt(): \DateTimeImmutable
|
|
{
|
|
return new \DateTimeImmutable('2026-09-18 12:00:00');
|
|
}
|
|
|
|
public function testCreateFromCreateRequest(): void
|
|
{
|
|
$jetzt = $this->jetzt();
|
|
$req = new MahlzeitCreateRequest(
|
|
name: 'Pasta',
|
|
notiz: 'vegan',
|
|
wochentage: [Wochentag::Fr, Wochentag::Sa],
|
|
);
|
|
|
|
$m = $this->factory()->createFromCreateRequest($req, $jetzt);
|
|
|
|
self::assertSame(0, $m->id);
|
|
self::assertSame('Pasta', $m->name);
|
|
self::assertSame('vegan', $m->notiz);
|
|
self::assertSame([Wochentag::Fr, Wochentag::Sa], $m->wochentage());
|
|
self::assertSame(0, $m->sortOrder);
|
|
self::assertSame(MahlzeitStatus::Geplant, $m->status);
|
|
self::assertSame($jetzt, $m->erstelltAm);
|
|
self::assertSame($jetzt, $m->aktualisiertAm);
|
|
}
|
|
|
|
public function testCreateWithLeerenNameWirft(): void
|
|
{
|
|
$req = new MahlzeitCreateRequest(name: ' ');
|
|
|
|
$this->expectException(BusinessRuleViolationException::class);
|
|
|
|
$this->factory()->createFromCreateRequest($req, $this->jetzt());
|
|
}
|
|
|
|
public function testUpdateÄndertNurGelieferteFelder(): void
|
|
{
|
|
$vorher = new Mahlzeit(
|
|
id: 7,
|
|
name: 'Altes',
|
|
notiz: 'alte Notiz',
|
|
wochentage: [Wochentag::Mo],
|
|
sortOrder: 3,
|
|
status: MahlzeitStatus::Geplant,
|
|
erstelltAm: $this->jetzt(),
|
|
aktualisiertAm: $this->jetzt(),
|
|
gegessenAm: null,
|
|
);
|
|
|
|
$req = new MahlzeitUpdateRequest(name: 'Neues', wochentage: [Wochentag::Do]);
|
|
|
|
$nachher = $this->factory()->updateFromUpdateRequest($vorher, $req, $this->jetzt());
|
|
|
|
self::assertSame('Neues', $nachher->name);
|
|
self::assertSame([Wochentag::Do], $nachher->wochentage());
|
|
self::assertSame('alte Notiz', $nachher->notiz, 'nicht geliefertes Feld bleibt unverändert');
|
|
self::assertSame(3, $nachher->sortOrder);
|
|
self::assertSame(7, $nachher->id);
|
|
}
|
|
|
|
public function testUpdateMitNullFeldBelässtBestandwert(): void
|
|
{
|
|
$vorher = new Mahlzeit(7, 'Altes', 'Notiz', [Wochentag::Mo], 3, MahlzeitStatus::Geplant, $this->jetzt(), $this->jetzt(), null);
|
|
|
|
$nachher = $this->factory()->updateFromUpdateRequest($vorher, new MahlzeitUpdateRequest(), $this->jetzt());
|
|
|
|
self::assertSame('Altes', $nachher->name);
|
|
self::assertSame('Notiz', $nachher->notiz);
|
|
self::assertSame([Wochentag::Mo], $nachher->wochentage());
|
|
}
|
|
|
|
public function testUpdateMitLeerenNameWirft(): void
|
|
{
|
|
$vorher = new Mahlzeit(7, 'Altes', '', [], 0, MahlzeitStatus::Geplant, $this->jetzt(), $this->jetzt(), null);
|
|
|
|
$this->expectException(BusinessRuleViolationException::class);
|
|
|
|
$this->factory()->updateFromUpdateRequest($vorher, new MahlzeitUpdateRequest(name: ' '), $this->jetzt());
|
|
}
|
|
|
|
public function testUpdateLeereWochentageListeSetztKeineTage(): void
|
|
{
|
|
$vorher = new Mahlzeit(7, 'Altes', '', [Wochentag::Mo], 0, MahlzeitStatus::Geplant, $this->jetzt(), $this->jetzt(), null);
|
|
|
|
$nachher = $this->factory()->updateFromUpdateRequest($vorher, new MahlzeitUpdateRequest(wochentage: []), $this->jetzt());
|
|
|
|
self::assertSame([], $nachher->wochentage());
|
|
}
|
|
}
|