diff --git a/migrations/Version20260618213556.php b/migrations/Version20260618213556.php new file mode 100644 index 0000000..d0b3d86 --- /dev/null +++ b/migrations/Version20260618213556.php @@ -0,0 +1,29 @@ +addSql('CREATE TABLE scenario (id UUID NOT NULL, distribution_mode VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, description TEXT DEFAULT NULL, PRIMARY KEY (id))'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('DROP TABLE scenario'); + } +} diff --git a/src/Entity/Scenario.php b/src/Entity/Scenario.php new file mode 100644 index 0000000..e02ef52 --- /dev/null +++ b/src/Entity/Scenario.php @@ -0,0 +1,72 @@ +id = new UuidV7(); + } + + public function getId(): UuidV7 + { + return $this->id; + } + + public function getDistributionMode(): DistributionMode + { + return $this->distributionMode; + } + + public function getName(): string + { + return $this->name; + } + + public function getDescription(): ?string + { + return $this->description; + } + + public function setDistributionMode(DistributionMode $distributionMode): static + { + $this->distributionMode = $distributionMode; + + return $this; + } + + public function setName(string $name): static + { + $this->name = $name; + + return $this; + } + + public function setDescription(?string $description): static + { + $this->description = $description; + + return $this; + } +} diff --git a/src/Repository/ScenarioRepository.php b/src/Repository/ScenarioRepository.php new file mode 100644 index 0000000..0ec938e --- /dev/null +++ b/src/Repository/ScenarioRepository.php @@ -0,0 +1,18 @@ + + */ +class ScenarioRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, Scenario::class); + } +} diff --git a/tests/Entity/ScenarioPersistenceTest.php b/tests/Entity/ScenarioPersistenceTest.php new file mode 100644 index 0000000..3e56db4 --- /dev/null +++ b/tests/Entity/ScenarioPersistenceTest.php @@ -0,0 +1,127 @@ +em = self::getContainer()->get(EntityManagerInterface::class); + } + + public function testItPersistsAScenarioWithAUuidId(): void + { + $scenario = new Scenario(); + $scenario->setName('Household Budget'); + + $this->em->persist($scenario); + $this->em->flush(); + + $id = $scenario->getId(); + self::assertInstanceOf(UuidV7::class, $id); + + $this->em->clear(); + + $reloaded = $this->em->find(Scenario::class, $id); + + self::assertNotNull($reloaded, 'Scenario must be retrievable from the database after an identity-map clear.'); + self::assertInstanceOf(UuidV7::class, $reloaded->getId()); + self::assertSame('Household Budget', $reloaded->getName()); + } + + public function testDistributionModeDefaultsToEvenWhenNotExplicitlySet(): void + { + $scenario = new Scenario(); + $scenario->setName('Default Mode Scenario'); + + $this->em->persist($scenario); + $this->em->flush(); + + $id = $scenario->getId(); + + $this->em->clear(); + + $reloaded = $this->em->find(Scenario::class, $id); + + self::assertNotNull($reloaded); + self::assertSame( + DistributionMode::EVEN, + $reloaded->getDistributionMode(), + 'distribution_mode must default to EVEN when not explicitly set.', + ); + } + + public function testItRoundTripsAnExplicitlySetPriorityDistributionMode(): void + { + $scenario = new Scenario(); + $scenario->setName('Priority Mode Scenario'); + $scenario->setDistributionMode(DistributionMode::PRIORITY); + + $this->em->persist($scenario); + $this->em->flush(); + + $id = $scenario->getId(); + + $this->em->clear(); + + $reloaded = $this->em->find(Scenario::class, $id); + + self::assertNotNull($reloaded); + self::assertInstanceOf( + DistributionMode::class, + $reloaded->getDistributionMode(), + 'distribution_mode must hydrate as a DistributionMode enum instance, not a raw string.', + ); + self::assertSame( + DistributionMode::PRIORITY, + $reloaded->getDistributionMode(), + 'An explicitly set PRIORITY distribution_mode must survive a flush + clear + reload round-trip.', + ); + } + + public function testDescriptionRoundTripsWhenSet(): void + { + $scenario = new Scenario(); + $scenario->setName('Described Scenario'); + $scenario->setDescription('Covers rent, groceries, and the emergency buffer.'); + + $this->em->persist($scenario); + $this->em->flush(); + + $id = $scenario->getId(); + + $this->em->clear(); + + $reloaded = $this->em->find(Scenario::class, $id); + + self::assertNotNull($reloaded); + self::assertSame('Covers rent, groceries, and the emergency buffer.', $reloaded->getDescription()); + } + + public function testDescriptionIsNullableAndRemainsNullWhenNotSet(): void + { + $scenario = new Scenario(); + $scenario->setName('Undescribed Scenario'); + + $this->em->persist($scenario); + $this->em->flush(); + + $id = $scenario->getId(); + + $this->em->clear(); + + $reloaded = $this->em->find(Scenario::class, $id); + + self::assertNotNull($reloaded); + self::assertNull($reloaded->getDescription()); + } +}