magento2-docker/dev/tests/integration/testsuite/Magento/Ups/Model/CarrierTest.php

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();
}
}