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); $wrapper = new IncoListResponse_incoSheets(); $wrapper->setInco($kiotaInco); $response = new IncoListResponse(); $response->setIncoSheets([$wrapper]); $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'); }); });