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

331 lines
13 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Domain\Models\Entities;
use Carbon\CarbonImmutable;
use Domain\Enums\BarcodeFormat;
use Domain\Enums\Country;
use Domain\Models\Entities\Coupon;
use Domain\Models\ValueObjects\Actor\ActorId;
use Domain\Models\ValueObjects\Brand\BrandCode;
use Domain\Models\ValueObjects\Coupon\CouponAvailabilityCalendar;
use Domain\Models\ValueObjects\Coupon\CouponDiffusion;
use Domain\Models\ValueObjects\Coupon\CouponId;
use Domain\Models\ValueObjects\Coupon\CouponLegalInformation;
use Domain\Models\ValueObjects\Coupon\CouponProduct;
use Domain\Models\ValueObjects\Coupon\CouponValidity;
use Domain\Models\ValueObjects\CouponName;
use Domain\Models\ValueObjects\CouponPicture;
use Domain\Models\ValueObjects\CouponProductName;
use Domain\Models\ValueObjects\GS1;
use Domain\Models\ValueObjects\MoneyAmount;
use Domain\Models\ValueObjects\PicturePath;
use Domain\Models\ValueObjects\ProcessingCode;
use Ramsey\Uuid\Uuid;
use Shared\Enums\Currency;
use Shared\ValueObjects\DateTime;
use Shared\ValueObjects\Money;
covers(Coupon::class);
describe('coupon', function (): void {
afterEach(function (): void {
CarbonImmutable::setTestNow();
});
it('creates a coupon', function (): void {
// GIVEN
$id = CouponId::generate();
$name = new CouponName('Name');
$status = \boolval(0);
$productName = new CouponProductName('Lorem ipsum');
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
$picture = new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg'));
$product = new CouponProduct('Lorem ipsum', [], []);
$diffusion = new CouponDiffusion(['2026-08-25', '2026-10-31']);
$availability = new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']);
$validity = new CouponValidity(30, new DateTime('2026-11-30'));
$legal = [new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)];
$code = new ProcessingCode('5425003944130');
$brandCode = new BrandCode('AAA01');
$createdBy = ActorId::generate();
$gtin = new GS1('110101010', BarcodeFormat::EAN13);
// WHEN
$coupon = Coupon::hydrate(
$id,
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
$gtin,
);
// THEN
expect($coupon->id())->toBe($id)
->and($coupon->name)->toBe($name)
->and($coupon->status)->toBe($status)
->and($coupon->productName)->toBe($productName)
->and($coupon->amount)->toBe($amount)
->and($coupon->picture)->toBe($picture)
->and($coupon->product)->toBe($product)
->and($coupon->diffusion)->toBe($diffusion)
->and($coupon->availability)->toBe($availability)
->and($coupon->validity)->toBe($validity)
->and($coupon->legal)->toBe($legal)
->and($coupon->code)->toBe($code)
->and($coupon->brandCode)->toBe($brandCode)
->and($coupon->createdBy)->toBe($createdBy)
->and($coupon->gtin)->toBe($gtin)
->and($coupon->updatedAt)->toBeNull()
->and($coupon->updatedAt())->toBeNull();
});
it('creates a coupon without gs1', function (): void {
// GIVEN
$id = CouponId::generate();
$name = new CouponName('Name');
$status = \boolval(0);
$productName = new CouponProductName('Lorem ipsum');
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
$picture = new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg'));
$product = new CouponProduct('Lorem ipsum', [], []);
$diffusion = new CouponDiffusion(['2026-08-25', '2026-10-31']);
$availability = new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']);
$validity = new CouponValidity(30, new DateTime('2026-11-30'));
$legal = [new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)];
$code = new ProcessingCode('5425003944130');
$brandCode = new BrandCode('AAA01');
$createdBy = ActorId::generate();
// WHEN
$coupon = Coupon::hydrate(
$id,
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
);
// THEN
expect($coupon->id())->toBe($id)
->and($coupon->name)->toBe($name)
->and($coupon->status)->toBe($status)
->and($coupon->productName)->toBe($productName)
->and($coupon->amount)->toBe($amount)
->and($coupon->picture)->toBe($picture)
->and($coupon->product)->toBe($product)
->and($coupon->diffusion)->toBe($diffusion)
->and($coupon->availability)->toBe($availability)
->and($coupon->validity)->toBe($validity)
->and($coupon->legal)->toBe($legal)
->and($coupon->code)->toBe($code)
->and($coupon->brandCode)->toBe($brandCode)
->and($coupon->createdBy)->toBe($createdBy)
->and($coupon->updatedAt)->toBeNull()
->and($coupon->updatedAt())->toBeNull();
});
it('creates a coupon with an explicit updatedAt date', function (): void {
// GIVEN
$id = CouponId::generate();
$name = new CouponName('Name');
$status = \boolval(0);
$productName = new CouponProductName('Lorem ipsum');
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
$picture = new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg'));
$product = new CouponProduct('Lorem ipsum', [], []);
$diffusion = new CouponDiffusion(['2026-08-25', '2026-10-31']);
$availability = new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']);
$validity = new CouponValidity(30, new DateTime('2026-11-30'));
$legal = [new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)];
$code = new ProcessingCode('5425003944130');
$brandCode = new BrandCode('AAA01');
$gtin = new GS1('110101010', BarcodeFormat::EAN13);
$createdBy = ActorId::generate();
$updatedAt = new \DateTimeImmutable('2026-09-22 10:00:00', new \DateTimeZone('UTC'));
// WHEN
$coupon = Coupon::hydrate(
$id,
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
$gtin,
$updatedAt
);
// THEN
expect($coupon->updatedAt)->toBe($updatedAt)
->and($coupon->updatedAt())->toBe($updatedAt);
});
it('creates a new coupon with a freshly generated id', function (): void {
// GIVEN
$name = new CouponName('Name');
$status = \boolval(0);
$productName = new CouponProductName('Lorem ipsum');
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
$picture = new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg'));
$product = new CouponProduct('Lorem ipsum', [], []);
$diffusion = new CouponDiffusion(['2026-08-25', '2026-10-31']);
$availability = new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']);
$validity = new CouponValidity(30, new DateTime('2026-11-30'));
$legal = [new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)];
$code = new ProcessingCode('5425003944130');
$brandCode = new BrandCode('AAA01');
$createdBy = ActorId::generate();
$gtin = new GS1('110101010', BarcodeFormat::EAN13);
// WHEN
$coupon = Coupon::create(
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
$gtin,
);
// THEN
expect($coupon->id())->toBeInstanceOf(CouponId::class)
->and($coupon->name)->toBe($name)
->and($coupon->status)->toBe($status)
->and($coupon->productName)->toBe($productName)
->and($coupon->amount)->toBe($amount)
->and($coupon->picture)->toBe($picture)
->and($coupon->product)->toBe($product)
->and($coupon->diffusion)->toBe($diffusion)
->and($coupon->availability)->toBe($availability)
->and($coupon->validity)->toBe($validity)
->and($coupon->legal)->toBe($legal)
->and($coupon->code)->toBe($code)
->and($coupon->brandCode)->toBe($brandCode)
->and($coupon->createdBy)->toBe($createdBy)
->and($coupon->gtin)->toBe($gtin)
->and($coupon->updatedAt)->toBeNull()
->and($coupon->updatedAt())->toBeNull();
});
it('generates a different id for each created coupon', function (): void {
// GIVEN
$name = new CouponName('Name');
$status = \boolval(0);
$productName = new CouponProductName('Lorem ipsum');
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
$picture = new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg'));
$product = new CouponProduct('Lorem ipsum', [], []);
$diffusion = new CouponDiffusion(['2026-08-25', '2026-10-31']);
$availability = new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']);
$validity = new CouponValidity(30, new DateTime('2026-11-30'));
$legal = [new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)];
$code = new ProcessingCode('5425003944130');
$brandCode = new BrandCode('AAA01');
$createdBy = ActorId::generate();
$gtin = new GS1('110101010', BarcodeFormat::EAN13);
// WHEN
$firstCoupon = Coupon::create(
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
$gtin
);
$secondCoupon = Coupon::create(
$name,
$status,
$productName,
$amount,
$picture,
$product,
$diffusion,
$availability,
$validity,
$legal,
$code,
$brandCode,
$createdBy,
$gtin
);
// THEN
expect($firstCoupon->id()->equals($secondCoupon->id()))->toBeFalse();
});
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 CouponId(Uuid::uuid7($expected));
$coupon = Coupon::hydrate(
$id,
new CouponName('Name'),
\boolval(0),
new CouponProductName('Lorem ipsum'),
new MoneyAmount(new Money(Currency::EUR, 1)),
new CouponPicture(new PicturePath('files/product.jpg'), new PicturePath('files/thumbnail.jpg')),
new CouponProduct('Lorem ipsum', [], []),
new CouponDiffusion(['2026-08-25', '2026-10-31']),
new CouponAvailabilityCalendar(['2026-08-25', '2026-10-31']),
new CouponValidity(30, new DateTime('2026-11-30')),
[new CouponLegalInformation('Lorem ipsum dolor sit amet consectetur adipiscing elit.', Country::FR)],
new ProcessingCode('5425003944130'),
new BrandCode('AAA01'),
ActorId::generate(),
new GS1('110101010', BarcodeFormat::EAN13),
);
// WHEN
$result = $coupon->createdAt();
// THEN
expect($result->format('Y-m-d H:i:s.v'))->toBe($expected->format('Y-m-d H:i:s.v'));
});
});