[#203] Réceptions — Parcours de pesée multi-étapes (première partie) (!3)

| Numéro du ticket | Titre du ticket |
|------------------|-----------------|
|        #203          |      Réceptions — Parcours de pesée multi-étapes         |

## Description de la PR
[#203] Réceptions — Parcours de pesée multi-étapes

## Modification du .env

## Check list

- [x] Pas de régression
- [x] TU/TI/TF rédigée
- [x] TU/TI/TF OK
- [x] CHANGELOG modifié

Reviewed-on: https://gitea.malio.fr/MALIO-DEV/Ferme/pulls/3
Reviewed-by: THOLOT DECHENE Matthieu <matthieu@yuno.malio.fr>
Co-authored-by: AUTIN Tristan <tristan@yuno.malio.fr>
Co-committed-by: AUTIN Tristan <tristan@yuno.malio.fr>
This commit is contained in:
AUTIN Tristan
2026-01-14 07:17:34 +00:00
committed by Autin
parent 9fb0fc12b8
commit 4a77449a41
44 changed files with 1976 additions and 73 deletions
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\Exception\PontBasculeException;
use App\Service\PontBasculePayloadDecoder;
use PHPUnit\Framework\TestCase;
/**
* @internal
*/
final class PontBasculePayloadDecoderTest extends TestCase
{
public function testDecodeValidPayload(): void
{
$decoder = new PontBasculePayloadDecoder();
$payload = json_encode([
'response_ascii' => "\u{0001}\u{0002}040200\u{0002}01001420.kg \u{0002}02000000.kg \u{0002}03001420.kg \u{0002}9900121",
], JSON_THROW_ON_ERROR);
$result = $decoder->decode($payload);
self::assertSame(121, $result->getDsd());
self::assertSame(1420.0, $result->getWeight());
}
public function testDecodeInvalidPayloadThrows(): void
{
$decoder = new PontBasculePayloadDecoder();
$this->expectException(PontBasculeException::class);
$this->expectExceptionMessage('Réponse invalide du pont bascule.');
$decoder->decode('not-json');
}
public function testDecodeMissingFieldThrows(): void
{
$decoder = new PontBasculePayloadDecoder();
$payload = json_encode(['ok' => true], JSON_THROW_ON_ERROR);
$this->expectException(PontBasculeException::class);
$this->expectExceptionMessage('Réponse incomplète du pont bascule: champ "response_ascii" manquant.');
$decoder->decode($payload);
}
public function testDecodeUnreadableValuesThrows(): void
{
$decoder = new PontBasculePayloadDecoder();
$payload = json_encode(['response_ascii' => 'no-data'], JSON_THROW_ON_ERROR);
$this->expectException(PontBasculeException::class);
$this->expectExceptionMessage('Impossible de lire les valeurs de pesée du pont bascule.');
$decoder->decode($payload);
}
}
+85
View File
@@ -0,0 +1,85 @@
<?php
declare(strict_types=1);
namespace App\Tests\Service;
use App\Exception\PontBasculeException;
use App\Service\PontBasculePayloadDecoder;
use App\Service\PontBasculeService;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
/**
* @internal
*/
final class PontBasculeServiceTest extends TestCase
{
public function testFetchBypassUsesDecoder(): void
{
$decoder = new PontBasculePayloadDecoder();
$httpClient = $this->createMock(HttpClientInterface::class);
$httpClient->expects(self::never())->method('request');
$service = new PontBasculeService($httpClient, $decoder, 'http://example.test', true);
$result = $service->fetch();
self::assertSame(121, $result->getDsd());
self::assertSame(1420.0, $result->getWeight());
self::assertInstanceOf(DateTimeImmutable::class, $result->getWeighedAt());
}
public function testFetchUsesHttpClientWhenNotBypass(): void
{
$payload = json_encode([
'response_ascii' => "\u{0001}\u{0002}040200\u{0002}03000123.kg \u{0002}9900042",
], JSON_THROW_ON_ERROR);
$response = $this->createMock(ResponseInterface::class);
$response->expects(self::once())->method('getContent')->with(false)->willReturn($payload);
$httpClient = $this->createMock(HttpClientInterface::class);
$httpClient
->expects(self::once())
->method('request')
->with('POST', 'http://example.test')
->willReturn($response)
;
$decoder = new PontBasculePayloadDecoder();
$service = new PontBasculeService($httpClient, $decoder, 'http://example.test', false);
$result = $service->fetch();
self::assertSame(42, $result->getDsd());
self::assertSame(123.0, $result->getWeight());
self::assertInstanceOf(DateTimeImmutable::class, $result->getWeighedAt());
}
public function testFetchThrowsOnTransportFailure(): void
{
$exception = $this->createStub(TransportExceptionInterface::class);
$httpClient = $this->createMock(HttpClientInterface::class);
$httpClient
->expects(self::once())
->method('request')
->willThrowException($exception)
;
$decoder = new PontBasculePayloadDecoder();
$service = new PontBasculeService($httpClient, $decoder, 'http://example.test', false);
$this->expectException(PontBasculeException::class);
$this->expectExceptionMessage('Erreur lors de la communication avec le pont bascule:');
$service->fetch();
}
}