ldc-arcadia-genesis-php-client/tests/Unit/Mapper/IncoMapperTest.php

310 lines
12 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Mapper;
require_once __DIR__ . '/PaginationMetaForTests.php';
use DateTime;
use DateTimeInterface;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Brand;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Additive;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Allegations;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Allergen;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\IncoWeight;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Ingredients;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\Nutriscore;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\PortionAmount;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\PortionType;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\Inco\StorageCondition;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PageOf;
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\PaginationDto;
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\BrandCode;
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoCompoId;
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoId;
use Uwil\ArcadiaApiPhpClient\Mapper\IncoMapper;
use Uwil\ArcadiaKiotaOpenApiClient\Models\Inco as KiotaInco;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoAdditive;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoAllegations;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoBrand;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoIngredients;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoListResponse;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoNutriscore;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoNutriscore_grade;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoPortionAmount;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoStorageCondition;
use Uwil\ArcadiaKiotaOpenApiClient\Models\IncoWeight as KiotaIncoWeight;
describe('IncoMapper test', function () {
it('can instanciate IncoMapper', function () {
// GIVEN / WHEN
$mapper = new IncoMapper();
// THEN
expect($mapper)->toBeInstanceOf(IncoMapper::class);
});
it('can map full kiota model to an inco dto', function () {
// GIVEN
$kiotaModel = new KiotaInco();
$kiotaModel->setIncoId('100');
$kiotaModel->setName('Poulet fermier');
$kiotaModel->setLabel('Poulet fermier Label Rouge');
$kiotaModel->setDescription('Poulet élevé en plein air 1.2kg');
$kiotaModel->setSellArguments('Origine France');
$kiotaModel->setPreparationAdvices('Cuire au four à 180°C pendant 1h15');
$kiotaModel->setTips('Arroser régulièrement');
$kiotaModel->setSellFamilly('Volaille');
$kiotaModel->setIsSeasonal(true);
$kiotaModel->setIncoCompoId('200');
$kiotaModel->setCreatedAt(new DateTime('2024-01-01 10:00:00'));
$kiotaModel->setUpdatedAt(new DateTime('2024-06-01 12:00:00'));
$brand = new IncoBrand();
$brand->setCode('LGL39');
$brand->setLabel('Le Gaulois');
$kiotaModel->setBrand($brand);
$allegations = new IncoAllegations();
$allegations->setAllegations(['Sans OGM']);
$allegations->setHealth(['Riche en protéines']);
$allegations->setNutrition(['Faible en matières grasses']);
$allegations->setOther(['Label Rouge']);
$kiotaModel->setAllegations($allegations);
$ingredients = new IncoIngredients();
$ingredients->setAdditionalData([
'groupe1' => ['Poulet fermier 98%', 'Sel 2%'],
]);
$kiotaModel->setIngredients($ingredients);
$portions = new IncoPortionAmount();
$portions->setLowPart(4);
$portions->setHighPart(6);
$portions->setApproximative(true);
$kiotaModel->setPortions($portions);
$kiotaModel->setAllergens(['Gluten', 'Soja']);
$weight = new KiotaIncoWeight();
$weight->setNetWeight(1200);
$weight->setGrossWeight(1350);
$weight->setTheoreticalAverage(1250);
$kiotaModel->setWeight($weight);
$nutriscore = new IncoNutriscore();
$nutriscore->setGrade(new IncoNutriscore_grade(IncoNutriscore_grade::A));
$kiotaModel->setNutriscore($nutriscore);
$storageCondition = new IncoStorageCondition();
$storageCondition->setInstructions('Conserver entre 0°C et 4°C');
$kiotaModel->setStorageCondition($storageCondition);
$additive = new IncoAdditive();
$additive->setCode('E300');
$additive->setLabel('Acide ascorbique');
$kiotaModel->setAdditives([$additive]);
// WHEN
$dto = (new IncoMapper())->toDto($kiotaModel);
// THEN
expect($dto)->toBeInstanceOf(Inco::class);
expect($dto->id)->toBeInstanceOf(IncoId::class);
expect($dto->id->value)->toBe('100');
expect($dto->name)->toBe('Poulet fermier');
expect($dto->libelle)->toBe('Poulet fermier Label Rouge');
expect($dto->description)->toBe('Poulet élevé en plein air 1.2kg');
expect($dto->sellArguments)->toBe('Origine France');
expect($dto->preparationAdvices)->toBe('Cuire au four à 180°C pendant 1h15');
expect($dto->tips)->toBe('Arroser régulièrement');
expect($dto->sellFamilly)->toBe('Volaille');
expect($dto->isSeasonal)->toBeTrue();
// Allegations
expect($dto->allegations)->toBeInstanceOf(Allegations::class);
expect($dto->allegations->allegations())->toBe(['Sans OGM']);
expect($dto->allegations->health())->toBe(['Riche en protéines']);
expect($dto->allegations->nutrition())->toBe(['Faible en matières grasses']);
expect($dto->allegations->other())->toBe(['Label Rouge']);
// Ingredients
expect($dto->ingredients)->toBeInstanceOf(Ingredients::class);
expect($dto->ingredients->groups)->toHaveKey('groupe1');
expect($dto->ingredients->groups['groupe1'])->toBe(['Poulet fermier 98%', 'Sel 2%']);
// Portions
expect($dto->portions)->toBeInstanceOf(PortionAmount::class);
expect($dto->portions->getLowValue())->toBe(4.0);
expect($dto->portions->getHighValue())->toBe(6.0);
expect($dto->portions->getType())->toBe(PortionType::approximative);
// Allergens
expect($dto->allergens)->toHaveCount(2);
expect($dto->allergens[0])->toBeInstanceOf(Allergen::class);
expect($dto->allergens[0]->code)->toBe(1);
expect($dto->allergens[0]->label)->toBe('Gluten');
expect($dto->allergens[1]->code)->toBe(2);
expect($dto->allergens[1]->label)->toBe('Soja');
// Brand
expect($dto->brand)->toBeInstanceOf(Brand::class);
expect($dto->brand->code)->toBeInstanceOf(BrandCode::class);
expect($dto->brand->code->value)->toBe('LGL39');
expect($dto->brand->label)->toBe('Le Gaulois');
// Weight
expect($dto->weight)->toBeInstanceOf(IncoWeight::class);
expect($dto->weight->netUvc)->toBe(1200);
expect($dto->weight->brutUvc)->toBe(1350);
expect($dto->weight->moyTheo)->toBe(1250);
// Nutriscore
expect($dto->nutriscore)->toBeInstanceOf(Nutriscore::class);
expect($dto->nutriscore->grade)->toBe('A');
// StorageCondition
expect($dto->storageCondition)->toBeInstanceOf(StorageCondition::class);
expect($dto->storageCondition->instructions)->toBe('Conserver entre 0°C et 4°C');
// Additives
expect($dto->additives)->toHaveCount(1);
expect($dto->additives[0])->toBeInstanceOf(Additive::class);
expect($dto->additives[0]->code)->toBe('E300');
expect($dto->additives[0]->label)->toBe('Acide ascorbique');
// Compo & Timestamps
expect($dto->compo)->toBeInstanceOf(IncoCompoId::class);
expect($dto->compo?->value)->toBe('200');
expect($dto->createdAt)->toBeInstanceOf(DateTimeInterface::class);
expect($dto->createdAt?->format('Y-m-d H:i:s'))->toBe('2024-01-01 10:00:00');
expect($dto->updatedAt)->toBeInstanceOf(DateTimeInterface::class);
expect($dto->updatedAt?->format('Y-m-d H:i:s'))->toBe('2024-06-01 12:00:00');
});
it('can map minimal kiota model to an inco dto with default/null values', function () {
// GIVEN
$kiotaModel = new KiotaInco();
$brand = new IncoBrand();
$brand->setCode('LGL39');
$kiotaModel->setBrand($brand);
// WHEN
$dto = (new IncoMapper())->toDto($kiotaModel);
// THEN
expect($dto)->toBeInstanceOf(Inco::class);
expect($dto->id->value)->toBe('0');
expect($dto->name)->toBe('');
expect($dto->libelle)->toBe('');
expect($dto->description)->toBe('');
expect($dto->sellArguments)->toBe('');
expect($dto->preparationAdvices)->toBe('');
expect($dto->tips)->toBeNull();
expect($dto->sellFamilly)->toBeNull();
expect($dto->isSeasonal)->toBeFalse();
expect($dto->allegations->allegations())->toBe([]);
expect($dto->ingredients->groups)->toBe([]);
expect($dto->portions)->toBeNull();
expect($dto->allergens)->toBe([]);
expect($dto->brand->code->value)->toBe('LGL39');
expect($dto->brand->label)->toBe('Marque');
expect($dto->weight)->toBeNull();
expect($dto->nutriscore)->toBeNull();
expect($dto->storageCondition)->toBeNull();
expect($dto->additives)->toBe([]);
expect($dto->compo)->toBeNull();
expect($dto->createdAt)->toBeNull();
expect($dto->updatedAt)->toBeNull();
});
it('handles null nutriscore grade gracefully', function () {
// GIVEN
$kiotaModel = new KiotaInco();
$brand = new IncoBrand();
$brand->setCode('LGL39');
$kiotaModel->setBrand($brand);
$nutriscore = new IncoNutriscore();
$nutriscore->setGrade(null);
$kiotaModel->setNutriscore($nutriscore);
// WHEN
$dto = (new IncoMapper())->toDto($kiotaModel);
// THEN
expect($dto->nutriscore)->toBeNull();
});
it('handles invalid additive gracefully', function () {
// GIVEN
$kiotaModel = new KiotaInco();
$brand = new IncoBrand();
$brand->setCode('LGL39');
$kiotaModel->setBrand($brand);
$invalidAdditive = new IncoAdditive();
$invalidAdditive->setCode('INVALID_E');
$invalidAdditive->setLabel('Invalid Additive');
$validAdditive = new IncoAdditive();
$validAdditive->setCode('E300');
$validAdditive->setLabel('Acide ascorbique');
$kiotaModel->setAdditives([$invalidAdditive, $validAdditive]);
// WHEN
$dto = (new IncoMapper())->toDto($kiotaModel);
// THEN
expect($dto->additives)->toHaveCount(1);
expect($dto->additives[0]->code)->toBe('E300');
});
it('can map all properties from kiota model to inco dto', function () {
// GIVEN
[
$pagination,
$paginationMeta,
] = generaterFirstPagePaginationMeta();
$response = new IncoListResponse();
$response->setIncoSheets([]);
$response->setPagination($paginationMeta);
// WHEN
$incoPageDto = (new IncoMapper())->toPage($response, $pagination);
// THEN
expect($incoPageDto)->toBeInstanceOf(PageOf::class);
expect($incoPageDto->items())->toBeArray();
expect($incoPageDto->pagination())->toBeInstanceOf(PaginationDto::class);
});
it('can map list response with items to page of inco dto', function () {
// GIVEN
[
$pagination,
$paginationMeta,
] = generaterFirstPagePaginationMeta();
$kiotaInco = new KiotaInco();
$kiotaInco->setIncoId('100');
$brand = new IncoBrand();
$brand->setCode('LGL39');
$kiotaInco->setBrand($brand);
$response = new IncoListResponse();
$response->setIncoSheets([$kiotaInco]);
$response->setPagination($paginationMeta);
// WHEN
$incoPageDto = (new IncoMapper())->toPage($response, $pagination);
// THEN
expect($incoPageDto)->toBeInstanceOf(PageOf::class);
expect($incoPageDto->items())->toHaveCount(1);
expect($incoPageDto->items()[0])->toBeInstanceOf(Inco::class);
expect($incoPageDto->items()[0]->id->value)->toBe('100');
});
});