getId()); self::assertSame('Chatellerault', $site->getName()); self::assertSame("1 avenue de l'Europe", $site->getStreet()); self::assertNull($site->getComplement()); self::assertSame('86100', $site->getPostalCode()); self::assertSame('Chatellerault', $site->getCity()); self::assertSame('#056CF2', $site->getColor()); self::assertInstanceOf(DateTimeImmutable::class, $site->getCreatedAt()); self::assertInstanceOf(DateTimeImmutable::class, $site->getUpdatedAt()); } public function testCreatedAtAndUpdatedAtAreInitiallyEqual(): void { $site = new Site('A', 'Rue X', null, '12345', 'B', '#000000'); // A la creation, les deux timestamps sont seedes avec la meme valeur // pour garantir updated_at >= created_at au niveau base. self::assertEquals($site->getCreatedAt(), $site->getUpdatedAt()); } public function testOnPreUpdateAdvancesUpdatedAtOnly(): void { $site = new Site('A', 'Rue X', null, '12345', 'B', '#000000'); $originalCreatedAt = $site->getCreatedAt(); // On force updatedAt a une valeur strictement anterieure via reflection // pour ne pas dependre d'un `sleep()` (flaky en CI, lent) : l'entite // n'expose volontairement pas de setter sur updatedAt, c'est le // callback Doctrine PreUpdate qui s'en charge. $pastUpdatedAt = new DateTimeImmutable('-1 hour'); $reflection = new ReflectionClass(Site::class); $updatedAtProperty = $reflection->getProperty('updatedAt'); $updatedAtProperty->setValue($site, $pastUpdatedAt); $site->onPreUpdate(); self::assertSame($originalCreatedAt, $site->getCreatedAt(), 'created_at doit rester immuable apres un update.'); self::assertGreaterThan($pastUpdatedAt, $site->getUpdatedAt(), 'updated_at doit avancer apres onPreUpdate().'); } public function testSettersMutateFields(): void { $site = new Site('Old', 'Old Street', null, '12345', 'OldCity', '#000000'); $site->setName('New'); $site->setStreet('New Street'); $site->setComplement('Bat A'); $site->setPostalCode('67890'); $site->setCity('NewCity'); $site->setColor('#ABCDEF'); self::assertSame('New', $site->getName()); self::assertSame('New Street', $site->getStreet()); self::assertSame('Bat A', $site->getComplement()); self::assertSame('67890', $site->getPostalCode()); self::assertSame('NewCity', $site->getCity()); self::assertSame('#ABCDEF', $site->getColor()); } public function testFullAddressGetterWithoutComplement(): void { $site = new Site( name: 'Site1', street: '1 avenue de l\'Europe', complement: null, postalCode: '86100', city: 'Chatellerault', color: '#000000', ); self::assertSame( "1 avenue de l'Europe\n86100 Chatellerault", $site->getFullAddress(), ); } public function testFullAddressGetterWithComplement(): void { $site = new Site( name: 'Site2', street: '12 route de Poitiers', complement: 'Batiment B', postalCode: '86330', city: 'Saint-Jean-de-Sauves', color: '#000000', ); self::assertSame( "12 route de Poitiers\nBatiment B\n86330 Saint-Jean-de-Sauves", $site->getFullAddress(), ); } public function testFullAddressGetterIgnoresEmptyComplement(): void { // Garde defensive : un complement vide ou whitespace-only ne doit // pas creer une ligne vide visuellement disgracieuse. $site = new Site('S', 'Rue', ' ', '12345', 'Ville', '#000000'); self::assertSame("Rue\n12345 Ville", $site->getFullAddress()); } }