ldc-boutique-cnc-sable/tests/Unit/Infra/Adapters/Serializers/BasketSerializerTest.php
2026-10-27 09:58:12 +01:00

167 lines
6.5 KiB
PHP

<?php
declare(strict_types=1);
use Domain\Enums\ProductBrand;
use Domain\Enums\TaxRate;
use Domain\Enums\Units\OrderUnit;
use Domain\Models\Entities\Basket;
use Domain\Models\ValueObjects\BasketProduct;
use Domain\Models\ValueObjects\Entities\BasketId;
use Domain\Models\ValueObjects\Entities\ProductId;
use Domain\Models\ValueObjects\IncoId;
use Infrastructure\Adapters\Serializers\BasketSerializer;
use Money\Currency;
use Money\Money;
use Ramsey\Uuid\Uuid;
it('serializes and deserializes basket correctly', function () {
describe('BasketSerializer', function () {
// GIVEN
$serializer = new BasketSerializer();
$basketIdStr = \Symfony\Component\Uid\Uuid::v7()->toRfc4122();
$productIdStr = \Symfony\Component\Uid\Uuid::v7()->toRfc4122();
$basketProduct = new BasketProduct(
id: new ProductId(Uuid::fromString($productIdStr)),
name: 'Product 1',
qty: 2,
unitPriceHt: new Money(1000, new Currency('EUR')),
unitDiscount: new Money(100, new Currency('EUR')),
taxRate: TaxRate::TVA_20,
weightGrams: 500,
brand: ProductBrand::loue,
incoId: new IncoId(12345),
orderUnit: OrderUnit::PCE,
slug: 'product-1',
picture: 'pic.png',
description: 'desc',
weightVariable: true,
discountRate: 0.1,
priceKgTtc: new Money(2000, new Currency('EUR')),
options: ['color' => 'red']
);
$basket = new Basket(
id: new BasketId(Uuid::fromString($basketIdStr)),
items: [$productIdStr => $basketProduct]
);
// WHEN
$array = $serializer->toArray($basket);
$array = json_decode(json_encode($array), true);
$deserializedBasket = $serializer->fromArray($array);
// THEN
expect($array)->toBeArray()
->and($array['id'])->toBe($basketIdStr)
->and($array['items'][0]['id'])->toBe($productIdStr)
->and($array['items'][0]['name'])->toBe('Product 1')
->and($array['items'][0]['taxRate'])->toBe(TaxRate::TVA_20->value)
->and($deserializedBasket->id->value->toString())->toBe($basketIdStr)
->and($deserializedBasket->items())->toHaveCount(1)
->and($deserializedBasket->items()[$productIdStr]->name)->toBe('Product 1')
->and($deserializedBasket->items()[$productIdStr]->weightVariable)->toBeTrue()
->and($deserializedBasket->items()[$productIdStr]->options)->toBe(['color' => 'red']);
});
it('throws exception if currency is missing during deserialization', function () {
// GIVEN
$serializer = new BasketSerializer();
$productIdStr = \Symfony\Component\Uid\Uuid::v7()->toRfc4122();
$data = [
'id' => \Symfony\Component\Uid\Uuid::v7()->toRfc4122(),
'items' => [
[
'id' => $productIdStr,
'name' => 'Test',
'qty' => 1,
'unitPriceHt' => ['amount' => 1000, 'currency' => ''],
'unitDiscount' => ['amount' => 100, 'currency' => 'EUR'],
'taxRate' => TaxRate::TVA_20->value,
'weightGrams' => 500,
'orderUnit' => OrderUnit::PCE->value,
'slug' => 'test',
'weightVariable' => false,
'priceKgTtc' => ['amount' => 2000, 'currency' => 'EUR'],
],
],
];
// WHEN
$action = fn () => $serializer->fromArray($data);
// THEN
expect($action)->toThrow(
\DomainException::class,
'Currency is required for unitPriceHt of item with id ' . $productIdStr
);
});
it('throws exception if currency is missing for unitDiscount', function () {
// GIVEN
$serializer = new BasketSerializer();
$productIdStr = \Symfony\Component\Uid\Uuid::v7()->toRfc4122();
$data = [
'id' => \Symfony\Component\Uid\Uuid::v7()->toRfc4122(),
'items' => [
[
'id' => $productIdStr,
'name' => 'Test',
'qty' => 1,
'unitPriceHt' => ['amount' => 1000, 'currency' => 'EUR'],
'unitDiscount' => ['amount' => 100, 'currency' => ''],
'taxRate' => TaxRate::TVA_20->value,
'weightGrams' => 500,
'orderUnit' => OrderUnit::PCE->value,
'slug' => 'test',
'weightVariable' => false,
'priceKgTtc' => ['amount' => 2000, 'currency' => 'EUR'],
],
],
];
// WHEN
$action = fn () => $serializer->fromArray($data);
// THEN
expect($action)->toThrow(
\DomainException::class,
'Currency is required for unitDiscount of item with id ' . $productIdStr
);
});
it('throws exception if currency is missing for priceKgTtc', function () {
// GIVEN
$serializer = new BasketSerializer();
$productIdStr = \Symfony\Component\Uid\Uuid::v7()->toRfc4122();
$data = [
'id' => \Symfony\Component\Uid\Uuid::v7()->toRfc4122(),
'items' => [
[
'id' => $productIdStr,
'name' => 'Test',
'qty' => 1,
'unitPriceHt' => ['amount' => 1000, 'currency' => 'EUR'],
'unitDiscount' => ['amount' => 100, 'currency' => 'EUR'],
'taxRate' => TaxRate::TVA_20->value,
'weightGrams' => 500,
'orderUnit' => OrderUnit::PCE->value,
'slug' => 'test',
'weightVariable' => false,
'priceKgTtc' => ['amount' => 2000, 'currency' => ''],
],
],
];
// WHEN
$action = fn () => $serializer->fromArray($data);
// THEN
expect($action)->toThrow(
\DomainException::class,
'Currency is required for priceKgTtc of item with id ' . $productIdStr
);
});
});