From e5b9c0a4e2dec332743b8de5fe70da437a165e1a Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Tue, 20 Jan 2026 19:19:27 +0100 Subject: [PATCH 1/7] draft --- docs/manual/resources/order.md | 33 ++++++++++ src/Api/Order/OrderOperationResponse.php | 60 +++++++++++++++++++ src/Api/Order/OrderOperationResponseBatch.php | 22 +++++++ .../Order/OrderOperationResponseReport.php | 58 ++++++++++++++++++ src/Api/Order/OrderOperationResult.php | 28 ++++++++- .../Api/Order/OrderOperationResultTest.php | 25 +++++++- 6 files changed, 222 insertions(+), 4 deletions(-) create mode 100644 src/Api/Order/OrderOperationResponse.php create mode 100644 src/Api/Order/OrderOperationResponseBatch.php create mode 100644 src/Api/Order/OrderOperationResponseReport.php diff --git a/docs/manual/resources/order.md b/docs/manual/resources/order.md index b7c455e..a8055b1 100644 --- a/docs/manual/resources/order.md +++ b/docs/manual/resources/order.md @@ -175,6 +175,39 @@ foreach ($result->wait(60)->getTickets() as $ticket) { $ticket->getId(); $ticket->getStatus(); } + +// Fetch all Responses objects generated for the operation +foreach ($result->getResponses() as $response) { + $batch = $response->getBatch(); + $batchId = $batch->getId(); + + // Fetch all tickets generated for the operation + foreach ($batch->getTicket() as $ticketItem) { + $ticketItem->getId(); + $ticketItem->getStatus(); + } + + // Alternatively, you can wait until all ticket are processed + // do not forget to define a timeout to prevent script to be blocked + + // Ca va pas la : Normalement on boucle sur tous les tickets de tous les batchs + // => mettre une ResponseCollection au niveau de result et le wait au niveau de la collection ??? + foreach ($response->wait(60)->getBatch()->getTicket() as $ticketItem) { + $ticketItem->getId(); + $ticketItem->getStatus(); + } + + // Fetch all reports generated for the operation + $report = $response->getReport(); + + foreach ($report as $reportItem) { + $reportItem->getId(); + $reportItem->getChannelName(); + $reportItem->getReference(); + $reportItem->getState(); + $reportItem->getMessage(); + } +} ``` ### Accept diff --git a/src/Api/Order/OrderOperationResponse.php b/src/Api/Order/OrderOperationResponse.php new file mode 100644 index 0000000..17844a1 --- /dev/null +++ b/src/Api/Order/OrderOperationResponse.php @@ -0,0 +1,60 @@ +getProperty('id'); + + $this->response = [ + 'batch' => new OrderOperationResponseBatch($batchId, new TicketDomain($resource->getLink('ticket'))), + 'report' => $this->createReport($resource->getProperty('report')), + ]; + } + + /** + * @param array{int, array{ + * id: int|null, + * channelName: string|null, + * reference: string|null, + * state: string, + * message: string + * }} $reports + * @return OrderOperationResponseReport[] + */ + private function createReport(array $reports): array + { + $reportItems = []; + + foreach ($reports as $report) { + if (! is_array($report)) { + continue; + } + + $reportItems[] = new OrderOperationResponseReport($report); + } + + return $reportItems; + } + + private function getBatch(): OrderOperationResponseBatch + { + return $this->response['batch']; + } + + /** + * @return OrderOperationResponseReport[] + */ + public function getReport(): array + { + return $this->response['report']; + } +} diff --git a/src/Api/Order/OrderOperationResponseBatch.php b/src/Api/Order/OrderOperationResponseBatch.php new file mode 100644 index 0000000..2c251cf --- /dev/null +++ b/src/Api/Order/OrderOperationResponseBatch.php @@ -0,0 +1,22 @@ +id; + } + + public function getTicket(): TicketDomain + { + return $this->ticket; + } +} diff --git a/src/Api/Order/OrderOperationResponseReport.php b/src/Api/Order/OrderOperationResponseReport.php new file mode 100644 index 0000000..19a381d --- /dev/null +++ b/src/Api/Order/OrderOperationResponseReport.php @@ -0,0 +1,58 @@ +id = $report['id']; + $this->channelName = $report['channelName']; + $this->reference = $report['reference']; + $this->state = $report['state']; + $this->message = $report['message']; + } + + public function getId(): ?int + { + return $this->id; + } + + public function getChannelName(): ?string + { + return $this->channelName; + } + + public function getReference(): ?string + { + return $this->reference; + } + + public function getState(): string + { + return $this->state; + } + + public function getMessage(): string + { + return $this->message; + } +} diff --git a/src/Api/Order/OrderOperationResult.php b/src/Api/Order/OrderOperationResult.php index 3523377..6e62c94 100644 --- a/src/Api/Order/OrderOperationResult.php +++ b/src/Api/Order/OrderOperationResult.php @@ -9,9 +9,13 @@ class OrderOperationResult /** @var Task\TicketDomain[] */ private $batches; + /** @var OrderOperationResponse[] */ + private array $responses; + public function __construct(array $resources = []) { $this->setBatches($resources); + $this->setResponses($resources); } /** @@ -39,7 +43,7 @@ public function getBatchIds() /** * Wait for all tickets to be processed. * - * @param int $timeout Seconds to wait for each batch until stop + * @param int $timeout Seconds to wait for each batch until stop * @param int $sleepSecs Seconds to wait between to calls * * @return $this The current instance @@ -54,7 +58,7 @@ public function wait($timeout = null, $sleepSecs = 1) } /** - * @var \ShoppingFeed\Sdk\Hal\HalResource[] $resources + * @param \ShoppingFeed\Sdk\Hal\HalResource[] $resources */ private function setBatches(array $resources) { @@ -68,4 +72,24 @@ private function setBatches(array $resources) $this->batches[$batchId] = $domain; } } + + /** + * @param \ShoppingFeed\Sdk\Hal\HalResource[] $resources + */ + private function setResponses(array $resources): void + { + $this->batches = []; + + foreach ($resources as $resource) { + $this->responses[] = new OrderOperationResponse($resource); + } + } + + /** + * @return OrderOperationResponse[] + */ + public function getResponses(): array + { + return $this->responses; + } } diff --git a/tests/unit/Api/Order/OrderOperationResultTest.php b/tests/unit/Api/Order/OrderOperationResultTest.php index 1e46e5d..a22bbb2 100644 --- a/tests/unit/Api/Order/OrderOperationResultTest.php +++ b/tests/unit/Api/Order/OrderOperationResultTest.php @@ -33,10 +33,31 @@ public function setUp(): void ->willReturn($this->link); $resource - ->expects($this->exactly(2)) + ->expects($this->exactly(4)) ->method('getProperty') ->with('id') - ->willReturnOnConsecutiveCalls('a', 'b'); + ->willReturnOnConsecutiveCalls('a', 'a', 'b', 'b'); + + $resource + ->expects($this->exactly(2)) + ->method('getProperty') + ->with('report') + ->willReturnOnConsecutiveCalls( + [0 => [ + 'id' => 1, + 'channelName' => 'Channel A', + 'reference' => 'REF123', + 'state' => 'success', + 'message' => 'Order processed successfully.' + ]], + [0 => [ + 'id' => 2, + 'channelName' => 'Channel A', + 'reference' => 'REF456', + 'state' => 'success', + 'message' => 'Order processed successfully.' + ]] + ); $this->resources['a'] = $resource; $this->resources['b'] = $resource; From 26b0f9a84372695e9686c8aa6cd954edc02c08e3 Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Wed, 21 Jan 2026 16:16:15 +0100 Subject: [PATCH 2/7] update order documentation --- docs/manual/resources/order.md | 71 ++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/docs/manual/resources/order.md b/docs/manual/resources/order.md index a8055b1..c94fa79 100644 --- a/docs/manual/resources/order.md +++ b/docs/manual/resources/order.md @@ -176,38 +176,59 @@ foreach ($result->wait(60)->getTickets() as $ticket) { $ticket->getStatus(); } -// Fetch all Responses objects generated for the operation -foreach ($result->getResponses() as $response) { - $batch = $response->getBatch(); - $batchId = $batch->getId(); +// Fetch all Batches objects generated for the operation +foreach ($result->getBatches() as $batch) { + $response = $batch->getResponse(); + $batchId = $response->getBatchId(); // Fetch all tickets generated for the operation - foreach ($batch->getTicket() as $ticketItem) { - $ticketItem->getId(); - $ticketItem->getStatus(); - } - - // Alternatively, you can wait until all ticket are processed - // do not forget to define a timeout to prevent script to be blocked - - // Ca va pas la : Normalement on boucle sur tous les tickets de tous les batchs - // => mettre une ResponseCollection au niveau de result et le wait au niveau de la collection ??? - foreach ($response->wait(60)->getBatch()->getTicket() as $ticketItem) { - $ticketItem->getId(); - $ticketItem->getStatus(); + foreach ($response->getTickets() as $ticket) { + $ticket->getId(); + $ticket->getStatus(); } // Fetch all reports generated for the operation - $report = $response->getReport(); - - foreach ($report as $reportItem) { - $reportItem->getId(); - $reportItem->getChannelName(); - $reportItem->getReference(); - $reportItem->getState(); - $reportItem->getMessage(); + foreach ($response->getReport() as $operationReport) { + $operationReport['id]']; + $operationReport['channelName']; + $operationReport['reference']; + $operationReport['state']; + $operationReport['message']; } } + +// Both writing will work +$tickets = $result->wait(60)->getTickets(); +$batchs = $result->wait(60)->getBatchs(); + +// But if you want to check what append for each operation : +$ignoredOperations = []; +$failedOperations = []: +$succeedOperations = []; +$stillProcessingOperations = []; + +foreach ($result->wait(60)->getBatches() as $batch) { + $response = $batch->getResponse(); + + foreach ($response->getTickets() as $ticket) { + if (null !== $ticket->getFinishedAt()) { + if ('succeed' === $ticket->getStatus()) { + $succeedOperations[] = $ticket->getPayload()['id']; + } else { + $failedOperations[] = $ticket->getPayload()['id']; + } + } else { + $stillProcessingOperations = $ticket->getPayload()['id']; + } + } + + foreach ($response->getReport() as $operationReport) { + if ('ignored' === $operationReport['state']) { + $ignoredOperations[] = $operationReport['id']; + } + } +} + ``` ### Accept From 08570e62ff5168f06099e01988f4d156f731099d Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Wed, 21 Jan 2026 16:19:42 +0100 Subject: [PATCH 3/7] correct spelling --- docs/manual/resources/order.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/manual/resources/order.md b/docs/manual/resources/order.md index c94fa79..49ae98f 100644 --- a/docs/manual/resources/order.md +++ b/docs/manual/resources/order.md @@ -199,7 +199,7 @@ foreach ($result->getBatches() as $batch) { // Both writing will work $tickets = $result->wait(60)->getTickets(); -$batchs = $result->wait(60)->getBatchs(); +$batchs = $result->wait(60)->getBatches(); // But if you want to check what append for each operation : $ignoredOperations = []; From 8d488ac95318e093e060f4b55937187b70b535a7 Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Wed, 21 Jan 2026 18:55:38 +0100 Subject: [PATCH 4/7] add report --- phpstan-baseline.neon | 18 ----- src/Api/Order/OrderOperationBatch.php | 20 +++++ src/Api/Order/OrderOperationResponse.php | 74 ++++++++++++------- src/Api/Order/OrderOperationResponseBatch.php | 22 ------ .../Order/OrderOperationResponseReport.php | 58 --------------- src/Api/Order/OrderOperationResult.php | 55 +++++--------- .../Api/Order/OrderOperationResultTest.php | 19 ++--- 7 files changed, 96 insertions(+), 170 deletions(-) create mode 100644 src/Api/Order/OrderOperationBatch.php delete mode 100644 src/Api/Order/OrderOperationResponseBatch.php delete mode 100644 src/Api/Order/OrderOperationResponseReport.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6f295c5..e67f549 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -270,24 +270,6 @@ parameters: count: 1 path: src/Api/Order/OrderOperationResult.php - - - message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:setBatches\(\) has no return type specified\.$#' - identifier: missingType.return - count: 1 - path: src/Api/Order/OrderOperationResult.php - - - - message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:setBatches\(\) has parameter \$resources with no value type specified in iterable type array\.$#' - identifier: missingType.iterableValue - count: 1 - path: src/Api/Order/OrderOperationResult.php - - - - message: '#^PHPDoc tag @var above a method has no effect\.$#' - identifier: varTag.misplaced - count: 1 - path: src/Api/Order/OrderOperationResult.php - - message: '#^Cannot call method withAddedHref\(\) on ShoppingFeed\\Sdk\\Hal\\HalLink\|null\.$#' identifier: method.nonObject diff --git a/src/Api/Order/OrderOperationBatch.php b/src/Api/Order/OrderOperationBatch.php new file mode 100644 index 0000000..2caa273 --- /dev/null +++ b/src/Api/Order/OrderOperationBatch.php @@ -0,0 +1,20 @@ +response = new OrderOperationResponse($resource); + } + + public function getResponse(): OrderOperationResponse + { + return $this->response; + } +} diff --git a/src/Api/Order/OrderOperationResponse.php b/src/Api/Order/OrderOperationResponse.php index 17844a1..aeff96b 100644 --- a/src/Api/Order/OrderOperationResponse.php +++ b/src/Api/Order/OrderOperationResponse.php @@ -2,59 +2,77 @@ namespace ShoppingFeed\Sdk\Api\Order; -use ShoppingFeed\Sdk\Api\Task\TicketDomain; +use ShoppingFeed\Sdk\Api\Task; +use ShoppingFeed\Sdk\Exception\RuntimeException; +use ShoppingFeed\Sdk\Hal\HalLink; use ShoppingFeed\Sdk\Hal\HalResource; class OrderOperationResponse { - /** @var array{batch: OrderOperationResponseBatch, report: OrderOperationResponseReport[]} */ - private array $response; + private string $batchId; - public function __construct(HalResource $resource) - { - $batchId = $resource->getProperty('id'); - - $this->response = [ - 'batch' => new OrderOperationResponseBatch($batchId, new TicketDomain($resource->getLink('ticket'))), - 'report' => $this->createReport($resource->getProperty('report')), - ]; - } + private Task\TicketDomain $ticketDomain; /** - * @param array{int, array{ + * @var array{int, array{ * id: int|null, * channelName: string|null, * reference: string|null, * state: string, * message: string - * }} $reports - * @return OrderOperationResponseReport[] + * }} $report */ - private function createReport(array $reports): array - { - $reportItems = []; + private array $report; - foreach ($reports as $report) { - if (! is_array($report)) { - continue; - } + public function __construct(HalResource $resource) + { + $this->batchId = $resource->getProperty('id'); + $this->report = $resource->getProperty('report'); + $link = $resource->getLink('ticket'); - $reportItems[] = new OrderOperationResponseReport($report); + if ($link instanceof HalLink) { + $this->ticketDomain = new Task\TicketDomain($link); + } else { + throw new RuntimeException('Ticket link is missing from the OrderOperationResponse resource.'); } + } + + public function getBatchId(): string + { + return $this->batchId; + } - return $reportItems; + /** + * Get the iterator for all tickets generated by the operation + * + * @return Task\TicketResource[] + */ + public function getTickets(): iterable + { + foreach ($this->ticketDomain->getByBatch($this->batchId) as $ticket) { + yield $ticket; + } } - private function getBatch(): OrderOperationResponseBatch + /** + * Use for waiting for ticket processing in OrderOperationResponse::wait() + */ + public function getTicketDomain(): Task\TicketDomain { - return $this->response['batch']; + return $this->ticketDomain; } /** - * @return OrderOperationResponseReport[] + * @return array{int, array{ + * id: int|null, + * channelName: string|null, + * reference: string|null, + * state: string, + * message: string + * }} */ public function getReport(): array { - return $this->response['report']; + return $this->report; } } diff --git a/src/Api/Order/OrderOperationResponseBatch.php b/src/Api/Order/OrderOperationResponseBatch.php deleted file mode 100644 index 2c251cf..0000000 --- a/src/Api/Order/OrderOperationResponseBatch.php +++ /dev/null @@ -1,22 +0,0 @@ -id; - } - - public function getTicket(): TicketDomain - { - return $this->ticket; - } -} diff --git a/src/Api/Order/OrderOperationResponseReport.php b/src/Api/Order/OrderOperationResponseReport.php deleted file mode 100644 index 19a381d..0000000 --- a/src/Api/Order/OrderOperationResponseReport.php +++ /dev/null @@ -1,58 +0,0 @@ -id = $report['id']; - $this->channelName = $report['channelName']; - $this->reference = $report['reference']; - $this->state = $report['state']; - $this->message = $report['message']; - } - - public function getId(): ?int - { - return $this->id; - } - - public function getChannelName(): ?string - { - return $this->channelName; - } - - public function getReference(): ?string - { - return $this->reference; - } - - public function getState(): string - { - return $this->state; - } - - public function getMessage(): string - { - return $this->message; - } -} diff --git a/src/Api/Order/OrderOperationResult.php b/src/Api/Order/OrderOperationResult.php index 6e62c94..012ad04 100644 --- a/src/Api/Order/OrderOperationResult.php +++ b/src/Api/Order/OrderOperationResult.php @@ -2,31 +2,25 @@ namespace ShoppingFeed\Sdk\Api\Order; -use ShoppingFeed\Sdk\Api\Task; - class OrderOperationResult { - /** @var Task\TicketDomain[] */ - private $batches; - - /** @var OrderOperationResponse[] */ - private array $responses; + /** @var OrderOperationBatch[] $batches */ + private array $batches; public function __construct(array $resources = []) { $this->setBatches($resources); - $this->setResponses($resources); } /** * Get the iterator for all tickets generated by the operation * - * @return Task\TicketResource[]|\Traversable + * @return \ShoppingFeed\Sdk\Api\Task\TicketResource[]|\Traversable */ public function getTickets() { - foreach ($this->batches as $id => $domain) { - foreach ($domain->getByBatch($id) as $ticket) { + foreach ($this->batches as $batch) { + foreach ($batch->getResponse()->getTickets() as $ticket) { yield $ticket; } } @@ -37,7 +31,13 @@ public function getTickets() */ public function getBatchIds() { - return array_keys($this->batches); + $batchIds = []; + + foreach ($this->batches as $batch) { + $batchIds[] = $batch->getResponse()->getBatchId(); + } + + return $batchIds; } /** @@ -50,8 +50,9 @@ public function getBatchIds() */ public function wait($timeout = null, $sleepSecs = 1) { - foreach ($this->batches as $id => $domain) { - $domain->getByBatch($id)->wait($timeout, $sleepSecs); + foreach ($this->batches as $batch) { + $response = $batch->getResponse(); + $response->getTicketDomain()->getByBatch($response->getBatchId())->wait($timeout, $sleepSecs); } return $this; @@ -60,36 +61,20 @@ public function wait($timeout = null, $sleepSecs = 1) /** * @param \ShoppingFeed\Sdk\Hal\HalResource[] $resources */ - private function setBatches(array $resources) - { - $this->batches = []; - - foreach ($resources as $resource) { - // Stored element is the domain in order to avoid early api calls - $batchId = $resource->getProperty('id'); - $domain = new Task\TicketDomain($resource->getLink('ticket')); - - $this->batches[$batchId] = $domain; - } - } - - /** - * @param \ShoppingFeed\Sdk\Hal\HalResource[] $resources - */ - private function setResponses(array $resources): void + private function setBatches(array $resources): void { $this->batches = []; foreach ($resources as $resource) { - $this->responses[] = new OrderOperationResponse($resource); + $this->batches[] = new OrderOperationBatch($resource); } } /** - * @return OrderOperationResponse[] + * @return OrderOperationBatch[] */ - public function getResponses(): array + public function getBatches(): array { - return $this->responses; + return $this->batches; } } diff --git a/tests/unit/Api/Order/OrderOperationResultTest.php b/tests/unit/Api/Order/OrderOperationResultTest.php index a22bbb2..989ac58 100644 --- a/tests/unit/Api/Order/OrderOperationResultTest.php +++ b/tests/unit/Api/Order/OrderOperationResultTest.php @@ -35,14 +35,14 @@ public function setUp(): void $resource ->expects($this->exactly(4)) ->method('getProperty') - ->with('id') - ->willReturnOnConsecutiveCalls('a', 'a', 'b', 'b'); - - $resource - ->expects($this->exactly(2)) - ->method('getProperty') - ->with('report') + ->withConsecutive( + ['id', null], + ['report', null], + ['id', null], + ['report', null] + ) ->willReturnOnConsecutiveCalls( + 'a', [0 => [ 'id' => 1, 'channelName' => 'Channel A', @@ -50,13 +50,14 @@ public function setUp(): void 'state' => 'success', 'message' => 'Order processed successfully.' ]], - [0 => [ + 'b', + [1 => [ 'id' => 2, 'channelName' => 'Channel A', 'reference' => 'REF456', 'state' => 'success', 'message' => 'Order processed successfully.' - ]] + ]], ); $this->resources['a'] = $resource; From b272c8ca612d43c446983a7a9c722a6855f62d98 Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Tue, 27 Jan 2026 08:14:31 +0100 Subject: [PATCH 5/7] add wait method add tu --- phpstan-baseline.neon | 2 +- src/Api/Order/OrderOperationResponse.php | 13 ++- src/Api/Order/OrderOperationResult.php | 7 +- .../Api/Order/OrderOperationResponseTest.php | 59 ++++++++++ .../Api/Order/OrderOperationResultTest.php | 108 +++++------------- .../unit/Api/Order/OrderOperationTestCase.php | 84 ++++++++++++++ 6 files changed, 184 insertions(+), 89 deletions(-) create mode 100644 tests/unit/Api/Order/OrderOperationResponseTest.php create mode 100644 tests/unit/Api/Order/OrderOperationTestCase.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e67f549..98d21c6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -262,7 +262,7 @@ parameters: message: '#^Call to an undefined method iterable\&Traversable\:\:wait\(\)\.$#' identifier: method.notFound count: 1 - path: src/Api/Order/OrderOperationResult.php + path: src/Api/Order/OrderOperationResponse.php - message: '#^Method ShoppingFeed\\Sdk\\Api\\Order\\OrderOperationResult\:\:__construct\(\) has parameter \$resources with no value type specified in iterable type array\.$#' diff --git a/src/Api/Order/OrderOperationResponse.php b/src/Api/Order/OrderOperationResponse.php index aeff96b..727f70f 100644 --- a/src/Api/Order/OrderOperationResponse.php +++ b/src/Api/Order/OrderOperationResponse.php @@ -55,11 +55,18 @@ public function getTickets(): iterable } /** - * Use for waiting for ticket processing in OrderOperationResponse::wait() + * Wait for all tickets to be processed. + * + * $timeout Seconds to wait for each batch until stop + * $sleepSecs Seconds to wait between to calls + * + * @return $this The current instance */ - public function getTicketDomain(): Task\TicketDomain + public function wait(?int $timeout = null, int $sleepSecs = 1): self { - return $this->ticketDomain; + $this->ticketDomain->getByBatch($this->batchId)->wait($timeout, $sleepSecs); + + return $this; } /** diff --git a/src/Api/Order/OrderOperationResult.php b/src/Api/Order/OrderOperationResult.php index 012ad04..1c5181e 100644 --- a/src/Api/Order/OrderOperationResult.php +++ b/src/Api/Order/OrderOperationResult.php @@ -43,16 +43,15 @@ public function getBatchIds() /** * Wait for all tickets to be processed. * - * @param int $timeout Seconds to wait for each batch until stop + * @param ?int $timeout Seconds to wait for each batch until stop * @param int $sleepSecs Seconds to wait between to calls * * @return $this The current instance */ - public function wait($timeout = null, $sleepSecs = 1) + public function wait(?int $timeout = null, int $sleepSecs = 1) { foreach ($this->batches as $batch) { - $response = $batch->getResponse(); - $response->getTicketDomain()->getByBatch($response->getBatchId())->wait($timeout, $sleepSecs); + $batch->getResponse()->wait($timeout, $sleepSecs); } return $this; diff --git a/tests/unit/Api/Order/OrderOperationResponseTest.php b/tests/unit/Api/Order/OrderOperationResponseTest.php new file mode 100644 index 0000000..5dbccbe --- /dev/null +++ b/tests/unit/Api/Order/OrderOperationResponseTest.php @@ -0,0 +1,59 @@ +resource = $this->createResourceMock('a', 1, 'REF123', $this->link); + $this->response = new OrderOperationResponse($this->resource); + } + + protected function getInstance(): OrderOperationResponse|OrderOperationResult + { + return $this->response; + } + + protected function getWaitCallCount(): int + { + return 1; + } + + public function testBatchId(): void + { + $this->assertSame('a', $this->response->getBatchId()); + } + + public function testGetReport(): void + { + $expectedReport = [ + [ + 'id' => 1, + 'channelName' => 'Channel A', + 'reference' => 'REF123', + 'state' => 'success', + 'message' => 'Order processed successfully.' + ] + ]; + + $this->assertSame($expectedReport, $this->response->getReport()); + } + + public function testExceptionOnMissingTicketLink(): void + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('Ticket link is missing from the OrderOperationResponse resource.'); + + $resource = $this->createResourceMock('a', 1, 'REF123'); + new OrderOperationResponse($resource); + } +} diff --git a/tests/unit/Api/Order/OrderOperationResultTest.php b/tests/unit/Api/Order/OrderOperationResultTest.php index 989ac58..23b6c98 100644 --- a/tests/unit/Api/Order/OrderOperationResultTest.php +++ b/tests/unit/Api/Order/OrderOperationResultTest.php @@ -1,106 +1,52 @@ link = $this->createMock(HalLink::class); - - $resource = $this->createMock(HalResource::class); - $resource - ->expects($this->any()) - ->method('getLink') - ->with('ticket') - ->willReturn($this->link); + parent::setUp(); - $resource - ->expects($this->exactly(4)) - ->method('getProperty') - ->withConsecutive( - ['id', null], - ['report', null], - ['id', null], - ['report', null] - ) - ->willReturnOnConsecutiveCalls( - 'a', - [0 => [ - 'id' => 1, - 'channelName' => 'Channel A', - 'reference' => 'REF123', - 'state' => 'success', - 'message' => 'Order processed successfully.' - ]], - 'b', - [1 => [ - 'id' => 2, - 'channelName' => 'Channel A', - 'reference' => 'REF456', - 'state' => 'success', - 'message' => 'Order processed successfully.' - ]], - ); - - $this->resources['a'] = $resource; - $this->resources['b'] = $resource; + $this->resources = [ + 'a' => $this->createResourceMock('a', 1, 'REF123', $this->link), + 'b' => $this->createResourceMock('b', 2, 'REF456', $this->link), + ]; $this->instance = new OrderOperationResult($this->resources); } - public function testBatchIds() + protected function getInstance(): OrderOperationResponse|OrderOperationResult { - $this->assertSame(['a', 'b'], $this->instance->getBatchIds()); + return $this->instance; } - public function testWait() + protected function getWaitCallCount(): int { - $this->link - ->expects($this->exactly(2)) - ->method('get') - ->willReturn($this->createMock(HalResource::class)); + return 2; + } - $this->assertSame( - $this->instance, - $this->instance->wait(1, 0.1) - ); + public function testBatchIds(): void + { + $this->assertSame(['a', 'b'], $this->instance->getBatchIds()); } - public function testGetTickets() + public function testGetBatches(): void { - $resource = $this->createMock(HalResource::class); - $this->link - ->expects($this->exactly(2)) - ->method('get') - ->willReturn($resource); + $batches = $this->instance->getBatches(); - $resource - ->expects($this->any()) - ->method('getAllResources') - ->willReturn([$resource]); + $this->assertCount(2, $batches); - $this->assertContainsOnly( - TicketResource::class, - $this->instance->getTickets() - ); + foreach ($batches as $batch) { + $this->assertInstanceOf(OrderOperationBatch::class, $batch); + } } } - diff --git a/tests/unit/Api/Order/OrderOperationTestCase.php b/tests/unit/Api/Order/OrderOperationTestCase.php new file mode 100644 index 0000000..a027448 --- /dev/null +++ b/tests/unit/Api/Order/OrderOperationTestCase.php @@ -0,0 +1,84 @@ +link = $this->createMock(HalLink::class); + } + + protected function createResourceMock($batchId, $orderId, $reference, $link = null) + { + $resource = $this->createMock(HalResource::class); + + $resource + ->method('getLink') + ->with('ticket') + ->willReturn($link); + + $callCount = 0; + $resource + ->method('getProperty') + ->willReturnCallback(function () use (&$callCount, $batchId, $orderId, $reference) { + $callCount++; + return match ($callCount) { + 1, 3 => $batchId, + 2, 4 => [ + [ + 'id' => $orderId, + 'channelName' => 'Channel A', + 'reference' => $reference, + 'state' => 'success', + 'message' => 'Order processed successfully.' + ] + ], + default => null, + }; + }); + + return $resource; + } + + abstract protected function getInstance(): OrderOperationResponse|OrderOperationResult; + + abstract protected function getWaitCallCount(): int; + + public function testWait(): void + { + $this->link + ->expects($this->exactly($this->getWaitCallCount())) + ->method('get') + ->willReturn($this->createMock(HalResource::class)); + + $this->assertSame($this->getInstance(), $this->getInstance()->wait(1)); + } + + public function testGetTickets(): void + { + $resource = $this->createMock(HalResource::class); + $this->link + ->expects($this->exactly($this->getWaitCallCount())) + ->method('get') + ->willReturn($resource); + + $resource + ->method('getAllResources') + ->willReturn([$resource]); + + $this->assertContainsOnly( + TicketResource::class, + $this->getInstance()->getTickets() + ); + } +} From 592817450bafe6dce3d01c81c9a136a39e793a83 Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Wed, 28 Jan 2026 09:47:38 +0100 Subject: [PATCH 6/7] minor correction --- src/Api/Order/OrderOperationBatch.php | 3 +++ src/Api/Order/OrderOperationResponse.php | 6 +++--- src/Api/Order/OrderOperationResult.php | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Api/Order/OrderOperationBatch.php b/src/Api/Order/OrderOperationBatch.php index 2caa273..bdff0b3 100644 --- a/src/Api/Order/OrderOperationBatch.php +++ b/src/Api/Order/OrderOperationBatch.php @@ -4,6 +4,9 @@ use ShoppingFeed\Sdk\Hal\HalResource; +/** + * This class was designed this way to make possible to add the request associate to the batch in future version. + */ class OrderOperationBatch { private OrderOperationResponse $response; diff --git a/src/Api/Order/OrderOperationResponse.php b/src/Api/Order/OrderOperationResponse.php index 727f70f..70626d6 100644 --- a/src/Api/Order/OrderOperationResponse.php +++ b/src/Api/Order/OrderOperationResponse.php @@ -30,11 +30,11 @@ public function __construct(HalResource $resource) $this->report = $resource->getProperty('report'); $link = $resource->getLink('ticket'); - if ($link instanceof HalLink) { - $this->ticketDomain = new Task\TicketDomain($link); - } else { + if (! $link instanceof HalLink) { throw new RuntimeException('Ticket link is missing from the OrderOperationResponse resource.'); } + + $this->ticketDomain = new Task\TicketDomain($link); } public function getBatchId(): string diff --git a/src/Api/Order/OrderOperationResult.php b/src/Api/Order/OrderOperationResult.php index 1c5181e..4c1d549 100644 --- a/src/Api/Order/OrderOperationResult.php +++ b/src/Api/Order/OrderOperationResult.php @@ -48,7 +48,7 @@ public function getBatchIds() * * @return $this The current instance */ - public function wait(?int $timeout = null, int $sleepSecs = 1) + public function wait($timeout = null, $sleepSecs = 1) { foreach ($this->batches as $batch) { $batch->getResponse()->wait($timeout, $sleepSecs); From 5f44aa2a39e2b8fba487c40e4b2e8b1905849c8a Mon Sep 17 00:00:00 2001 From: olivierh94 Date: Thu, 29 Jan 2026 09:49:07 +0100 Subject: [PATCH 7/7] feedback --- src/Api/Order/OrderOperationResponse.php | 4 +--- src/Api/Order/OrderOperationResult.php | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/Api/Order/OrderOperationResponse.php b/src/Api/Order/OrderOperationResponse.php index 70626d6..633e271 100644 --- a/src/Api/Order/OrderOperationResponse.php +++ b/src/Api/Order/OrderOperationResponse.php @@ -49,9 +49,7 @@ public function getBatchId(): string */ public function getTickets(): iterable { - foreach ($this->ticketDomain->getByBatch($this->batchId) as $ticket) { - yield $ticket; - } + yield from $this->ticketDomain->getByBatch($this->batchId); } /** diff --git a/src/Api/Order/OrderOperationResult.php b/src/Api/Order/OrderOperationResult.php index 4c1d549..75e9cad 100644 --- a/src/Api/Order/OrderOperationResult.php +++ b/src/Api/Order/OrderOperationResult.php @@ -20,9 +20,7 @@ public function __construct(array $resources = []) public function getTickets() { foreach ($this->batches as $batch) { - foreach ($batch->getResponse()->getTickets() as $ticket) { - yield $ticket; - } + yield from $batch->getResponse()->getTickets(); } } @@ -51,7 +49,7 @@ public function getBatchIds() public function wait($timeout = null, $sleepSecs = 1) { foreach ($this->batches as $batch) { - $batch->getResponse()->wait($timeout, $sleepSecs); + $batch->getResponse()->wait((int) $timeout, (int) $sleepSecs); } return $this;