ldc-arcadia-api/tests/Unit/Infra/Adapters/Parsers/IncoCompositionParserTest.php
Jérémy Munsch dc836f911a
refactor(parser): normalize percentage value handling
Refactor percentage value parsing to use a dedicated method for better readability and maintainability.
Add tests to ensure legacy overflow percentages are normalized correctly.
2026-10-06 15:46:22 +02:00

191 lines
7.8 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Infra\Adapters\Parsers;
use Domain\Models\ValueObjects\Inco\Composition\AminoAcids;
use Domain\Models\ValueObjects\Inco\Composition\CarbohydratesDetail;
use Domain\Models\ValueObjects\Inco\Composition\Energy;
use Domain\Models\ValueObjects\Inco\Composition\FattyAcids;
use Domain\Models\ValueObjects\Inco\Composition\FreshProduceAndNuts;
use Domain\Models\ValueObjects\Inco\Composition\Identification;
use Domain\Models\ValueObjects\Inco\Composition\Minerals;
use Domain\Models\ValueObjects\Inco\Composition\NutriScore;
use Domain\Models\ValueObjects\Inco\Composition\NutriScorePoints;
use Domain\Models\ValueObjects\Inco\Composition\PortionMacronutrients;
use Domain\Models\ValueObjects\Inco\Composition\ReferenceIntakes;
use Domain\Models\ValueObjects\Inco\Composition\ReferenceMacronutrients;
use Domain\Models\ValueObjects\Inco\Composition\SpecialCompounds;
use Domain\Models\ValueObjects\Inco\Composition\Vitamins;
use Infra\Adapters\Parsers\IncoCompositionParser;
use PHPUnit\Framework\TestCase;
covers(IncoCompositionParser::class);
uses(TestCase::class);
describe('IncoCompositionParser', function (): void {
it('parses identification from row data', function (): void {
$row = [
'NOM' => 'NUGGETS DE POULET',
'NUMERO' => '96504',
'SOURCE' => '1',
'ID_INCO' => '47789',
];
$vo = IncoCompositionParser::toIdentification($row);
expect($vo)->toBeInstanceOf(Identification::class)
->and($vo->name)->toBe('NUGGETS DE POULET')
->and($vo->number)->toBe('96504')
->and($vo->source)->toBe('1');
});
it('parses energy values for reference and portion', function (): void {
$row = [
'TAILLE_REF' => '100g',
'VAL_ENERG_KJ_R' => '890',
'VAL_ENERG_KCAL_R' => '212',
'TAILLE_PORT' => '150g',
'VAL_ENERG_KJ_P' => '1335',
'VAL_ENERG_KCAL_P' => '318',
];
$vo = IncoCompositionParser::toEnergy($row);
expect($vo)->toBeInstanceOf(Energy::class)
->and($vo->reference->size)->toBe('100g')
->and($vo->reference->energyKj)->toBe('890')
->and($vo->reference->energyKcal)->toBe('212')
->and($vo->portion->size)->toBe('150g')
->and($vo->portion->energyKj)->toBe('1335')
->and($vo->portion->energyKcal)->toBe('318');
});
it('parses reference and portion macronutrients', function (): void {
$row = [
'MAT_GRASS_R' => '9.5',
'AGS_R' => '1.8',
'GLUCIDES_R' => '16.0',
'SUCRE_R' => '0.8',
'FIB_ALIM_R' => '1.5',
'PROTEINE_R' => '15.0',
'SEL_R' => '1.10',
'MAT_GRASS_P' => '14.25',
'AGS_P' => '2.7',
'GLUCIDES_P' => '24.0',
'SUCRE_P' => '1.2',
'FIB_ALIM_P' => '2.25',
'PROTEINE_P' => '22.5',
'SEL_P' => '1.65',
];
$refMacro = IncoCompositionParser::toReferenceMacronutrients($row);
$portMacro = IncoCompositionParser::toPortionMacronutrients($row);
expect($refMacro)->toBeInstanceOf(ReferenceMacronutrients::class)
->and($refMacro->fat->amount)->toBe('9.5')
->and($refMacro->protein->amount)->toBe('15.0')
->and($portMacro)->toBeInstanceOf(PortionMacronutrients::class)
->and($portMacro->fat->amount)->toBe('14.25')
->and($portMacro->protein->amount)->toBe('22.5');
});
it('parses fresh produce and nuts amounts', function (): void {
$row = [
'FRUITS_R' => '10',
'FRUITS_COQUE_SECH_R' => '5',
'FRUITS_P' => '15',
'FRUITS_COQUE_SECH_P' => '7.5',
'POURCENT_FNL_FRAIS' => '20',
'POURCENT_FRUITS' => '15',
];
$vo = IncoCompositionParser::toFreshProduceAndNuts($row);
expect($vo)->toBeInstanceOf(FreshProduceAndNuts::class)
->and($vo->reference->fruits)->toBe('10')
->and($vo->reference->nuts)->toBe('5')
->and($vo->freshFnlPercentage->value)->toBe('20');
});
it('parses reference intakes and nutriscore points', function (): void {
$row = [
'POURCENT_APPORT_REF_E14_P' => '10',
'POURCENT_APPORT_REF_KJO_P' => '10',
'POURCENT_APPORT_REF_FAT_P' => '12',
'POURCENT_APPORT_REF_FATSAT_P' => '14',
'POURCENT_APPORT_REF_CHOVAL_P' => '6',
'POURCENT_APPORT_REF_SUGAR_P' => '1',
'POURCENT_APPORT_REF_PRO_P' => '30',
'POURCENT_APPORT_REF_SALTEQ_P' => '18',
'APPORT_PORT' => '150g',
'POINTS_ENERGIE' => '3',
'POINTS_AGS' => '2',
'POINTS_SUCRES' => '0',
'POINTS_SEL' => '1',
'POINTS_FIBRES' => '1',
'POINTS_PROTEINES' => '4',
'POINTS_FNL_FRAIS' => '0',
'COMPOSANTE_N' => '6',
'SCORE_NUTRI' => '1',
'CLASSEMENT' => 'B',
];
$intakes = IncoCompositionParser::toReferenceIntakes($row);
$points = IncoCompositionParser::toNutriScorePoints($row);
$score = IncoCompositionParser::toNutriScore($row);
expect($intakes)->toBeInstanceOf(ReferenceIntakes::class)
->and($intakes->portionAmount)->toBe('150g')
->and($points)->toBeInstanceOf(NutriScorePoints::class)
->and($points->energyPoints)->toBe('3')
->and($score)->toBeInstanceOf(NutriScore::class)
->and($score->grade)->toBe('B');
});
it('normalizes legacy overflow percentages by dividing by 10', function (): void {
$row = [
'POURCENT_APPORT_REF_PRO_P' => '130',
'POURCENT_APPORT_REF_FAT_P' => '105',
'POURCENT_APPORT_REF_E14_P' => '10',
'POURCENT_APPORT_REF_KJO_P' => '10',
'POURCENT_APPORT_REF_FATSAT_P' => '14',
'POURCENT_APPORT_REF_CHOVAL_P' => '6',
'POURCENT_APPORT_REF_SUGAR_P' => '1',
'POURCENT_APPORT_REF_SALTEQ_P' => '18',
'APPORT_PORT' => '100g',
];
$intakes = IncoCompositionParser::toReferenceIntakes($row);
expect($intakes->protein->value)->toBe('13')
->and($intakes->fat->value)->toBe('10.5');
});
it('parses minerals, vitamins, fatty acids, amino acids, and special compounds', function (): void {
$row = [
'NUT_CA' => '120',
'NUT_FE' => '2.5',
'NUT_VITA' => '80',
'NUT_VITC' => '15',
'NUT_STARCH' => '10',
'NUT_SUCS' => '0.5',
'NUT_CHOL' => '45',
'NUT_FOLEIQ' => '3.2',
'NUT_AAE' => '12',
'NUT_CHOLN' => '50',
'NUT_CARNITINE' => '10',
'NUT_TAU' => '20',
'NUT_NUCLEOTIDE' => '5',
];
expect(IncoCompositionParser::toMinerals($row))->toBeInstanceOf(Minerals::class)
->and(IncoCompositionParser::toVitamines($row))->toBeInstanceOf(Vitamins::class)
->and(IncoCompositionParser::toCarbohydratesDetail($row))->toBeInstanceOf(CarbohydratesDetail::class)
->and(IncoCompositionParser::toFattyAcids($row))->toBeInstanceOf(FattyAcids::class)
->and(IncoCompositionParser::toAminoAcids($row))->toBeInstanceOf(AminoAcids::class)
->and(IncoCompositionParser::toSpecialCompounds($row))->toBeInstanceOf(SpecialCompounds::class);
});
});