451 lines
18 KiB
PHP
451 lines
18 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit\Lib\ApiDto;
|
|
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\AbstractIncoCompoPartDto;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\AcideGras;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\AcidesAmines;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\ApportsReference;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\ComposesSpeciaux;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\Energie;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\FruitLegumeNoix;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\GlucidesDetail;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\Identification;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\MacronutrimentsPortion;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\MacronutrimentsRef;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\Mineraux;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\NutriScore;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\PointsNutriScore;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiDto\Dto\IncoCompo\Vitamines;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoCompoId;
|
|
use Uwil\ArcadiaApiPhpClient\Lib\ApiValueObject\IncoId;
|
|
|
|
/**
|
|
* Creates an AcideGras instance with all 60 fields populated.
|
|
*/
|
|
function createCompleteAcideGras(): AcideGras
|
|
{
|
|
return new AcideGras(
|
|
nutFd: '10.5',
|
|
nutChol: '60',
|
|
nutAgt: '0.1',
|
|
nutFformiq: '0',
|
|
nutFacetiq: '0',
|
|
nutFpropioniq: '0',
|
|
nutFbutyriq: '0',
|
|
nutFvaleriq: '0',
|
|
nutFcaproiq: '0',
|
|
nutFenatiq: '0',
|
|
nutFcapryliq: '0',
|
|
nutFpelargoniq: '0',
|
|
nutFcapriq: '0',
|
|
nutFundecyliq: '0',
|
|
nutFlauriq: '0.05',
|
|
nutFtridecyliq: '0',
|
|
nutFmyristiq: '0.1',
|
|
nutFpentadecyliq: '0',
|
|
nutF16d0: '2.5',
|
|
nutFmargariq: '0',
|
|
nutFsteariq: '1.2',
|
|
nutFarachidiq: '0.05',
|
|
nutFheneicosyliq: '0',
|
|
nutFbeheniq: '0',
|
|
nutFtricosiliq: '0',
|
|
nutFlignoceriq: '0',
|
|
nutFcarboceriq: '0',
|
|
nutFcerotiq: '0',
|
|
nutFceroplastiq: '0',
|
|
nutFmontaniq: '0',
|
|
nutFnonacosyliq: '0',
|
|
nutFmelissiq: '0',
|
|
nutFlaceroiq: '0',
|
|
nutFhentriacontyliq: '0',
|
|
nutFhextriacontyliq: '0',
|
|
nutFheptatriacontyliq: '0',
|
|
nutFoctatriacontyliq: '0',
|
|
nutFnonadylique: '0',
|
|
nutFpsylliq: '0',
|
|
nutFpalm: '0.3',
|
|
nutFoleiq: '3.8',
|
|
nutF18d: '0',
|
|
nutF19d: '0',
|
|
nutF11eico: '0.1',
|
|
nutFgeddiq: '0',
|
|
nutFeruciq: '0',
|
|
nutFnervoniq: '0',
|
|
nutFhyeniq: '0',
|
|
nutFamscis: '4.2',
|
|
nutF18d2cn6: '1.8',
|
|
nutF18d3n3: '0.2',
|
|
nutF20d4: '0.05',
|
|
nutF20d5n3: '0.02',
|
|
nutF22d6n3: '0.03',
|
|
nutFapun3: '0.25',
|
|
nutFapun6: '1.85',
|
|
nutFapun9: '0',
|
|
nutFapucis: '2.1',
|
|
nutFapulc: '0.1',
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Creates a complete IncoCompo object graph with all 14 nutritional parts.
|
|
*/
|
|
function createCompleteIncoCompo(
|
|
string $id = '10',
|
|
string $idInco = '20',
|
|
): IncoCompo {
|
|
return new IncoCompo(
|
|
id: new IncoCompoId($id),
|
|
idInco: new IncoId($idInco),
|
|
identification: new Identification(
|
|
nom: 'Composition Poulet',
|
|
numero: 'COMP-001',
|
|
source: 'Laboratoire LDC',
|
|
),
|
|
energie: new Energie(
|
|
tailleReference: '100g',
|
|
valEnergKjReference: '650',
|
|
valEnergKcalReference: '155',
|
|
taillePortion: '150g',
|
|
valEnergKjPortion: '975',
|
|
valEnergKcalPortion: '232.5',
|
|
),
|
|
macronutrimentsRef: new MacronutrimentsRef(
|
|
matGrassReference: '10.5',
|
|
matGrassReferencePrec: '=',
|
|
acideGrasSatureReference: '2.5',
|
|
acideGrasSatureReferencePrec: '=',
|
|
glucidesReference: '1.0',
|
|
glucidesReferencePrec: '<',
|
|
sucreReference: '0.5',
|
|
sucreReferencePrec: '<',
|
|
fibAlimReference: '0.8',
|
|
fibAlimReferencePrec: '=',
|
|
proteineReference: '22.0',
|
|
proteineReferencePrec: '=',
|
|
selReference: '1.2',
|
|
selReferencePrec: '=',
|
|
sodiumReference: '0.48',
|
|
),
|
|
macronutrimentsPortion: new MacronutrimentsPortion(
|
|
matGrassPortion: '15.75',
|
|
matGrassPortionPrec: '=',
|
|
acideGrasSaturePortion: '3.75',
|
|
acideGrasSaturePortionPrec: '=',
|
|
glucidesPortion: '1.5',
|
|
glucidesPortionPrec: '<',
|
|
sucrePortion: '0.75',
|
|
sucrePortionPrec: '<',
|
|
fibAlimPortion: '1.2',
|
|
fibAlimPortionPrec: '=',
|
|
proteinePortion: '33.0',
|
|
proteinePortionPrec: '=',
|
|
selPortion: '1.8',
|
|
selPortionPrec: '=',
|
|
sodiumPortion: '0.72',
|
|
),
|
|
fnl: new FruitLegumeNoix(
|
|
fruitsReference: '0',
|
|
fruitsCoqueSechReference: '0',
|
|
fruitsPortion: '0',
|
|
fruitsCoqueSechPortion: '0',
|
|
fruitLegumeNoixFrais: '0',
|
|
fruitLegumeNoixFraisPortion: '0',
|
|
pourcentFruitsLegumesNoixFrais: '0',
|
|
pourcentFruits: '0',
|
|
),
|
|
apportsReference: new ApportsReference(
|
|
pourcentApportRefE14P: '12%',
|
|
pourcentApportRefKjoP: '12%',
|
|
pourcentApportRefFatP: '15%',
|
|
pourcentApportRefFatsatP: '13%',
|
|
pourcentApportRefChovalP: '1%',
|
|
pourcentApportRefSugarP: '1%',
|
|
pourcentApportRefProP: '44%',
|
|
pourcentApportRefSalteqP: '20%',
|
|
apportPort: '150g',
|
|
pSurL: '2.1',
|
|
),
|
|
nutriScore: new NutriScore(
|
|
composanteN: '5',
|
|
composanteN2022: '5',
|
|
composanteP: '2',
|
|
composanteP2022: '2',
|
|
scoreNutri: '3',
|
|
scoreNutri2022: '3',
|
|
classement: 'B',
|
|
nutriScore2022: 'B',
|
|
nutriAArt: 'Non',
|
|
viandeRouge: 'Non',
|
|
),
|
|
pointsNutriScore: new PointsNutriScore(
|
|
pointsEnergie: '1',
|
|
pointsAcideGrasSature: '1',
|
|
pointsSucres: '0',
|
|
pointsSel: '1',
|
|
pointsFibres: '0',
|
|
pointsProteines: '4',
|
|
pointsFruitsLegumesNoixFrais: '0',
|
|
),
|
|
mineraux: new Mineraux(
|
|
nutCa: '12',
|
|
nutMg: '25',
|
|
nutK: '300',
|
|
nutP: '200',
|
|
nutCld: '50',
|
|
nutFe: '1.5',
|
|
nutZn: '2.0',
|
|
nutCu: '0.1',
|
|
nutMn: '0.05',
|
|
nutSe: '15',
|
|
nutId: '10',
|
|
nutCr: '5',
|
|
nutMo: '8',
|
|
nutS6: '2',
|
|
nutNitra: '0',
|
|
),
|
|
vitamines: new Vitamines(
|
|
nutVita: '20',
|
|
nutVitb6: '0.4',
|
|
nutVitb12: '1.2',
|
|
nutVitc: '5',
|
|
nutVitd: '0.2',
|
|
nutVite: '1.0',
|
|
nutVitk: '10',
|
|
nutChocal: '0.1',
|
|
nutNia: '8.0',
|
|
nutRibf: '0.2',
|
|
nutThia: '0.1',
|
|
nutPantac: '0.8',
|
|
nutBiot: '5',
|
|
nutFoldfe: '25',
|
|
),
|
|
glucidesDetail: new GlucidesDetail(
|
|
nutStarch: '0.5',
|
|
nutMaltdex: '0',
|
|
nutSucs: '0.1',
|
|
nutGlus: '0.1',
|
|
nutLacs: '0',
|
|
nutMals: '0',
|
|
nutGalfb: '0',
|
|
nutGHc: '0',
|
|
nutFrufb: '0',
|
|
nutFrus: '0.1',
|
|
nutOlsac: '0',
|
|
nutPolyl: '0',
|
|
nutFibsol: '0.3',
|
|
nutInotl: '0',
|
|
),
|
|
acideGras: createCompleteAcideGras(),
|
|
acidesAmines: new AcidesAmines(
|
|
nutAae: '15',
|
|
nutCasn: '0',
|
|
nutWhey: '0',
|
|
),
|
|
composesSpeciaux: new ComposesSpeciaux(
|
|
nutCholn: '30',
|
|
nutCarnitine: '10',
|
|
nutTau: '5',
|
|
nutNucleotide: '2',
|
|
),
|
|
);
|
|
}
|
|
|
|
describe('IncoCompo DTO test', function (): void {
|
|
it('can instantiate IncoCompo with complete 14-part nutrition graph', function (): void {
|
|
// GIVEN
|
|
$compo = createCompleteIncoCompo('10', '20');
|
|
|
|
// THEN
|
|
expect($compo)->toBeInstanceOf(IncoCompo::class)
|
|
->and($compo)->toBeInstanceOf(Dto::class)
|
|
->and($compo->id)->toBeInstanceOf(IncoCompoId::class)
|
|
->and($compo->id->value)->toBe('10')
|
|
->and($compo->idInco)->toBeInstanceOf(IncoId::class)
|
|
->and($compo->idInco->value)->toBe('20');
|
|
|
|
// Verify all 14 parts are instances of AbstractIncoCompoPartDto
|
|
expect($compo->identification)->toBeInstanceOf(Identification::class)
|
|
->and($compo->identification)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->identification->nom)->toBe('Composition Poulet')
|
|
->and($compo->identification->numero)->toBe('COMP-001')
|
|
->and($compo->identification->source)->toBe('Laboratoire LDC');
|
|
|
|
expect($compo->energie)->toBeInstanceOf(Energie::class)
|
|
->and($compo->energie)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->energie->valEnergKcalReference)->toBe('155')
|
|
->and($compo->energie->valEnergKcalPortion)->toBe('232.5');
|
|
|
|
expect($compo->macronutrimentsRef)->toBeInstanceOf(MacronutrimentsRef::class)
|
|
->and($compo->macronutrimentsRef)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->macronutrimentsRef->proteineReference)->toBe('22.0');
|
|
|
|
expect($compo->macronutrimentsPortion)->toBeInstanceOf(MacronutrimentsPortion::class)
|
|
->and($compo->macronutrimentsPortion)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->macronutrimentsPortion->proteinePortion)->toBe('33.0');
|
|
|
|
expect($compo->fnl)->toBeInstanceOf(FruitLegumeNoix::class)
|
|
->and($compo->fnl)->toBeInstanceOf(AbstractIncoCompoPartDto::class);
|
|
|
|
expect($compo->apportsReference)->toBeInstanceOf(ApportsReference::class)
|
|
->and($compo->apportsReference)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->apportsReference->pSurL)->toBe('2.1');
|
|
|
|
expect($compo->nutriScore)->toBeInstanceOf(NutriScore::class)
|
|
->and($compo->nutriScore)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->nutriScore->classement)->toBe('B');
|
|
|
|
expect($compo->pointsNutriScore)->toBeInstanceOf(PointsNutriScore::class)
|
|
->and($compo->pointsNutriScore)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->pointsNutriScore->pointsProteines)->toBe('4');
|
|
|
|
expect($compo->mineraux)->toBeInstanceOf(Mineraux::class)
|
|
->and($compo->mineraux)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->mineraux->nutCa)->toBe('12');
|
|
|
|
expect($compo->vitamines)->toBeInstanceOf(Vitamines::class)
|
|
->and($compo->vitamines)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->vitamines->nutVita)->toBe('20');
|
|
|
|
expect($compo->glucidesDetail)->toBeInstanceOf(GlucidesDetail::class)
|
|
->and($compo->glucidesDetail)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->glucidesDetail->nutStarch)->toBe('0.5');
|
|
|
|
expect($compo->acideGras)->toBeInstanceOf(AcideGras::class)
|
|
->and($compo->acideGras)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->acideGras->nutFd)->toBe('10.5')
|
|
->and($compo->acideGras->nutChol)->toBe('60');
|
|
|
|
expect($compo->acidesAmines)->toBeInstanceOf(AcidesAmines::class)
|
|
->and($compo->acidesAmines)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->acidesAmines->nutAae)->toBe('15');
|
|
|
|
expect($compo->composesSpeciaux)->toBeInstanceOf(ComposesSpeciaux::class)
|
|
->and($compo->composesSpeciaux)->toBeInstanceOf(AbstractIncoCompoPartDto::class)
|
|
->and($compo->composesSpeciaux->nutCholn)->toBe('30');
|
|
});
|
|
|
|
it('can jsonSerialize complete IncoCompo graph recursively', function (): void {
|
|
// GIVEN
|
|
$compo = createCompleteIncoCompo('10', '20');
|
|
|
|
// WHEN
|
|
$serialized = $compo->jsonSerialize();
|
|
|
|
// THEN
|
|
expect($serialized)->toBeArray()
|
|
->and($serialized['id'])->toBe('10')
|
|
->and($serialized['idInco'])->toBe('20')
|
|
->and($serialized['identification'])->toBe($compo->identification)
|
|
->and($serialized['energie'])->toBe($compo->energie)
|
|
->and($serialized['macronutrimentsRef'])->toBe($compo->macronutrimentsRef)
|
|
->and($serialized['macronutrimentsPortion'])->toBe($compo->macronutrimentsPortion)
|
|
->and($serialized['fnl'])->toBe($compo->fnl)
|
|
->and($serialized['apportsReference'])->toBe($compo->apportsReference)
|
|
->and($serialized['nutriScore'])->toBe($compo->nutriScore)
|
|
->and($serialized['pointsNutriScore'])->toBe($compo->pointsNutriScore)
|
|
->and($serialized['mineraux'])->toBe($compo->mineraux)
|
|
->and($serialized['vitamines'])->toBe($compo->vitamines)
|
|
->and($serialized['glucidesDetail'])->toBe($compo->glucidesDetail)
|
|
->and($serialized['acideGras'])->toBe($compo->acideGras)
|
|
->and($serialized['acidesAmines'])->toBe($compo->acidesAmines)
|
|
->and($serialized['composesSpeciaux'])->toBe($compo->composesSpeciaux);
|
|
|
|
// Recursive json_encode check
|
|
$jsonString = json_encode($compo);
|
|
expect($jsonString)->toBeString();
|
|
$decoded = json_decode((string) $jsonString, true);
|
|
expect($decoded)->toBeArray()
|
|
->and($decoded['id'])->toBe('10')
|
|
->and($decoded['idInco'])->toBe('20')
|
|
->and($decoded['identification']['nom'])->toBe('Composition Poulet')
|
|
->and($decoded['energie']['valEnergKcalReference'])->toBe('155')
|
|
->and($decoded['macronutrimentsRef']['proteineReference'])->toBe('22.0')
|
|
->and($decoded['nutriScore']['classement'])->toBe('B')
|
|
->and($decoded['mineraux']['nutCa'])->toBe('12')
|
|
->and($decoded['vitamines']['nutVita'])->toBe('20')
|
|
->and($decoded['acideGras']['nutChol'])->toBe('60')
|
|
->and($decoded['acidesAmines']['nutAae'])->toBe('15')
|
|
->and($decoded['composesSpeciaux']['nutCholn'])->toBe('30');
|
|
});
|
|
|
|
it('exercises humanReadableValues and units across compo parts', function (): void {
|
|
// GIVEN
|
|
$compo = createCompleteIncoCompo();
|
|
|
|
// WHEN & THEN: Energie
|
|
$energyValues = $compo->energie->humanReadableValues();
|
|
expect($energyValues)->toBeArray()
|
|
->and($energyValues['Taille de référence'])->toBe('100g')
|
|
->and($energyValues['Énergie (kJ) / 100g'])->toBe('650')
|
|
->and($energyValues['Énergie (kcal) / 100g'])->toBe('155');
|
|
|
|
$energyUnits = Energie::units();
|
|
expect($energyUnits['valEnergKjReference'])->toBe('kJ')
|
|
->and($energyUnits['valEnergKcalReference'])->toBe('kcal');
|
|
|
|
// Energie string cast
|
|
$energyString = (string) $compo->energie;
|
|
expect($energyString)->toContain('Taille de référence : 100g')
|
|
->and($energyString)->toContain('Énergie (kcal) / 100g : 155 kcal');
|
|
|
|
// Identification human readable
|
|
$identValues = $compo->identification->humanReadableValues();
|
|
expect($identValues['Nom'])->toBe('Composition Poulet')
|
|
->and($identValues['Numéro'])->toBe('COMP-001')
|
|
->and($identValues['Source'])->toBe('Laboratoire LDC');
|
|
|
|
// NutriScore human readable
|
|
$nsValues = $compo->nutriScore->humanReadableValues();
|
|
expect($nsValues['Classement (A-E)'])->toBe('B');
|
|
|
|
// AcideGras units
|
|
$agUnits = AcideGras::units();
|
|
expect($agUnits['nutChol'])->toBe('mg')
|
|
->and($agUnits['nutFd'])->toBe('g');
|
|
});
|
|
|
|
it('covers fieldLabels, fieldUnits, humanReadableValues, units, humanReadableUnits, and string cast for all 14 nutritional parts', function (
|
|
string $partClass,
|
|
string $property
|
|
): void {
|
|
// GIVEN
|
|
$compo = createCompleteIncoCompo();
|
|
/** @var AbstractIncoCompoPartDto $part */
|
|
$part = $compo->{$property};
|
|
|
|
// WHEN
|
|
$humanValues = $part->humanReadableValues();
|
|
$arrayValues = $part->toArray();
|
|
$units = $partClass::units();
|
|
$humanUnits = $partClass::humanReadableUnits();
|
|
$asString = (string) $part;
|
|
|
|
// THEN
|
|
expect($humanValues)->toBeArray()->not->toBeEmpty()
|
|
->and($arrayValues)->toBeArray()->not->toBeEmpty()
|
|
->and($units)->toBeArray()->not->toBeEmpty()
|
|
->and($humanUnits)->toBeArray()->not->toBeEmpty()
|
|
->and($asString)->toBeString()->not->toBeEmpty();
|
|
})->with([
|
|
'Identification' => [Identification::class, 'identification'],
|
|
'Energie' => [Energie::class, 'energie'],
|
|
'MacronutrimentsRef' => [MacronutrimentsRef::class, 'macronutrimentsRef'],
|
|
'MacronutrimentsPortion' => [MacronutrimentsPortion::class, 'macronutrimentsPortion'],
|
|
'FruitLegumeNoix' => [FruitLegumeNoix::class, 'fnl'],
|
|
'ApportsReference' => [ApportsReference::class, 'apportsReference'],
|
|
'NutriScore' => [NutriScore::class, 'nutriScore'],
|
|
'PointsNutriScore' => [PointsNutriScore::class, 'pointsNutriScore'],
|
|
'Mineraux' => [Mineraux::class, 'mineraux'],
|
|
'Vitamines' => [Vitamines::class, 'vitamines'],
|
|
'GlucidesDetail' => [GlucidesDetail::class, 'glucidesDetail'],
|
|
'AcideGras' => [AcideGras::class, 'acideGras'],
|
|
'AcidesAmines' => [AcidesAmines::class, 'acidesAmines'],
|
|
'ComposesSpeciaux' => [ComposesSpeciaux::class, 'composesSpeciaux'],
|
|
]);
|
|
});
|