491 lines
16 KiB
PHP
491 lines
16 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Domain\Models\Entities;
|
|
|
|
use Carbon\CarbonImmutable;
|
|
use DateTime;
|
|
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\CouponCode;
|
|
use Domain\Models\ValueObjects\Coupon\CouponDiffusion;
|
|
use Domain\Models\ValueObjects\Coupon\CouponId;
|
|
use Domain\Models\ValueObjects\Coupon\CouponLegalInformation;
|
|
use Domain\Models\ValueObjects\Coupon\CouponLegalInformationArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponMovement;
|
|
use Domain\Models\ValueObjects\Coupon\CouponMovementArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponName;
|
|
use Domain\Models\ValueObjects\Coupon\CouponPicture;
|
|
use Domain\Models\ValueObjects\Coupon\CouponProductArray;
|
|
use Domain\Models\ValueObjects\Coupon\CouponQuantity;
|
|
use Domain\Models\ValueObjects\Coupon\CouponValidityInformation;
|
|
use Domain\Models\ValueObjects\Coupon\CouponValidityInformationArray;
|
|
use Domain\Models\ValueObjects\IncoCode;
|
|
use Domain\Models\ValueObjects\MoneyAmount;
|
|
use Domain\Models\ValueObjects\Period;
|
|
use Domain\Models\ValueObjects\PicturePath;
|
|
use Domain\Models\ValueObjects\ProcessingCode;
|
|
use Domain\Models\ValueObjects\ProcessingCodeArray;
|
|
use Ramsey\Uuid\Uuid;
|
|
use Shared\Enums\Country;
|
|
use Shared\Enums\Currency;
|
|
use Shared\ValueObjects\Money;
|
|
|
|
covers(Coupon::class);
|
|
|
|
describe('coupon', function (): void {
|
|
$code = new CouponCode('AAA01');
|
|
$name = new CouponName('Name');
|
|
$amount = new MoneyAmount(new Money(Currency::EUR, 1));
|
|
$picture = new CouponPicture(
|
|
new PicturePath('files/product.jpg'),
|
|
new PicturePath('files/thumbnail.jpg'),
|
|
new PicturePath('files/mobileThumbnail.jpg'),
|
|
);
|
|
$diffusion = new CouponDiffusion(new Period(new DateTime('2026-01-01'), new DateTime('2026-02-01')));
|
|
$validityInformations = new CouponValidityInformationArray([
|
|
new CouponValidityInformation(
|
|
'Lorem ipsum dolor sit amet consectetur adipiscing elit.',
|
|
Country::FRANCE,
|
|
)
|
|
]);
|
|
$legalInformations = new CouponLegalInformationArray([
|
|
new CouponLegalInformation(
|
|
'Lorem ipsum dolor sit amet consectetur adipiscing elit.',
|
|
Country::FRANCE,
|
|
)
|
|
]);
|
|
$processingCode = new ProcessingCodeArray([
|
|
new ProcessingCode('5425003944130', Country::FRANCE),
|
|
]);
|
|
$brandCode = new BrandCode('AAA01');
|
|
$createdBy = ActorId::generate();
|
|
$products = new CouponProductArray([new IncoCode(35784), new IncoCode(15522)]);
|
|
$movements = new CouponMovementArray([new CouponMovement(100)]);
|
|
$quantity = new CouponQuantity(100);
|
|
$availabilityCalendar = new CouponAvailabilityCalendar([
|
|
new Period(
|
|
new DateTime('2026-08-25'),
|
|
new DateTime('2026-10-31'),
|
|
)]);
|
|
|
|
afterEach(function (): void {
|
|
CarbonImmutable::setTestNow();
|
|
});
|
|
|
|
it('creates a coupon', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
|
|
// WHEN
|
|
$coupon = Coupon::hydrate(
|
|
id: $id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
|
|
// THEN
|
|
expect($coupon->id())->toBe($id)
|
|
->and($coupon->code)->toBe($code)
|
|
->and($coupon->name)->toBe($name)
|
|
->and($coupon->amount)->toBe($amount)
|
|
->and($coupon->picture)->toBe($picture)
|
|
->and($coupon->diffusion)->toBe($diffusion)
|
|
->and($coupon->validityInformations)->toBe($validityInformations)
|
|
->and($coupon->legalInformations)->toBe($legalInformations)
|
|
->and($coupon->processingCode)->toBe($processingCode)
|
|
->and($coupon->brandCode)->toBe($brandCode)
|
|
->and($coupon->createdBy)->toBe($createdBy)
|
|
->and($coupon->products)->toBe($products)
|
|
->and($coupon->availabilityCalendar)->toBe($availabilityCalendar)
|
|
->and($coupon->movements)->toBe($movements)
|
|
->and($coupon->updatedAt)->toBeNull()
|
|
->and($coupon->updatedAt())->toBeNull();
|
|
});
|
|
|
|
it('hydrates a coupon without availability calendar', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
|
|
// WHEN
|
|
$coupon = Coupon::hydrate(
|
|
id: $id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
);
|
|
|
|
// THEN
|
|
expect($coupon->availabilityCalendar)->toBeNull()
|
|
->and($coupon->products)->toBe($products);
|
|
});
|
|
|
|
it('hydrates a coupon without products', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
|
|
// WHEN
|
|
$coupon = Coupon::hydrate(
|
|
id: $id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: new CouponProductArray(),
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
|
|
// THEN
|
|
expect($coupon->products->value)->toBe([])
|
|
->and($coupon->availabilityCalendar)->toBe($availabilityCalendar);
|
|
});
|
|
|
|
it('throws when validity information contains an invalid item', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
|
|
// WHEN / THEN
|
|
expect(fn (): Coupon => Coupon::hydrate(
|
|
id: $id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: new CouponValidityInformationArray(['Not a CouponValidityInformation']),
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
))->toThrow(\DomainException::class, 'Value of CouponValidityInformationArray must be CouponValidityInformation instances.');
|
|
});
|
|
|
|
it('throws when legal information contains an invalid item', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
|
|
// WHEN / THEN
|
|
expect(fn (): Coupon => Coupon::hydrate(
|
|
id: $id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: new CouponLegalInformationArray(['Not a CouponLegalInformation']),
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
))->toThrow(\DomainException::class, 'Value of CouponLegalInformationArray must be CouponLegalInformation instances.');
|
|
});
|
|
|
|
it('hydrates a coupon with an explicit updatedAt date', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN
|
|
$id = CouponId::generate();
|
|
$updatedAt = new \DateTimeImmutable('2026-09-22 10:00:00', new \DateTimeZone('UTC'));
|
|
|
|
// WHEN
|
|
$coupon = Coupon::hydrate(
|
|
$id,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
updatedAt: $updatedAt,
|
|
);
|
|
|
|
// THEN
|
|
expect($coupon->updatedAt)->toBe($updatedAt)
|
|
->and($coupon->updatedAt())->toBe($updatedAt);
|
|
});
|
|
|
|
it('creates a new coupon with a freshly generated id', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN / WHEN
|
|
$coupon = Coupon::create(
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
|
|
// THEN
|
|
expect($coupon->id())->toBeInstanceOf(CouponId::class)
|
|
->and($coupon->code)->toBe($code)
|
|
->and($coupon->name)->toBe($name)
|
|
->and($coupon->amount)->toBe($amount)
|
|
->and($coupon->picture)->toBe($picture)
|
|
->and($coupon->diffusion)->toBe($diffusion)
|
|
->and($coupon->validityInformations)->toBe($validityInformations)
|
|
->and($coupon->legalInformations)->toBe($legalInformations)
|
|
->and($coupon->processingCode)->toBe($processingCode)
|
|
->and($coupon->brandCode)->toBe($brandCode)
|
|
->and($coupon->createdBy)->toBe($createdBy)
|
|
->and($coupon->products)->toBe($products)
|
|
->and($coupon->movements)->toBe($movements)
|
|
->and($coupon->quantity)->toBe($quantity)
|
|
->and($coupon->availabilityCalendar)->toBe($availabilityCalendar)
|
|
->and($coupon->updatedAt)->toBeNull()
|
|
->and($coupon->updatedAt())->toBeNull();
|
|
});
|
|
|
|
it('generates a different id for each created coupon', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): void {
|
|
// GIVEN / WHEN
|
|
$firstCoupon = Coupon::create(
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
$secondCoupon = Coupon::create(
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
|
|
// THEN
|
|
expect($firstCoupon->id()->equals($secondCoupon->id()))->toBeFalse();
|
|
});
|
|
|
|
it('returns the creation date extracted from the id', function () use (
|
|
$code,
|
|
$name,
|
|
$amount,
|
|
$picture,
|
|
$diffusion,
|
|
$validityInformations,
|
|
$legalInformations,
|
|
$processingCode,
|
|
$brandCode,
|
|
$createdBy,
|
|
$products,
|
|
$movements,
|
|
$quantity,
|
|
$availabilityCalendar,
|
|
): 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,
|
|
code: $code,
|
|
name: $name,
|
|
amount: $amount,
|
|
picture: $picture,
|
|
diffusion: $diffusion,
|
|
validityInformations: $validityInformations,
|
|
legalInformations: $legalInformations,
|
|
processingCode: $processingCode,
|
|
brandCode: $brandCode,
|
|
createdBy: $createdBy,
|
|
products: $products,
|
|
movements: $movements,
|
|
quantity: $quantity,
|
|
availabilityCalendar: $availabilityCalendar,
|
|
);
|
|
|
|
// 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'));
|
|
});
|
|
});
|