Multiple implementations of the same back-end application. The aim is to provide quick, side-by-side comparisons of different technologies (languages, frameworks, libraries) while preserving consistent business logic across all implementations.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

155 lines
4.5 KiB

<?php
declare(strict_types=1);
namespace AutoStore\Tests\Unit\Domain\Policies;
use AutoStore\Domain\Entities\Item;
use AutoStore\Domain\Specifications\ItemExpirationSpec;
use AutoStore\Domain\Specifications\Specification;
use AutoStore\Infrastructure\Mappers\ItemMapper;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
class ItemExpirationSpecTest extends TestCase
{
private const ITEM_ID = 'test-id';
private const ITEM_ID_2 = 'test-id-2';
private const ITEM_NAME = 'Test Item';
private const ITEM_NAME_2 = 'Test Item 2';
private const ORDER_URL = 'http://example.com/order';
private const ORDER_URL_2 = 'http://example.com/order2';
private const USER_ID = 'user-id';
private const USER_ID_2 = 'user-id-2';
private const CURRENT_TIME = '2023-01-01 12:00:00';
private const EXPIRED_TIME = '2023-01-01 11:00:00';
private const VALID_TIME = '2023-01-01 13:00:00';
private ItemExpirationSpec $spec;
protected function setUp(): void
{
$this->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));
}
}