469 lines
18 KiB
PHP
Executable File
469 lines
18 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Copyright © Magento, Inc. All rights reserved.
|
|
* See COPYING.txt for license details.
|
|
*/
|
|
declare(strict_types=1);
|
|
|
|
namespace Magento\Ups\Model;
|
|
|
|
use Magento\Framework\App\Config\ReinitableConfigInterface;
|
|
use Magento\Framework\DataObject;
|
|
use Magento\Framework\HTTP\AsyncClient\HttpException;
|
|
use Magento\Framework\HTTP\AsyncClient\HttpResponseDeferredInterface;
|
|
use Magento\Framework\HTTP\AsyncClient\Response;
|
|
use Magento\Framework\HTTP\AsyncClientInterface;
|
|
use Magento\Quote\Model\Quote\Address\RateRequest;
|
|
use Magento\Quote\Model\Quote\Address\RateRequestFactory;
|
|
use Magento\Quote\Model\Quote\Address\RateResult\Error;
|
|
use Magento\Shipping\Model\Shipment\Request;
|
|
use Magento\TestFramework\Helper\Bootstrap;
|
|
use Magento\TestFramework\HTTP\AsyncClientInterfaceMock;
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
use PHPUnit\Framework\TestCase;
|
|
use Psr\Log\LoggerInterface;
|
|
|
|
/**
|
|
* Integration tests for Carrier model class
|
|
*
|
|
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
|
|
*/
|
|
class CarrierTest extends TestCase
|
|
{
|
|
/**
|
|
* @var Carrier
|
|
*/
|
|
private $carrier;
|
|
|
|
/**
|
|
* @var AsyncClientInterfaceMock
|
|
*/
|
|
private $httpClient;
|
|
|
|
/**
|
|
* @var ReinitableConfigInterface
|
|
*/
|
|
private $config;
|
|
|
|
/**
|
|
* @var LoggerInterface|MockObject
|
|
*/
|
|
private $loggerMock;
|
|
|
|
/**
|
|
* @var string[]
|
|
*/
|
|
private $logs = [];
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
protected function setUp(): void
|
|
{
|
|
$this->httpClient = Bootstrap::getObjectManager()->get(AsyncClientInterface::class);
|
|
$this->config = Bootstrap::getObjectManager()->get(ReinitableConfigInterface::class);
|
|
$this->logs = [];
|
|
$this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
|
|
$this->loggerMock->method('debug')
|
|
->willReturnCallback(
|
|
function (string $message) {
|
|
$this->logs[] = $message;
|
|
}
|
|
);
|
|
$this->carrier = Bootstrap::getObjectManager()->create(Carrier::class, ['logger' => $this->loggerMock]);
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public function testGetShipAcceptUrl()
|
|
{
|
|
$this->assertEquals('https://wwwcie.ups.com/ups.app/xml/ShipAccept', $this->carrier->getShipAcceptUrl());
|
|
}
|
|
|
|
/**
|
|
* Test ship accept url for live site
|
|
*
|
|
* @magentoConfigFixture current_store carriers/ups/is_account_live 1
|
|
*/
|
|
public function testGetShipAcceptUrlLive()
|
|
{
|
|
$this->assertEquals('https://onlinetools.ups.com/ups.app/xml/ShipAccept', $this->carrier->getShipAcceptUrl());
|
|
}
|
|
|
|
/**
|
|
* @return void
|
|
*/
|
|
public function testGetShipConfirmUrl()
|
|
{
|
|
$this->assertEquals('https://wwwcie.ups.com/ups.app/xml/ShipConfirm', $this->carrier->getShipConfirmUrl());
|
|
}
|
|
|
|
/**
|
|
* Test ship accept url for live site
|
|
*
|
|
* @magentoConfigFixture current_store carriers/ups/is_account_live 1
|
|
*/
|
|
public function testGetShipConfirmUrlLive()
|
|
{
|
|
$this->assertEquals(
|
|
'https://onlinetools.ups.com/ups.app/xml/ShipConfirm',
|
|
$this->carrier->getShipConfirmUrl()
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Collect rates for UPS Ground method.
|
|
*
|
|
* @magentoConfigFixture current_store carriers/ups/active 1
|
|
* @magentoConfigFixture current_store carriers/ups/type UPS_XML
|
|
* @magentoConfigFixture current_store carriers/ups/allowed_methods 03
|
|
* @magentoConfigFixture current_store carriers/ups/free_method 03
|
|
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
|
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the United States
|
|
* @magentoConfigFixture default_store carriers/ups/username user
|
|
* @magentoConfigFixture default_store carriers/ups/password pass
|
|
* @magentoConfigFixture default_store carriers/ups/access_license_number acn
|
|
* @magentoConfigFixture default_store carriers/ups/debug 1
|
|
* @magentoConfigFixture default_store currency/options/allow USD,EUR
|
|
* @magentoConfigFixture default_store currency/options/base USD
|
|
*/
|
|
public function testCollectFreeRates()
|
|
{
|
|
$request = Bootstrap::getObjectManager()->create(
|
|
RateRequest::class,
|
|
[
|
|
'data' => [
|
|
'dest_country' => 'US',
|
|
'dest_postal' => '90001',
|
|
'package_weight' => '1',
|
|
'package_qty' => '1',
|
|
'free_method_weight' => '5',
|
|
'product' => '11',
|
|
'action' => 'Rate',
|
|
'unit_measure' => 'KGS',
|
|
'free_shipping' => '1',
|
|
'base_currency' => new DataObject(['code' => 'USD'])
|
|
]
|
|
]
|
|
);
|
|
//phpcs:disable Magento2.Functions.DiscouragedFunction
|
|
$this->httpClient->nextResponses(
|
|
[
|
|
new Response(
|
|
200,
|
|
[],
|
|
file_get_contents(__DIR__ . "/../_files/ups_rates_response_option9.xml")
|
|
)
|
|
]
|
|
);
|
|
|
|
$rates = $this->carrier->collectRates($request)->getAllRates();
|
|
$this->assertEquals('19.19', $rates[0]->getPrice());
|
|
$this->assertEquals('03', $rates[0]->getMethod());
|
|
}
|
|
|
|
/**
|
|
* Test processing rates response.
|
|
*
|
|
* @param int $negotiable
|
|
* @param int $tax
|
|
* @param int $responseId
|
|
* @param string $method
|
|
* @param float $price
|
|
* @return void
|
|
* @dataProvider collectRatesDataProvider
|
|
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
|
* @magentoConfigFixture default_store carriers/ups/type UPS_XML
|
|
* @magentoConfigFixture default_store carriers/ups/active 1
|
|
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
|
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
|
* @magentoConfigFixture default_store carriers/ups/username user
|
|
* @magentoConfigFixture default_store carriers/ups/password pass
|
|
* @magentoConfigFixture default_store carriers/ups/access_license_number acn
|
|
* @magentoConfigFixture default_store carriers/ups/debug 1
|
|
* @magentoConfigFixture default_store currency/options/allow GBP,USD,EUR
|
|
* @magentoConfigFixture default_store currency/options/base GBP
|
|
*/
|
|
public function testCollectRates(int $negotiable, int $tax, int $responseId, string $method, float $price): void
|
|
{
|
|
$request = Bootstrap::getObjectManager()->create(
|
|
RateRequest::class,
|
|
[
|
|
'data' => [
|
|
'dest_country' => 'GB',
|
|
'dest_postal' => '01104',
|
|
'product' => '11',
|
|
'action' => 'Rate',
|
|
'unit_measure' => 'KGS',
|
|
'base_currency' => new DataObject(['code' => 'GBP'])
|
|
]
|
|
]
|
|
);
|
|
//phpcs:disable Magento2.Functions.DiscouragedFunction
|
|
$this->httpClient->nextResponses(
|
|
[
|
|
new Response(
|
|
200,
|
|
[],
|
|
file_get_contents(__DIR__ . "/../_files/ups_rates_response_option$responseId.xml")
|
|
)
|
|
]
|
|
);
|
|
//phpcs:enable Magento2.Functions.DiscouragedFunction
|
|
$this->config->setValue('carriers/ups/negotiated_active', $negotiable, 'store');
|
|
$this->config->setValue('carriers/ups/include_taxes', $tax, 'store');
|
|
$this->config->setValue('carriers/ups/allowed_methods', $method, 'store');
|
|
|
|
$rates = $this->carrier->collectRates($request)->getAllRates();
|
|
$this->assertEquals($price, $rates[0]->getPrice());
|
|
$this->assertEquals($method, $rates[0]->getMethod());
|
|
|
|
$requestFound = false;
|
|
foreach ($this->logs as $log) {
|
|
if (mb_stripos($log, 'RatingServiceSelectionRequest') &&
|
|
mb_stripos($log, 'RatingServiceSelectionResponse')
|
|
) {
|
|
$requestFound = true;
|
|
break;
|
|
}
|
|
}
|
|
$this->assertTrue($requestFound);
|
|
}
|
|
|
|
/**
|
|
* Test collect rates function without any allowed methods set.
|
|
*
|
|
* @return void
|
|
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
|
* @magentoConfigFixture default_store carriers/ups/type UPS_XML
|
|
* @magentoConfigFixture default_store carriers/ups/active 1
|
|
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
|
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
|
* @magentoConfigFixture default_store carriers/ups/username user
|
|
* @magentoConfigFixture default_store carriers/ups/password pass
|
|
* @magentoConfigFixture default_store carriers/ups/access_license_number acn
|
|
* @magentoConfigFixture default_store carriers/ups/debug 1
|
|
* @magentoConfigFixture default_store currency/options/allow GBP,USD,EUR
|
|
* @magentoConfigFixture default_store currency/options/base GBP
|
|
*/
|
|
public function testCollectRatesWithoutAnyAllowedMethods(): void
|
|
{
|
|
$request = Bootstrap::getObjectManager()->create(
|
|
RateRequest::class,
|
|
[
|
|
'data' => [
|
|
'dest_country' => 'GB',
|
|
'dest_postal' => '01104',
|
|
'product' => '11',
|
|
'action' => 'Rate',
|
|
'unit_measure' => 'KGS',
|
|
'base_currency' => new DataObject(['code' => 'GBP'])
|
|
]
|
|
]
|
|
);
|
|
$this->config->setValue('carriers/ups/allowed_methods', '', 'store');
|
|
$rates = $this->carrier->collectRates($request)->getAllRates();
|
|
$this->assertInstanceOf(Error::class, current($rates));
|
|
$this->assertEquals(current($rates)['carrier_title'], $this->carrier->getConfigData('title'));
|
|
$this->assertEquals(current($rates)['error_message'], $this->carrier->getConfigData('specificerrmsg'));
|
|
}
|
|
|
|
/**
|
|
* Get list of rates variations
|
|
*
|
|
* @return array
|
|
*/
|
|
public function collectRatesDataProvider()
|
|
{
|
|
return [
|
|
[0, 0, 1, '11', 6.45 ],
|
|
[0, 0, 2, '65', 29.59 ],
|
|
[0, 1, 3, '11', 7.74 ],
|
|
[0, 1, 4, '65', 29.59 ],
|
|
[1, 0, 5, '11', 9.35 ],
|
|
[1, 0, 6, '65', 41.61 ],
|
|
[1, 1, 7, '11', 11.22 ],
|
|
[1, 1, 8, '65', 41.61 ],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Test shipping a package.
|
|
*
|
|
*
|
|
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
|
* @magentoConfigFixture default_store carriers/ups/type UPS_XML
|
|
* @magentoConfigFixture default_store carriers/ups/active 1
|
|
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
|
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
|
* @magentoConfigFixture default_store carriers/ups/username user
|
|
* @magentoConfigFixture default_store carriers/ups/password pass
|
|
* @magentoConfigFixture default_store carriers/ups/access_license_number acn
|
|
* @magentoConfigFixture default_store currency/options/allow GBP,USD,EUR
|
|
* @magentoConfigFixture default_store currency/options/base GBP
|
|
* @magentoConfigFixture default_store carriers/ups/min_package_weight 2
|
|
* @magentoConfigFixture default_store carriers/ups/debug 1
|
|
*/
|
|
public function testRequestToShipment(): void
|
|
{
|
|
//phpcs:disable Magento2.Functions.DiscouragedFunction
|
|
$expectedShipmentRequest = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmRequest.xml');
|
|
$shipmentResponse = file_get_contents(__DIR__ . '/../_files/ShipmentConfirmResponse.xml');
|
|
$acceptResponse = file_get_contents(__DIR__ . '/../_files/ShipmentAcceptResponse.xml');
|
|
//phpcs:enable Magento2.Functions.DiscouragedFunction
|
|
$this->httpClient->nextResponses(
|
|
[
|
|
new Response(200, [], $shipmentResponse),
|
|
new Response(200, [], $acceptResponse)
|
|
]
|
|
);
|
|
$this->httpClient->clearRequests();
|
|
|
|
$request = new Request(
|
|
[
|
|
'packages' => [
|
|
'package' => [
|
|
'params' => [
|
|
'width' => '3',
|
|
'length' => '3',
|
|
'height' => '3',
|
|
'dimension_units' => 'INCH',
|
|
'weight_units' => 'POUND',
|
|
'weight' => '0.454000000001',
|
|
'customs_value' => '10.00',
|
|
'container' => 'Small Express Box',
|
|
],
|
|
'items' => [
|
|
'item1' => [
|
|
'name' => 'item_name',
|
|
],
|
|
],
|
|
],
|
|
'package2' => [
|
|
'params' => [
|
|
'width' => '4',
|
|
'length' => '4',
|
|
'height' => '4',
|
|
'dimension_units' => 'INCH',
|
|
'weight_units' => 'POUND',
|
|
'weight' => '0.55',
|
|
'customs_value' => '20.00',
|
|
'container' => 'Large Express Box',
|
|
'delivery_confirmation' => 0,
|
|
],
|
|
'items' => [
|
|
'item2' => [
|
|
'name' => 'item2_name',
|
|
],
|
|
],
|
|
],
|
|
]
|
|
]
|
|
);
|
|
$request->setRecipientAddressCountryCode('UK');
|
|
|
|
$result = $this->carrier->requestToShipment($request);
|
|
|
|
$requests = $this->httpClient->getRequests();
|
|
$this->assertNotEmpty($requests);
|
|
$shipmentRequest = $this->extractShipmentRequest($requests[0]->getBody());
|
|
$this->assertEquals(
|
|
$this->formatXml($expectedShipmentRequest),
|
|
$this->formatXml($shipmentRequest)
|
|
);
|
|
|
|
$this->assertEmpty($result->getErrors());
|
|
$this->assertNotEmpty($result->getInfo());
|
|
$this->assertEquals(
|
|
'1Z207W886698856557',
|
|
$result->getInfo()[0]['tracking_number'],
|
|
'Tracking Number must match.'
|
|
);
|
|
$this->assertEquals(
|
|
'2V467W886398839541',
|
|
$result->getInfo()[1]['tracking_number'],
|
|
'Tracking Number must match.'
|
|
);
|
|
$this->httpClient->clearRequests();
|
|
}
|
|
|
|
/**
|
|
* Test get carriers rates if has HttpException.
|
|
*
|
|
* @magentoConfigFixture default_store shipping/origin/country_id GB
|
|
* @magentoConfigFixture default_store carriers/ups/type UPS_XML
|
|
* @magentoConfigFixture default_store carriers/ups/active 1
|
|
* @magentoConfigFixture default_store carriers/ups/shipper_number 12345
|
|
* @magentoConfigFixture default_store carriers/ups/origin_shipment Shipments Originating in the European Union
|
|
* @magentoConfigFixture default_store carriers/ups/username user
|
|
* @magentoConfigFixture default_store carriers/ups/password pass
|
|
* @magentoConfigFixture default_store carriers/ups/access_license_number acn
|
|
* @magentoConfigFixture default_store carriers/ups/debug 1
|
|
* @magentoConfigFixture default_store currency/options/allow GBP,USD,EUR
|
|
* @magentoConfigFixture default_store currency/options/base GBP
|
|
*/
|
|
public function testGetRatesWithHttpException(): void
|
|
{
|
|
$deferredResponse = $this->getMockBuilder(HttpResponseDeferredInterface::class)
|
|
->onlyMethods(['get'])
|
|
->getMockForAbstractClass();
|
|
$exception = new HttpException('Exception message');
|
|
$deferredResponse->method('get')->willThrowException($exception);
|
|
$this->httpClient->setDeferredResponseMock($deferredResponse);
|
|
$request = Bootstrap::getObjectManager()->create(
|
|
RateRequest::class,
|
|
[
|
|
'data' => [
|
|
'dest_country' => 'GB',
|
|
'dest_postal' => '01105',
|
|
'product' => '11',
|
|
'action' => 'Rate',
|
|
'unit_measure' => 'KGS',
|
|
'base_currency' => new DataObject(['code' => 'GBP'])
|
|
]
|
|
]
|
|
);
|
|
$resultRate = $this->carrier->collectRates($request)->getAllRates()[0];
|
|
$error = Bootstrap::getObjectManager()->get(Error::class);
|
|
$error->setCarrier('ups');
|
|
$error->setCarrierTitle($this->carrier->getConfigData('title'));
|
|
$error->setErrorMessage($this->carrier->getConfigData('specificerrmsg'));
|
|
|
|
$this->assertEquals($error, $resultRate);
|
|
}
|
|
|
|
/**
|
|
* Extracts shipment request.
|
|
*
|
|
* @param string $requestBody
|
|
* @return string
|
|
*/
|
|
private function extractShipmentRequest(string $requestBody): string
|
|
{
|
|
$resultXml = '';
|
|
$pattern = '%(<\?xml version="1.0"\?>\n<ShipmentConfirmRequest)(.*)$%im';
|
|
if (preg_match($pattern, $requestBody, $result)) {
|
|
$resultXml = array_shift($result);
|
|
}
|
|
|
|
return $resultXml;
|
|
}
|
|
|
|
/**
|
|
* Format XML string.
|
|
*
|
|
* @param string $xmlString
|
|
* @return string
|
|
*/
|
|
private function formatXml(string $xmlString): string
|
|
{
|
|
$xmlDocument = new \DOMDocument('1.0');
|
|
$xmlDocument->preserveWhiteSpace = false;
|
|
$xmlDocument->formatOutput = true;
|
|
$xmlDocument->loadXML($xmlString);
|
|
|
|
return $xmlDocument->saveXML();
|
|
}
|
|
}
|