getId()); self::assertNull($category->getName()); self::assertNull($category->getEvent()); self::assertSame(0, $category->getPosition()); self::assertFalse($category->isHidden()); self::assertInstanceOf(\DateTimeImmutable::class, $category->getCreatedAt()); self::assertInstanceOf(\DateTimeImmutable::class, $category->getStartAt()); self::assertInstanceOf(\DateTimeImmutable::class, $category->getEndAt()); } public function testSetAndGetName(): void { $category = new Category(); $result = $category->setName('VIP'); self::assertSame('VIP', $category->getName()); self::assertSame($category, $result); } public function testSetAndGetPosition(): void { $category = new Category(); $result = $category->setPosition(3); self::assertSame(3, $category->getPosition()); self::assertSame($category, $result); } public function testSetAndGetStartAt(): void { $category = new Category(); $date = new \DateTimeImmutable('2026-06-01 10:00:00'); $result = $category->setStartAt($date); self::assertSame($date, $category->getStartAt()); self::assertSame($category, $result); } public function testSetAndGetEndAt(): void { $category = new Category(); $date = new \DateTimeImmutable('2026-06-15 18:00:00'); $result = $category->setEndAt($date); self::assertSame($date, $category->getEndAt()); self::assertSame($category, $result); } public function testSetAndGetIsHidden(): void { $category = new Category(); $result = $category->setIsHidden(true); self::assertTrue($category->isHidden()); self::assertSame($category, $result); $category->setIsHidden(false); self::assertFalse($category->isHidden()); } public function testSetEventSetsEndAtToOneDayBeforeEventStart(): void { $event = new Event(); $event->setStartAt(new \DateTimeImmutable('+60 days')); $category = new Category(); $result = $category->setEvent($event); self::assertSame($event, $category->getEvent()); self::assertSame($category, $result); $expectedEnd = $event->getStartAt()->modify('-1 day'); self::assertSame( $expectedEnd->format('Y-m-d H:i:s'), $category->getEndAt()->format('Y-m-d H:i:s') ); } public function testSetEventWithPastStartAtUsesEventStartAt(): void { $event = new Event(); $event->setStartAt(new \DateTimeImmutable('-1 day')); $category = new Category(); $category->setEvent($event); // endCandidate (-2 days) < startAt (now), so endAt = event.startAt self::assertSame( $event->getStartAt()->format('Y-m-d H:i:s'), $category->getEndAt()->format('Y-m-d H:i:s') ); } public function testSetEventNull(): void { $category = new Category(); $originalEnd = $category->getEndAt(); $category->setEvent(null); self::assertNull($category->getEvent()); self::assertSame($originalEnd, $category->getEndAt()); } public function testIsActiveWhenNowIsBetweenStartAndEnd(): void { $category = new Category(); $category->setStartAt(new \DateTimeImmutable('-1 hour')); $category->setEndAt(new \DateTimeImmutable('+1 hour')); self::assertTrue($category->isActive()); } public function testIsActiveWhenNowIsBeforeStart(): void { $category = new Category(); $category->setStartAt(new \DateTimeImmutable('+1 hour')); $category->setEndAt(new \DateTimeImmutable('+2 hours')); self::assertFalse($category->isActive()); } public function testIsActiveWhenNowIsAfterEnd(): void { $category = new Category(); $category->setStartAt(new \DateTimeImmutable('-2 hours')); $category->setEndAt(new \DateTimeImmutable('-1 hour')); self::assertFalse($category->isActive()); } public function testGetCreatedAt(): void { $before = new \DateTimeImmutable(); $category = new Category(); $after = new \DateTimeImmutable(); self::assertGreaterThanOrEqual($before, $category->getCreatedAt()); self::assertLessThanOrEqual($after, $category->getCreatedAt()); } public function testSetEventWithNullStartAt(): void { $event = new Event(); $category = new Category(); $originalEnd = $category->getEndAt(); $category->setEvent($event); // Event has no startAt set, so endAt should not change self::assertNull($event->getStartAt()); self::assertSame($originalEnd, $category->getEndAt()); } }