From 5a6d166bc8be7f0c667e82a6baa43e3b11240a31 Mon Sep 17 00:00:00 2001 From: tristan Date: Tue, 21 Apr 2026 16:51:29 +0200 Subject: [PATCH] test : tests adversariaux InventoryMapper + docblock EarTagSeriesDto --- src/Bovin/Dto/EarTagSeriesDto.php | 10 +++ .../Unit/Bovin/Mapper/InventoryMapperTest.php | 76 +++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/Bovin/Dto/EarTagSeriesDto.php b/src/Bovin/Dto/EarTagSeriesDto.php index bbadc7e..0e9e0d3 100644 --- a/src/Bovin/Dto/EarTagSeriesDto.php +++ b/src/Bovin/Dto/EarTagSeriesDto.php @@ -4,6 +4,16 @@ declare(strict_types=1); namespace Malio\EdnotifBundle\Bovin\Dto; +/** + * Wrapper minimal d'une entrée `SerieBoucles` du message de l'opération + * `IpBGetInventaire` (quand `includeEarTagStock: true`). + * + * Le noeud XSD `typeSerieBoucles` est riche (plages de numéros, fournisseur, + * statut, dates...). En Phase 1 on garde volontairement la structure brute + * via `$rawNode` : les consommateurs qui ont besoin d'un champ précis y + * accèdent par `$serie->rawNode->NomDuChamp`. Si un cas d'usage métier concret + * remonte (rebouclage, commande de boucles), on parsera dans un DTO dédié. + */ final readonly class EarTagSeriesDto { public function __construct( diff --git a/tests/Unit/Bovin/Mapper/InventoryMapperTest.php b/tests/Unit/Bovin/Mapper/InventoryMapperTest.php index 76dac82..2c4a524 100644 --- a/tests/Unit/Bovin/Mapper/InventoryMapperTest.php +++ b/tests/Unit/Bovin/Mapper/InventoryMapperTest.php @@ -54,6 +54,82 @@ final class InventoryMapperTest extends TestCase self::assertNull($inventory->startDate); } + public function testMapInventoryWithStockBouclesAbsentYieldsNullFlag(): void + { + $mapper = new InventoryMapper(new AnimalSummaryMapper(), new StandardResponseMapper()); + + $message = new stdClass(); + $message->InformationsMessage = new stdClass(); + $message->InformationsMessage->DateDebut = '2026-01-01'; + // StockBoucles deliberately omitted + + $inventory = $mapper->map($this->makeSoapResponse(), $message); + + self::assertNull($inventory->includesEarTagStock); + } + + public function testMapInventoryWithStockBouclesZeroYieldsFalseFlag(): void + { + $mapper = new InventoryMapper(new AnimalSummaryMapper(), new StandardResponseMapper()); + + $message = new stdClass(); + $message->InformationsMessage = new stdClass(); + $message->InformationsMessage->StockBoucles = '0'; + + $inventory = $mapper->map($this->makeSoapResponse(), $message); + + self::assertFalse($inventory->includesEarTagStock); + } + + public function testMapInventoryWithDateFinAbsentYieldsNullEndDate(): void + { + $mapper = new InventoryMapper(new AnimalSummaryMapper(), new StandardResponseMapper()); + + $message = new stdClass(); + $message->InformationsMessage = new stdClass(); + $message->InformationsMessage->DateDebut = '2026-01-01'; + // DateFin deliberately omitted + + $inventory = $mapper->map($this->makeSoapResponse(), $message); + + self::assertNull($inventory->endDate); + } + + public function testMapInventoryWithSerieBouclesAsListPreservesAllEntries(): void + { + $mapper = new InventoryMapper(new AnimalSummaryMapper(), new StandardResponseMapper()); + + $serie1 = new stdClass(); + $serie1->NumeroSerieDebut = 'A0001'; + $serie2 = new stdClass(); + $serie2->NumeroSerieDebut = 'B0001'; + + $message = new stdClass(); + $message->Boucles = new stdClass(); + $message->Boucles->SerieBoucles = [$serie1, $serie2]; + + $inventory = $mapper->map($this->makeSoapResponse(), $message); + + self::assertCount(2, $inventory->earTagSeries); + self::assertSame('A0001', $inventory->earTagSeries[0]->rawNode->NumeroSerieDebut); + self::assertSame('B0001', $inventory->earTagSeries[1]->rawNode->NumeroSerieDebut); + } + + public function testMapInventoryWithMissingNbBovinsDefaultsToZero(): void + { + $mapper = new InventoryMapper(new AnimalSummaryMapper(), new StandardResponseMapper()); + + $soapResponse = new stdClass(); + $soapResponse->ReponseStandard = new stdClass(); + $soapResponse->ReponseStandard->Resultat = true; + $soapResponse->ReponseSpecifique = new stdClass(); + // NbBovins deliberately omitted + + $inventory = $mapper->map($soapResponse, null); + + self::assertSame(0, $inventory->nbBovins); + } + private function makeSoapResponse(): object { $response = new stdClass();