Phase 50 complete: - add conditional waybill push for allegro orders only - add retry on ALLEGRO_HTTP_401 and non-critical failure handling - add unit tests and update architecture/changelog docs
323 lines
9.8 KiB
PHP
323 lines
9.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Unit;
|
|
|
|
use App\Modules\Orders\OrdersRepository;
|
|
use App\Modules\Settings\AllegroApiClient;
|
|
use App\Modules\Settings\AllegroTokenManager;
|
|
use App\Modules\Settings\CompanySettingsRepository;
|
|
use App\Modules\Shipments\AllegroShipmentService;
|
|
use App\Modules\Shipments\ShipmentPackageRepository;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
use RuntimeException;
|
|
|
|
final class AllegroShipmentServiceTest extends TestCase
|
|
{
|
|
private AllegroTokenManager&MockObject $tokenManager;
|
|
private AllegroApiClient&MockObject $apiClient;
|
|
private ShipmentPackageRepository&MockObject $packages;
|
|
private CompanySettingsRepository&MockObject $companySettings;
|
|
private OrdersRepository&MockObject $ordersRepository;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->tokenManager = $this->createMock(AllegroTokenManager::class);
|
|
$this->apiClient = $this->createMock(AllegroApiClient::class);
|
|
$this->packages = $this->createMock(ShipmentPackageRepository::class);
|
|
$this->companySettings = $this->createMock(CompanySettingsRepository::class);
|
|
$this->ordersRepository = $this->createMock(OrdersRepository::class);
|
|
}
|
|
|
|
public function testCheckCreationStatusPushesWaybillForAllegroOrder(): void
|
|
{
|
|
$this->tokenManager
|
|
->method('resolveToken')
|
|
->willReturn(['token-1', 'sandbox']);
|
|
|
|
$this->packages
|
|
->method('findById')
|
|
->with(11)
|
|
->willReturn([
|
|
'id' => 11,
|
|
'order_id' => 200,
|
|
'command_id' => 'cmd-11',
|
|
'carrier_id' => 'INPOST',
|
|
]);
|
|
|
|
$this->packages
|
|
->expects($this->once())
|
|
->method('update')
|
|
->with(
|
|
11,
|
|
$this->callback(static function (array $payload): bool {
|
|
return ($payload['tracking_number'] ?? null) === 'TRK-001'
|
|
&& ($payload['carrier_id'] ?? null) === 'INPOST';
|
|
})
|
|
);
|
|
|
|
$this->packages
|
|
->expects($this->once())
|
|
->method('resolveCarrierName')
|
|
->with('allegro_wza', 'INPOST')
|
|
->willReturn('InPost');
|
|
|
|
$this->ordersRepository
|
|
->method('findDetails')
|
|
->with(200)
|
|
->willReturn([
|
|
'order' => [
|
|
'source' => 'allegro',
|
|
'source_order_id' => 'CHECKOUT-200',
|
|
],
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentCreationStatus')
|
|
->with('sandbox', 'token-1', 'cmd-11')
|
|
->willReturn([
|
|
'status' => 'SUCCESS',
|
|
'shipmentId' => 'SHIP-11',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentDetails')
|
|
->with('sandbox', 'token-1', 'SHIP-11')
|
|
->willReturn([
|
|
'waybill' => 'TRK-001',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->expects($this->once())
|
|
->method('addShipmentToOrder')
|
|
->with(
|
|
'sandbox',
|
|
'token-1',
|
|
'CHECKOUT-200',
|
|
'TRK-001',
|
|
'INPOST',
|
|
'InPost'
|
|
)
|
|
->willReturn([]);
|
|
|
|
$service = $this->createService();
|
|
$result = $service->checkCreationStatus(11);
|
|
|
|
$this->assertSame('created', $result['status']);
|
|
$this->assertSame('TRK-001', $result['tracking_number']);
|
|
}
|
|
|
|
public function testCheckCreationStatusSkipsPushForNonAllegroOrder(): void
|
|
{
|
|
$this->tokenManager
|
|
->method('resolveToken')
|
|
->willReturn(['token-1', 'sandbox']);
|
|
|
|
$this->packages
|
|
->method('findById')
|
|
->with(12)
|
|
->willReturn([
|
|
'id' => 12,
|
|
'order_id' => 201,
|
|
'command_id' => 'cmd-12',
|
|
'carrier_id' => 'DPD',
|
|
]);
|
|
|
|
$this->packages
|
|
->expects($this->once())
|
|
->method('update');
|
|
|
|
$this->ordersRepository
|
|
->method('findDetails')
|
|
->with(201)
|
|
->willReturn([
|
|
'order' => [
|
|
'source' => 'shoppro',
|
|
'source_order_id' => 'SP-ORDER-1',
|
|
],
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentCreationStatus')
|
|
->willReturn([
|
|
'status' => 'SUCCESS',
|
|
'shipmentId' => 'SHIP-12',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentDetails')
|
|
->willReturn([
|
|
'waybill' => 'TRK-002',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->expects($this->never())
|
|
->method('addShipmentToOrder');
|
|
|
|
$service = $this->createService();
|
|
$result = $service->checkCreationStatus(12);
|
|
|
|
$this->assertSame('created', $result['status']);
|
|
$this->assertSame('TRK-002', $result['tracking_number']);
|
|
}
|
|
|
|
public function testCheckCreationStatusDoesNotFailWhenPushReturnsError(): void
|
|
{
|
|
$this->tokenManager
|
|
->method('resolveToken')
|
|
->willReturn(['token-1', 'sandbox']);
|
|
|
|
$this->packages
|
|
->method('findById')
|
|
->with(13)
|
|
->willReturn([
|
|
'id' => 13,
|
|
'order_id' => 202,
|
|
'command_id' => 'cmd-13',
|
|
'carrier_id' => 'DHL',
|
|
]);
|
|
|
|
$this->packages
|
|
->expects($this->once())
|
|
->method('update');
|
|
|
|
$this->packages
|
|
->method('resolveCarrierName')
|
|
->willReturn('DHL');
|
|
|
|
$this->ordersRepository
|
|
->method('findDetails')
|
|
->with(202)
|
|
->willReturn([
|
|
'order' => [
|
|
'source' => 'allegro',
|
|
'source_order_id' => 'CHECKOUT-202',
|
|
],
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentCreationStatus')
|
|
->willReturn([
|
|
'status' => 'SUCCESS',
|
|
'shipmentId' => 'SHIP-13',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentDetails')
|
|
->willReturn([
|
|
'waybill' => 'TRK-003',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->expects($this->once())
|
|
->method('addShipmentToOrder')
|
|
->willThrowException(new RuntimeException('API Allegro HTTP 422'));
|
|
|
|
$service = $this->createService();
|
|
$result = $service->checkCreationStatus(13);
|
|
|
|
$this->assertSame('created', $result['status']);
|
|
$this->assertSame('TRK-003', $result['tracking_number']);
|
|
}
|
|
|
|
public function testCheckCreationStatusRetriesPushAfter401(): void
|
|
{
|
|
$this->tokenManager
|
|
->method('resolveToken')
|
|
->willReturnOnConsecutiveCalls(
|
|
['token-old', 'sandbox'],
|
|
['token-new', 'production']
|
|
);
|
|
|
|
$this->packages
|
|
->method('findById')
|
|
->with(14)
|
|
->willReturn([
|
|
'id' => 14,
|
|
'order_id' => 203,
|
|
'command_id' => 'cmd-14',
|
|
'carrier_id' => 'INPOST',
|
|
]);
|
|
|
|
$this->packages
|
|
->expects($this->once())
|
|
->method('update');
|
|
|
|
$this->packages
|
|
->method('resolveCarrierName')
|
|
->willReturn('InPost');
|
|
|
|
$this->ordersRepository
|
|
->method('findDetails')
|
|
->with(203)
|
|
->willReturn([
|
|
'order' => [
|
|
'source' => 'allegro',
|
|
'source_order_id' => 'CHECKOUT-203',
|
|
],
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentCreationStatus')
|
|
->with('sandbox', 'token-old', 'cmd-14')
|
|
->willReturn([
|
|
'status' => 'SUCCESS',
|
|
'shipmentId' => 'SHIP-14',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->method('getShipmentDetails')
|
|
->with('sandbox', 'token-old', 'SHIP-14')
|
|
->willReturn([
|
|
'waybill' => 'TRK-004',
|
|
]);
|
|
|
|
$this->apiClient
|
|
->expects($this->exactly(2))
|
|
->method('addShipmentToOrder')
|
|
->willReturnCallback(static function (
|
|
string $environment,
|
|
string $token,
|
|
string $checkoutId,
|
|
string $waybill,
|
|
string $carrierId,
|
|
string $carrierName
|
|
): array {
|
|
static $calls = 0;
|
|
$calls++;
|
|
|
|
if ($calls === 1) {
|
|
TestCase::assertSame('sandbox', $environment);
|
|
TestCase::assertSame('token-old', $token);
|
|
TestCase::assertSame('CHECKOUT-203', $checkoutId);
|
|
TestCase::assertSame('TRK-004', $waybill);
|
|
TestCase::assertSame('INPOST', $carrierId);
|
|
TestCase::assertSame('InPost', $carrierName);
|
|
throw new RuntimeException('ALLEGRO_HTTP_401');
|
|
}
|
|
|
|
TestCase::assertSame('production', $environment);
|
|
TestCase::assertSame('token-new', $token);
|
|
return [];
|
|
});
|
|
|
|
$service = $this->createService();
|
|
$result = $service->checkCreationStatus(14);
|
|
|
|
$this->assertSame('created', $result['status']);
|
|
$this->assertSame('TRK-004', $result['tracking_number']);
|
|
}
|
|
|
|
private function createService(): AllegroShipmentService
|
|
{
|
|
return new AllegroShipmentService(
|
|
$this->tokenManager,
|
|
$this->apiClient,
|
|
$this->packages,
|
|
$this->companySettings,
|
|
$this->ordersRepository
|
|
);
|
|
}
|
|
}
|