test : ajout de TU sur les services et providers
This commit is contained in:
57
.idea/workspace.xml
generated
57
.idea/workspace.xml
generated
@@ -6,8 +6,8 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="7c107abe-5995-4428-8429-b146aaca8386" name="Changes" comment="feat : update du fichier README.md et CHANGELOG.md">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/CHANGELOG.md" beforeDir="false" afterPath="$PROJECT_DIR$/CHANGELOG.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/config/reference.php" beforeDir="false" afterPath="$PROJECT_DIR$/config/reference.php" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/frontend/composables/useApi.ts" beforeDir="false" afterPath="$PROJECT_DIR$/frontend/composables/useApi.ts" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -198,28 +198,28 @@
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"git-widget-placeholder": "feat/203-reception-parcours-pesee-multi-etapas",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "reference.webide.settings.project.settings.php.debug",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
<component name="PropertiesComponent">{
|
||||
"keyToString": {
|
||||
"RunOnceActivity.MCP Project settings loaded": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
"RunOnceActivity.typescript.service.memoryLimit.init": "true",
|
||||
"git-widget-placeholder": "feat/203-reception-parcours-pesee-multi-etapas",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
"node.js.selected.package.eslint": "(autodetect)",
|
||||
"node.js.selected.package.tslint": "(autodetect)",
|
||||
"nodejs_package_manager_path": "npm",
|
||||
"settings.editor.selected.configurable": "reference.webide.settings.project.settings.php.debug",
|
||||
"vue.rearranger.settings.migration": "true"
|
||||
},
|
||||
"keyToStringList": {
|
||||
"vue.recent.templates": [
|
||||
"Vue Composition API Component"
|
||||
"keyToStringList": {
|
||||
"vue.recent.templates": [
|
||||
"Vue Composition API Component"
|
||||
]
|
||||
}
|
||||
}]]></component>
|
||||
}</component>
|
||||
<component name="RecentsManager">
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="\\wsl.localhost\Ubuntu-24.04\home\tristan\workspace\ferme\frontend\pages\reception" />
|
||||
@@ -242,7 +242,7 @@
|
||||
<updated>1767956826164</updated>
|
||||
<workItem from="1767956827666" duration="7866000" />
|
||||
<workItem from="1768201706520" duration="13383000" />
|
||||
<workItem from="1768287908317" duration="22144000" />
|
||||
<workItem from="1768287908317" duration="23185000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="feat : Ajout de pinia, création de la table weight et reception mise en place du système de step pour les receptions (WIP)">
|
||||
<option name="closed" value="true" />
|
||||
@@ -276,7 +276,15 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1768316965511</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="5" />
|
||||
<task id="LOCAL-00005" summary="feat : update du fichier README.md et CHANGELOG.md">
|
||||
<option name="closed" value="true" />
|
||||
<created>1768317786187</created>
|
||||
<option name="number" value="00005" />
|
||||
<option name="presentableId" value="LOCAL-00005" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1768317786187</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="6" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -300,7 +308,8 @@
|
||||
<MESSAGE value="feat : Ajout de zod, création d'un composant de chargement loading-dots.vue et finalisation du flow d'une reception" />
|
||||
<MESSAGE value="feat : Ajout d'un composable pour la pesée qui sera réutilisable pour l'expédition, ajout de contrainte sur les entity de reception et weight pour plus de robustesse et correction de la class active des liens dans la nav" />
|
||||
<MESSAGE value="feat : update du fichier AGENTS.md" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="feat : update du fichier AGENTS.md" />
|
||||
<MESSAGE value="feat : update du fichier README.md et CHANGELOG.md" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="feat : update du fichier README.md et CHANGELOG.md" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
|
||||
61
tests/Service/PontBasculePayloadDecoderTest.php
Normal file
61
tests/Service/PontBasculePayloadDecoderTest.php
Normal file
@@ -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
tests/Service/PontBasculeServiceTest.php
Normal file
85
tests/Service/PontBasculeServiceTest.php
Normal 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();
|
||||
}
|
||||
}
|
||||
62
tests/State/ReceptionWeighingProviderTest.php
Normal file
62
tests/State/ReceptionWeighingProviderTest.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\State;
|
||||
|
||||
use ApiPlatform\Metadata\Get;
|
||||
use App\Dto\PontBasculeReading;
|
||||
use App\Service\PontBasculePayloadDecoder;
|
||||
use App\Service\PontBasculeService;
|
||||
use App\State\ReceptionWeighingProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final class ReceptionWeighingProviderTest extends TestCase
|
||||
{
|
||||
public function testProvideReturnsReading(): void
|
||||
{
|
||||
$decoder = new PontBasculePayloadDecoder();
|
||||
|
||||
$httpClient = $this->createMock(HttpClientInterface::class);
|
||||
$httpClient->expects(self::never())->method('request');
|
||||
|
||||
$service = new PontBasculeService($httpClient, $decoder, 'http://example.test', true);
|
||||
|
||||
$provider = new ReceptionWeighingProvider($service);
|
||||
|
||||
$result = $provider->provide(new Get());
|
||||
|
||||
self::assertInstanceOf(PontBasculeReading::class, $result);
|
||||
self::assertSame(121, $result->getDsd());
|
||||
self::assertSame(1420.0, $result->getWeight());
|
||||
}
|
||||
|
||||
public function testProvideThrowsHttpException(): 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);
|
||||
|
||||
$provider = new ReceptionWeighingProvider($service);
|
||||
|
||||
$this->expectException(HttpException::class);
|
||||
$this->expectExceptionMessage('Erreur lors de la communication avec le pont bascule:');
|
||||
|
||||
$provider->provide(new Get());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user