ldc-mesbr-app/tests/Unit/Domain/Models/Entities/StockTest.php
2026-10-02 12:47:27 +02:00

145 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Domain\Models\Entities;
use Domain\Models\Entities\Stock;
use Domain\Models\ValueObjects\Actor\ActorId;
use Domain\Models\ValueObjects\Campaign\CampaignCode;
use Domain\Models\ValueObjects\ProcessingCode;
use Domain\Models\ValueObjects\Stock\StockAdjustment;
use Domain\Models\ValueObjects\Stock\StockAmount;
use Domain\Models\ValueObjects\Stock\StockId;
use Ramsey\Uuid\Uuid;
covers(Stock::class);
describe('stock', function (): void {
it('hydrates a stock', function (): void {
// GIVEN
$id = StockId::generate();
$stockAmount = new StockAmount(10);
$campaignCode = new CampaignCode('AAA01');
$processingCode = new ProcessingCode('PC1');
$stockAdjustment = [new StockAdjustment(5, 'Inventory correction', ActorId::generate())];
// WHEN
$stock = Stock::hydrate($id, $stockAmount, $campaignCode, $processingCode, $stockAdjustment);
// THEN
expect($stock->id())->toBe($id)
->and($stock->stockAmount)->toBe($stockAmount)
->and($stock->campaignCode)->toBe($campaignCode)
->and($stock->processingCode)->toBe($processingCode)
->and($stock->stockAdjustment)->toBe($stockAdjustment)
->and($stock->updatedAt)->toBeNull()
->and($stock->updatedAt())->toBeNull();
});
it('hydrates a stock with several stock adjustments', function (): void {
// GIVEN
$id = StockId::generate();
$stockAmount = new StockAmount(10);
$campaignCode = new CampaignCode('AAA01');
$processingCode = new ProcessingCode('PC1');
$stockAdjustment = [
new StockAdjustment(5, 'Inventory correction', ActorId::generate()),
new StockAdjustment(10, 'Inventory correction', ActorId::generate()),
];
// WHEN
$stock = Stock::hydrate(
$id,
$stockAmount,
$campaignCode,
$processingCode,
$stockAdjustment,
);
// THEN
expect($stock->id())->toBe($id)
->and($stock->stockAmount)->toBe($stockAmount)
->and($stock->campaignCode)->toBe($campaignCode)
->and($stock->processingCode)->toBe($processingCode)
->and($stock->stockAdjustment)->toBe($stockAdjustment)
->and($stock->updatedAt)->toBeNull()
->and($stock->updatedAt())->toBeNull();
});
it('hydrates a stock without stock adjustement', function (): void {
// GIVEN
$id = StockId::generate();
$stockAmount = new StockAmount(10);
$campaignCode = new CampaignCode('AAA01');
$processingCode = new ProcessingCode('PC1');
// WHEN
$stock = Stock::hydrate($id, $stockAmount, $campaignCode, $processingCode);
// THEN
expect($stock->id())->toBe($id)
->and($stock->stockAmount)->toBe($stockAmount)
->and($stock->campaignCode)->toBe($campaignCode)
->and($stock->processingCode)->toBe($processingCode)
->and($stock->stockAdjustment)->toBe([])
->and($stock->updatedAt)->toBeNull()
->and($stock->updatedAt())->toBeNull();
});
it('rejects a stock with a non-stock-adjustment element', function (): void {
// GIVEN
$id = StockId::generate();
$stockAmount = new StockAmount(10);
$campaignCode = new CampaignCode('AAA01');
$processingCode = new ProcessingCode('PC1');
$stockAdjustment = [new StockAmount(5)];
// WHEN / THEN
expect(fn (): Stock => Stock::hydrate(
$id,
$stockAmount,
$campaignCode,
$processingCode,
$stockAdjustment,
))->toThrow(\DomainException::class, 'Stock adjustment must be StockAdjustment instances.');
});
it('hydrates a stock with an explicit updatedAt date', function (): void {
// GIVEN
$updatedAt = new \DateTimeImmutable('2026-06-15 12:00:00', new \DateTimeZone('UTC'));
// WHEN
$stock = Stock::hydrate(
StockId::generate(),
new StockAmount(10),
new CampaignCode('AAA01'),
new ProcessingCode('PC1'),
[new StockAdjustment(5, 'Inventory correction', ActorId::generate())],
$updatedAt,
);
// THEN
expect($stock->updatedAt)->toBe($updatedAt)
->and($stock->updatedAt())->toBe($updatedAt);
});
it('returns the creation date extracted from the id', function (): void {
// GIVEN
$expected = new \DateTimeImmutable('2024-06-15 12:34:56.789000', new \DateTimeZone('UTC'));
$id = new StockId(Uuid::uuid7($expected));
$stock = Stock::hydrate(
$id,
new StockAmount(10),
new CampaignCode('AAA01'),
new ProcessingCode('PC1'),
[new StockAdjustment(5, 'Inventory correction', ActorId::generate())],
);
// WHEN
$result = $stock->createdAt();
// THEN
expect($result->format('Y-m-d H:i:s.v'))->toBe($expected->format('Y-m-d H:i:s.v'));
});
});