ldc-arcadia-api/tests/Unit/Infra/Adapters/Parsers/IncoParserTest.php

159 lines
6.3 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Tests\Unit\Infra\Adapters\Parsers;
use Domain\Models\ValueObjects\Inco\Additive;
use Domain\Models\ValueObjects\Inco\Allegations;
use Domain\Models\ValueObjects\Inco\Allergen;
use Domain\Models\ValueObjects\Inco\IncoWeight;
use Domain\Models\ValueObjects\Inco\PortionAmount;
use Domain\Models\ValueObjects\Inco\StorageCondition;
use Infra\Adapters\Parsers\IncoParser;
use PHPUnit\Framework\TestCase;
covers(IncoParser::class);
uses(TestCase::class);
describe('IncoParser', function (): void {
describe('toAllegations', function (): void {
it('parses allegations across 4 categories and filters out "aucun"', function (): void {
$vo = IncoParser::toAllegations(
allegations: 'sans conservateur, aucun colorant',
sante: 'riche en fer',
nutrit: 'faible en gras',
autre: '100% français'
);
expect($vo)->toBeInstanceOf(Allegations::class)
->and($vo->allegations())->toContain('Sans conservateur')
->and($vo->allegations())->not->toContain('aucun colorant')
->and($vo->health())->toContain('Riche en fer')
->and($vo->nutrition())->toContain('Faible en gras')
->and($vo->other())->toContain('100% français');
});
});
describe('toPortionAmount', function (): void {
it('parses exact portion amount', function (): void {
$vo = IncoParser::toPortionAmount('4', 'exact');
expect($vo)->toBeInstanceOf(PortionAmount::class)
->and($vo?->lowPart())->toBe(400)
->and($vo?->highPart())->toBe(400)
->and($vo?->approximative())->toBeFalse();
});
it('parses range portion amount like 3/4', function (): void {
$vo = IncoParser::toPortionAmount('3/4');
expect($vo)->toBeInstanceOf(PortionAmount::class)
->and($vo?->lowPart())->toBe(300)
->and($vo?->highPart())->toBe(400)
->and($vo?->approximative())->toBeTrue();
});
it('returns null for null or invalid portion', function (): void {
expect(IncoParser::toPortionAmount(null))->toBeNull()
->and(IncoParser::toPortionAmount(''))->toBeNull()
->and(IncoParser::toPortionAmount('non-numeric'))->toBeNull();
});
});
describe('toNutriscore', function (): void {
it('parses valid nutriscore grade A to E', function (): void {
expect(IncoParser::toNutriscore('A')?->grade)->toBe('A')
->and(IncoParser::toNutriscore('b')?->grade)->toBe('B')
->and(IncoParser::toNutriscore('NUTRISCORE: C')?->grade)->toBe('C');
});
it('returns null for invalid nutriscore grade', function (): void {
expect(IncoParser::toNutriscore(null))->toBeNull()
->and(IncoParser::toNutriscore('Z'))->toBeNull()
->and(IncoParser::toNutriscore(''))->toBeNull();
});
});
describe('toWeight', function (): void {
it('parses net, gross, and average weight', function (): void {
$vo = IncoParser::toWeight(300, 320, 310);
expect($vo)->toBeInstanceOf(IncoWeight::class)
->and($vo?->netWeight)->toBe(300)
->and($vo?->grossWeight)->toBe(320)
->and($vo?->theoreticalAverage)->toBe(310);
});
it('returns null when all weights are null', function (): void {
expect(IncoParser::toWeight(null, null, null))->toBeNull();
});
});
describe('toStorageCondition', function (): void {
it('parses and cleans storage condition string', function (): void {
$vo = IncoParser::toStorageCondition('<p>A conserver entre 0°C et +4°C</p>');
expect($vo)->toBeInstanceOf(StorageCondition::class)
->and($vo?->instructions)->toBe('A conserver entre 0°C et +4°C');
});
it('returns null for null or empty condition', function (): void {
expect(IncoParser::toStorageCondition(null))->toBeNull()
->and(IncoParser::toStorageCondition(' '))->toBeNull();
});
});
describe('toAdditives', function (): void {
it('parses string of delimited additives (code:label;code:label)', function (): void {
$raw = 'E250:Nitrite de sodium;E300:Acide ascorbique';
$additives = IncoParser::toAdditives($raw);
expect($additives)->toHaveCount(2)
->and($additives[0])->toBeInstanceOf(Additive::class)
->and($additives[0]->code)->toBe('E250')
->and($additives[0]->label)->toBe('Nitrite de sodium')
->and($additives[1]->code)->toBe('E300')
->and($additives[1]->label)->toBe('Acide ascorbique');
});
it('parses array of additive entries', function (): void {
$raw = [
['code' => 'E450', 'libelle' => 'Diphosphates'],
['code' => 'E330', 'libelle' => 'Acide citrique'],
];
$additives = IncoParser::toAdditives($raw);
expect($additives)->toHaveCount(2)
->and($additives[0]->code)->toBe('E450')
->and($additives[1]->code)->toBe('E330');
});
});
describe('toAllergens', function (): void {
it('parses string of delimited allergens (code:label;code:label)', function (): void {
$raw = '1:Gluten;7:Lait';
$allergens = IncoParser::toAllergens($raw);
expect($allergens)->toHaveCount(2)
->and($allergens[0])->toBeInstanceOf(Allergen::class)
->and($allergens[0]->code)->toBe(1)
->and($allergens[0]->label)->toBe('Gluten')
->and($allergens[1]->code)->toBe(7)
->and($allergens[1]->label)->toBe('Lait');
});
it('parses array of allergen entries', function (): void {
$raw = [
['code' => 3, 'libelle' => 'Œufs'],
];
$allergens = IncoParser::toAllergens($raw);
expect($allergens)->toHaveCount(1)
->and($allergens[0]->code)->toBe(3)
->and($allergens[0]->label)->toBe('Œufs');
});
});
});