integrationRepository = $this->createMock(AllegroIntegrationRepository::class); $this->tokenManager = $this->createMock(AllegroTokenManager::class); $this->apiClient = $this->createMock(AllegroApiClient::class); $this->orders = $this->createMock(OrderImportRepository::class); $this->statusMappings = $this->createMock(AllegroStatusMappingRepository::class); $this->ordersRepository = $this->createMock(OrdersRepository::class); $this->service = new AllegroOrderImportService( $this->integrationRepository, $this->tokenManager, $this->apiClient, $this->orders, $this->statusMappings, $this->ordersRepository ); } public function testImportSingleOrderHappyPath(): void { $checkoutFormId = 'abc-123'; $payload = $this->buildMinimalPayload($checkoutFormId); $this->tokenManager ->method('resolveToken') ->willReturn(['access-token-xyz', 'sandbox']); $this->apiClient ->method('getCheckoutForm') ->with('sandbox', 'access-token-xyz', $checkoutFormId) ->willReturn($payload); $this->apiClient ->method('getCheckoutFormShipments') ->willReturn([]); $this->integrationRepository ->method('getActiveIntegrationId') ->willReturn(5); $this->statusMappings ->method('findMappedOrderproStatusCode') ->willReturn('new'); $this->orders ->expects($this->once()) ->method('upsertOrderAggregate') ->willReturn(['order_id' => 42, 'created' => true]); $this->ordersRepository ->expects($this->once()) ->method('recordActivity') ->with(42, 'import', $this->stringContains('Zaimportowano')); $result = $this->service->importSingleOrder($checkoutFormId); $this->assertSame(42, $result['order_id']); $this->assertTrue($result['created']); $this->assertSame($checkoutFormId, $result['source_order_id']); } public function testImportSingleOrderRetryOn401(): void { $checkoutFormId = 'retry-456'; $payload = $this->buildMinimalPayload($checkoutFormId); $this->tokenManager ->method('resolveToken') ->willReturnOnConsecutiveCalls( ['stale-token', 'sandbox'], ['fresh-token', 'sandbox'] ); $callCount = 0; $this->apiClient ->method('getCheckoutForm') ->willReturnCallback(function () use (&$callCount, $payload): array { $callCount++; if ($callCount === 1) { throw new RuntimeException('ALLEGRO_HTTP_401'); } return $payload; }); $this->apiClient->method('getCheckoutFormShipments')->willReturn([]); $this->integrationRepository->method('getActiveIntegrationId')->willReturn(1); $this->statusMappings->method('findMappedOrderproStatusCode')->willReturn(null); $this->orders ->expects($this->once()) ->method('upsertOrderAggregate') ->willReturn(['order_id' => 99, 'created' => true]); $result = $this->service->importSingleOrder($checkoutFormId); $this->assertSame(99, $result['order_id']); $this->assertSame(2, $callCount); } public function testImportSingleOrderThrowsOnEmptyId(): void { $this->expectException(AllegroApiException::class); $this->expectExceptionMessage('Podaj ID zamowienia'); $this->service->importSingleOrder(''); } public function testImportSingleOrderPropagatesNon401RuntimeException(): void { $this->tokenManager ->method('resolveToken') ->willReturn(['token', 'sandbox']); $this->apiClient ->method('getCheckoutForm') ->willThrowException(new RuntimeException('ALLEGRO_HTTP_500')); $this->expectException(RuntimeException::class); $this->expectExceptionMessage('ALLEGRO_HTTP_500'); $this->service->importSingleOrder('order-789'); } public function testImportSingleOrderReturnsCorrectFieldsOnReImport(): void { $checkoutFormId = 'reimport-001'; $payload = $this->buildMinimalPayload($checkoutFormId); $this->tokenManager->method('resolveToken')->willReturn(['tok', 'production']); $this->apiClient->method('getCheckoutForm')->willReturn($payload); $this->apiClient->method('getCheckoutFormShipments')->willReturn([]); $this->integrationRepository->method('getActiveIntegrationId')->willReturn(1); $this->statusMappings->method('findMappedOrderproStatusCode')->willReturn(null); $this->orders ->method('upsertOrderAggregate') ->willReturn(['order_id' => 10, 'created' => false]); $this->ordersRepository ->expects($this->once()) ->method('recordActivity') ->with(10, 'import', $this->stringContains('Zaktualizowano')); $result = $this->service->importSingleOrder($checkoutFormId); $this->assertSame(10, $result['order_id']); $this->assertFalse($result['created']); $this->assertArrayHasKey('image_diagnostics', $result); } /** * @return array */ private function buildMinimalPayload(string $checkoutFormId): array { return [ 'id' => $checkoutFormId, 'status' => 'READY_FOR_PROCESSING', 'fulfillment' => ['status' => 'NEW'], 'payment' => [ 'id' => 'pay-1', 'type' => 'allegro', 'status' => 'paid', 'amount' => ['amount' => '99.00', 'currency' => 'PLN'], 'paidAmount' => ['amount' => '99.00', 'currency' => 'PLN'], ], 'summary' => [ 'totalToPay' => ['amount' => '99.00', 'currency' => 'PLN'], ], 'buyer' => [ 'login' => 'test-buyer', 'firstName' => 'Jan', 'lastName' => 'Kowalski', 'email' => 'jan@example.com', 'phoneNumber' => '500100200', ], 'delivery' => [ 'method' => ['id' => 'inpost', 'name' => 'InPost Paczkomaty'], 'address' => [ 'firstName' => 'Jan', 'lastName' => 'Kowalski', 'street' => 'ul. Testowa 1', 'city' => 'Warszawa', 'zipCode' => '00-001', 'countryCode' => 'PL', ], ], 'lineItems' => [ [ 'id' => 'item-1', 'offer' => ['id' => 'offer-1', 'name' => 'Produkt testowy'], 'quantity' => 2, 'originalPrice' => ['amount' => '49.50', 'currency' => 'PLN'], ], ], 'invoice' => [], 'marketplace' => ['id' => 'allegro-pl'], 'boughtAt' => '2026-03-14T10:00:00Z', 'updatedAt' => '2026-03-14T10:05:00Z', ]; } }