spec = new ItemExpirationSpec(); } private function createExpiredItem(): Item { return new Item( self::ITEM_ID, self::ITEM_NAME, new DateTimeImmutable('-1 day'), self::ORDER_URL, self::USER_ID ); } private function createValidItem(): Item { return new Item( self::ITEM_ID, self::ITEM_NAME, new DateTimeImmutable('+1 day'), self::ORDER_URL, self::USER_ID ); } private function createItemWithExpiration(string $expirationDate): Item { return new Item( self::ITEM_ID, self::ITEM_NAME, new DateTimeImmutable($expirationDate), self::ORDER_URL, self::USER_ID ); } private function createSecondItemWithExpiration(string $expirationDate): Item { return new Item( self::ITEM_ID_2, self::ITEM_NAME_2, new DateTimeImmutable($expirationDate), self::ORDER_URL_2, self::USER_ID_2 ); } public function testWhenItemIsExpiredThenIsExpiredReturnsTrue(): void { // Given $item = $this->createExpiredItem(); $currentTime = new DateTimeImmutable(); // When $result = $this->spec->isExpired($item, $currentTime); // Then $this->assertTrue($result); } public function testWhenItemIsNotExpiredThenIsExpiredReturnsFalse(): void { // Given $item = $this->createValidItem(); $currentTime = new DateTimeImmutable(); // When $result = $this->spec->isExpired($item, $currentTime); // Then $this->assertFalse($result); } public function testGetExpirationSpecShouldReturnMatchingSpecification(): void { // Given $currentTime = new DateTimeImmutable(self::CURRENT_TIME); // When $specification = $this->spec->getSpec($currentTime); // Then $this->assertInstanceOf(Specification::class, $specification); $expiredData = [ 'id' => self::ITEM_ID, 'name' => self::ITEM_NAME, 'expirationDate' => self::EXPIRED_TIME, 'orderUrl' => self::ORDER_URL, 'userId' => self::USER_ID ]; $validData = [ 'id' => self::ITEM_ID_2, 'name' => self::ITEM_NAME_2, 'expirationDate' => self::VALID_TIME, 'orderUrl' => self::ORDER_URL_2, 'userId' => self::USER_ID_2 ]; $this->assertTrue($specification->match((object)$expiredData)); $this->assertFalse($specification->match((object)$validData)); } public function testGetExpirationSpecShouldWorkWithItemObjects(): void { // Given $currentTime = new DateTimeImmutable(self::CURRENT_TIME); $expiredItem = $this->createItemWithExpiration(self::EXPIRED_TIME); $validItem = $this->createSecondItemWithExpiration(self::VALID_TIME); // When $specification = $this->spec->getSpec($currentTime); // Then // Test with array representation using the mapper $expiredArray = ItemMapper::toArray($expiredItem); $validArray = ItemMapper::toArray($validItem); // Check that the specification matches the array representation $this->assertTrue($specification->match((object)$expiredArray)); $this->assertFalse($specification->match((object)$validArray)); } }