123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\Fedex\Test\Unit\Model;
- use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
- use Magento\CatalogInventory\Model\StockRegistry;
- use Magento\Directory\Helper\Data;
- use Magento\Directory\Model\Country;
- use Magento\Directory\Model\CountryFactory;
- use Magento\Directory\Model\CurrencyFactory;
- use Magento\Directory\Model\RegionFactory;
- use Magento\Fedex\Model\Carrier;
- use Magento\Framework\App\Config\ScopeConfigInterface;
- use Magento\Framework\Module\Dir\Reader;
- use Magento\Framework\Pricing\PriceCurrencyInterface;
- use Magento\Framework\Serialize\Serializer\Json;
- use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
- use Magento\Framework\Xml\Security;
- use Magento\Quote\Model\Quote\Address\RateRequest;
- use Magento\Quote\Model\Quote\Address\RateResult\Error as RateResultError;
- use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory as RateErrorFactory;
- use Magento\Quote\Model\Quote\Address\RateResult\Method;
- use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
- use Magento\Shipping\Model\Rate\Result as RateResult;
- use Magento\Shipping\Model\Rate\ResultFactory as RateResultFactory;
- use Magento\Shipping\Model\Simplexml\ElementFactory;
- use Magento\Shipping\Model\Tracking\Result;
- use Magento\Shipping\Model\Tracking\Result\Error;
- use Magento\Shipping\Model\Tracking\Result\ErrorFactory;
- use Magento\Shipping\Model\Tracking\Result\Status;
- use Magento\Shipping\Model\Tracking\Result\StatusFactory;
- use Magento\Shipping\Model\Tracking\ResultFactory;
- use Magento\Store\Model\Store;
- use Magento\Store\Model\StoreManagerInterface;
- use PHPUnit_Framework_MockObject_MockObject as MockObject;
- use Psr\Log\LoggerInterface;
- /**
- * CarrierTest contains units test for Fedex carrier methods
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
- class CarrierTest extends \PHPUnit\Framework\TestCase
- {
- /**
- * @var ObjectManager
- */
- private $helper;
- /**
- * @var Carrier|MockObject
- */
- private $carrier;
- /**
- * @var ScopeConfigInterface|MockObject
- */
- private $scope;
- /**
- * @var Error|MockObject
- */
- private $error;
- /**
- * @var ErrorFactory|MockObject
- */
- private $errorFactory;
- /**
- * @var ErrorFactory|MockObject
- */
- private $trackErrorFactory;
- /**
- * @var StatusFactory|MockObject
- */
- private $statusFactory;
- /**
- * @var Result
- */
- private $result;
- /**
- * @var \SoapClient|MockObject
- */
- private $soapClient;
- /**
- * @var Json|MockObject
- */
- private $serializer;
- /**
- * @var LoggerInterface|MockObject
- */
- private $logger;
- protected function setUp()
- {
- $this->helper = new ObjectManager($this);
- $this->scope = $this->getMockBuilder(ScopeConfigInterface::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->scope->expects($this->any())
- ->method('getValue')
- ->willReturnCallback([$this, 'scopeConfigGetValue']);
- $countryFactory = $this->getCountryFactory();
- $rateFactory = $this->getRateFactory();
- $storeManager = $this->getStoreManager();
- $resultFactory = $this->getResultFactory();
- $this->initRateErrorFactory();
- $rateMethodFactory = $this->getRateMethodFactory();
- $this->trackErrorFactory = $this->getMockBuilder(ErrorFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->statusFactory = $this->getMockBuilder(StatusFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $elementFactory = $this->getMockBuilder(ElementFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $collectionFactory = $this->getMockBuilder(CollectionFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $regionFactory = $this->getMockBuilder(RegionFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $currencyFactory = $this->getMockBuilder(CurrencyFactory::class)
- ->disableOriginalConstructor()
- ->getMock();
- $data = $this->getMockBuilder(Data::class)
- ->disableOriginalConstructor()
- ->getMock();
- $stockRegistry = $this->getMockBuilder(StockRegistry::class)
- ->disableOriginalConstructor()
- ->getMock();
- $reader = $this->getMockBuilder(Reader::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->serializer = $this->getMockBuilder(Json::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->logger = $this->getMockForAbstractClass(LoggerInterface::class);
- $this->carrier = $this->getMockBuilder(Carrier::class)
- ->setMethods(['_createSoapClient'])
- ->setConstructorArgs(
- [
- 'scopeConfig' => $this->scope,
- 'rateErrorFactory' => $this->errorFactory,
- 'logger' => $this->logger,
- 'xmlSecurity' => new Security(),
- 'xmlElFactory' => $elementFactory,
- 'rateFactory' => $rateFactory,
- 'rateMethodFactory' => $rateMethodFactory,
- 'trackFactory' => $resultFactory,
- 'trackErrorFactory' => $this->trackErrorFactory,
- 'trackStatusFactory' => $this->statusFactory,
- 'regionFactory' => $regionFactory,
- 'countryFactory' => $countryFactory,
- 'currencyFactory' => $currencyFactory,
- 'directoryData' => $data,
- 'stockRegistry' => $stockRegistry,
- 'storeManager' => $storeManager,
- 'configReader' => $reader,
- 'productCollectionFactory' => $collectionFactory,
- 'data' => [],
- 'serializer' => $this->serializer,
- ]
- )->getMock();
- $this->soapClient = $this->getMockBuilder(\SoapClient::class)
- ->disableOriginalConstructor()
- ->setMethods(['getRates', 'track'])
- ->getMock();
- $this->carrier->method('_createSoapClient')
- ->willReturn($this->soapClient);
- }
- public function testSetRequestWithoutCity()
- {
- $request = $this->getMockBuilder(RateRequest::class)
- ->disableOriginalConstructor()
- ->setMethods(['getDestCity'])
- ->getMock();
- $request->expects($this->once())
- ->method('getDestCity')
- ->willReturn(null);
- $this->carrier->setRequest($request);
- }
- public function testSetRequestWithCity()
- {
- $request = $this->getMockBuilder(RateRequest::class)
- ->disableOriginalConstructor()
- ->setMethods(['getDestCity'])
- ->getMock();
- $request->expects($this->exactly(2))
- ->method('getDestCity')
- ->willReturn('Small Town');
- $this->carrier->setRequest($request);
- }
- /**
- * Callback function, emulates getValue function.
- *
- * @param string $path
- * @return string|null
- */
- public function scopeConfigGetValue(string $path)
- {
- $pathMap = [
- 'carriers/fedex/showmethod' => 1,
- 'carriers/fedex/allowed_methods' => 'ServiceType',
- 'carriers/fedex/debug' => 1,
- ];
- return isset($pathMap[$path]) ? $pathMap[$path] : null;
- }
- /**
- * @param float $amount
- * @param string $rateType
- * @param float $expected
- * @param int $callNum
- * @dataProvider collectRatesDataProvider
- */
- public function testCollectRatesRateAmountOriginBased($amount, $rateType, $expected, $callNum = 1)
- {
- $this->scope->expects($this->any())
- ->method('isSetFlag')
- ->willReturn(true);
- // @codingStandardsIgnoreStart
- $netAmount = new \stdClass();
- $netAmount->Amount = $amount;
- $totalNetCharge = new \stdClass();
- $totalNetCharge->TotalNetCharge = $netAmount;
- $totalNetCharge->RateType = $rateType;
- $ratedShipmentDetail = new \stdClass();
- $ratedShipmentDetail->ShipmentRateDetail = $totalNetCharge;
- $rate = new \stdClass();
- $rate->ServiceType = 'ServiceType';
- $rate->RatedShipmentDetails = [$ratedShipmentDetail];
- $response = new \stdClass();
- $response->HighestSeverity = 'SUCCESS';
- $response->RateReplyDetails = $rate;
- // @codingStandardsIgnoreEnd
- $this->serializer->method('serialize')
- ->willReturn('CollectRateString' . $amount);
- $request = $this->getMockBuilder(RateRequest::class)
- ->disableOriginalConstructor()
- ->getMock();
- $this->soapClient->expects($this->exactly($callNum))
- ->method('getRates')
- ->willReturn($response);
- $allRates1 = $this->carrier->collectRates($request)->getAllRates();
- foreach ($allRates1 as $rate) {
- $this->assertEquals($expected, $rate->getData('cost'));
- }
- }
- /**
- * Get list of rates variations
- * @return array
- */
- public function collectRatesDataProvider()
- {
- return [
- [10.0, 'RATED_ACCOUNT_PACKAGE', 10],
- [10.0, 'RATED_ACCOUNT_PACKAGE', 10, 0],
- [11.50, 'PAYOR_ACCOUNT_PACKAGE', 11.5],
- [11.50, 'PAYOR_ACCOUNT_PACKAGE', 11.5, 0],
- [100.01, 'RATED_ACCOUNT_SHIPMENT', 100.01],
- [100.01, 'RATED_ACCOUNT_SHIPMENT', 100.01, 0],
- [32.2, 'PAYOR_ACCOUNT_SHIPMENT', 32.2],
- [32.2, 'PAYOR_ACCOUNT_SHIPMENT', 32.2, 0],
- [15.0, 'RATED_LIST_PACKAGE', 15],
- [15.0, 'RATED_LIST_PACKAGE', 15, 0],
- [123.25, 'PAYOR_LIST_PACKAGE', 123.25],
- [123.25, 'PAYOR_LIST_PACKAGE', 123.25, 0],
- [12.12, 'RATED_LIST_SHIPMENT', 12.12],
- [12.12, 'RATED_LIST_SHIPMENT', 12.12, 0],
- [38.9, 'PAYOR_LIST_SHIPMENT', 38.9],
- [38.9, 'PAYOR_LIST_SHIPMENT', 38.9, 0],
- ];
- }
- public function testCollectRatesErrorMessage()
- {
- $this->scope->expects($this->once())
- ->method('isSetFlag')
- ->willReturn(false);
- $this->error->expects($this->once())
- ->method('setCarrier')
- ->with('fedex');
- $this->error->expects($this->once())
- ->method('setCarrierTitle');
- $this->error->expects($this->once())
- ->method('setErrorMessage');
- $request = new RateRequest();
- $request->setPackageWeight(1);
- $this->assertSame($this->error, $this->carrier->collectRates($request));
- }
- /**
- * @param string $data
- * @param array $maskFields
- * @param string $expected
- * @dataProvider logDataProvider
- */
- public function testFilterDebugData($data, array $maskFields, $expected)
- {
- $refClass = new \ReflectionClass(Carrier::class);
- $property = $refClass->getProperty('_debugReplacePrivateDataKeys');
- $property->setAccessible(true);
- $property->setValue($this->carrier, $maskFields);
- $refMethod = $refClass->getMethod('filterDebugData');
- $refMethod->setAccessible(true);
- $result = $refMethod->invoke($this->carrier, $data);
- $this->assertEquals($expected, $result);
- }
- /**
- * Get list of variations
- */
- public function logDataProvider()
- {
- return [
- [
- [
- 'WebAuthenticationDetail' => [
- 'UserCredential' => [
- 'Key' => 'testKey',
- 'Password' => 'testPassword',
- ],
- ],
- 'ClientDetail' => [
- 'AccountNumber' => 4121213,
- 'MeterNumber' => 'testMeterNumber',
- ],
- ],
- ['Key', 'Password', 'MeterNumber'],
- [
- 'WebAuthenticationDetail' => [
- 'UserCredential' => [
- 'Key' => '****',
- 'Password' => '****',
- ],
- ],
- 'ClientDetail' => [
- 'AccountNumber' => 4121213,
- 'MeterNumber' => '****',
- ],
- ],
- ],
- ];
- }
- public function testGetTrackingErrorResponse()
- {
- $tracking = '123456789012';
- $errorMessage = 'Tracking information is unavailable.';
- // @codingStandardsIgnoreStart
- $response = new \stdClass();
- $response->HighestSeverity = 'ERROR';
- $response->Notifications = new \stdClass();
- $response->Notifications->Message = $errorMessage;
- // @codingStandardsIgnoreEnd
- $error = $this->helper->getObject(Error::class);
- $this->trackErrorFactory->expects($this->once())
- ->method('create')
- ->willReturn($error);
- $this->carrier->getTracking($tracking);
- $tracks = $this->carrier->getResult()->getAllTrackings();
- $this->assertEquals(1, count($tracks));
- /** @var Error $current */
- $current = $tracks[0];
- $this->assertInstanceOf(Error::class, $current);
- $this->assertEquals(__($errorMessage), $current->getErrorMessage());
- }
- /**
- * @param string $tracking
- * @param string $shipTimeStamp
- * @param string $expectedDate
- * @param string $expectedTime
- * @dataProvider shipDateDataProvider
- */
- public function testGetTracking($tracking, $shipTimeStamp, $expectedDate, $expectedTime, $callNum = 1)
- {
- // @codingStandardsIgnoreStart
- $response = new \stdClass();
- $response->HighestSeverity = 'SUCCESS';
- $response->CompletedTrackDetails = new \stdClass();
- $trackDetails = new \stdClass();
- $trackDetails->ShipTimestamp = $shipTimeStamp;
- $trackDetails->DeliverySignatureName = 'signature';
- $trackDetails->StatusDetail = new \stdClass();
- $trackDetails->StatusDetail->Description = 'SUCCESS';
- $trackDetails->Service = new \stdClass();
- $trackDetails->Service->Description = 'ground';
- $trackDetails->EstimatedDeliveryTimestamp = $shipTimeStamp;
- $trackDetails->EstimatedDeliveryAddress = new \stdClass();
- $trackDetails->EstimatedDeliveryAddress->City = 'Culver City';
- $trackDetails->EstimatedDeliveryAddress->StateOrProvinceCode = 'CA';
- $trackDetails->EstimatedDeliveryAddress->CountryCode = 'US';
- $trackDetails->PackageWeight = new \stdClass();
- $trackDetails->PackageWeight->Value = 23;
- $trackDetails->PackageWeight->Units = 'LB';
- $response->CompletedTrackDetails->TrackDetails = [$trackDetails];
- // @codingStandardsIgnoreEnd
- $this->soapClient->expects($this->exactly($callNum))
- ->method('track')
- ->willReturn($response);
- $this->serializer->method('serialize')
- ->willReturn('TrackingString' . $tracking);
- $status = $this->helper->getObject(Status::class);
- $this->statusFactory->method('create')
- ->willReturn($status);
- $tracks = $this->carrier->getTracking($tracking)->getAllTrackings();
- $this->assertEquals(1, count($tracks));
- $current = $tracks[0];
- $fields = [
- 'signedby',
- 'status',
- 'service',
- 'deliverylocation',
- 'weight',
- ];
- array_walk($fields, function ($field) use ($current) {
- $this->assertNotEmpty($current[$field]);
- });
- $this->assertEquals($expectedDate, $current['deliverydate']);
- $this->assertEquals($expectedTime, $current['deliverytime']);
- $this->assertEquals($expectedDate, $current['shippeddate']);
- }
- /**
- * Gets list of variations for testing ship date.
- *
- * @return array
- */
- public function shipDateDataProvider()
- {
- return [
- 'tracking1' => [
- 'tracking1',
- 'shipTimestamp' => '2016-08-05T14:06:35+01:00',
- 'expectedDate' => '2016-08-05',
- '13:06:35',
- ],
- 'tracking1-again' => [
- 'tracking1',
- 'shipTimestamp' => '2016-08-05T02:06:35+03:00',
- 'expectedDate' => '2016-08-05',
- '13:06:35',
- 0,
- ],
- 'tracking2' => [
- 'tracking2',
- 'shipTimestamp' => '2016-08-05T02:06:35+03:00',
- 'expectedDate' => '2016-08-04',
- '23:06:35',
- ],
- 'tracking3' => [
- 'tracking3',
- 'shipTimestamp' => '2016-08-05T14:06:35',
- 'expectedDate' => '2016-08-05',
- '14:06:35',
- ],
- 'tracking4' => [
- 'tracking4',
- 'shipTimestamp' => '2016-08-05 14:06:35',
- 'expectedDate' => null,
- null,
- ],
- 'tracking5' => [
- 'tracking5',
- 'shipTimestamp' => '2016-08-05 14:06:35+00:00',
- 'expectedDate' => null,
- null,
- ],
- 'tracking6' => [
- 'tracking6',
- 'shipTimestamp' => '2016-08-05',
- 'expectedDate' => null,
- null,
- ],
- 'tracking7' => [
- 'tracking7',
- 'shipTimestamp' => '2016/08/05',
- 'expectedDate' => null,
- null
- ],
- ];
- }
- /**
- * @param string $tracking
- * @param string $shipTimeStamp
- * @param string $expectedDate
- * @param string $expectedTime
- * @param int $callNum
- * @dataProvider shipDateDataProvider
- */
- public function testGetTrackingWithEvents($tracking, $shipTimeStamp, $expectedDate, $expectedTime, $callNum = 1)
- {
- $tracking = $tracking . 'WithEvent';
- // @codingStandardsIgnoreStart
- $response = new \stdClass();
- $response->HighestSeverity = 'SUCCESS';
- $response->CompletedTrackDetails = new \stdClass();
- $event = new \stdClass();
- $event->EventDescription = 'Test';
- $event->Timestamp = $shipTimeStamp;
- $event->Address = new \stdClass();
- $event->Address->City = 'Culver City';
- $event->Address->StateOrProvinceCode = 'CA';
- $event->Address->CountryCode = 'US';
- $trackDetails = new \stdClass();
- $trackDetails->Events = $event;
- $response->CompletedTrackDetails->TrackDetails = $trackDetails;
- // @codingStandardsIgnoreEnd
- $this->soapClient->expects($this->exactly($callNum))
- ->method('track')
- ->willReturn($response);
- $this->serializer->method('serialize')
- ->willReturn('TrackingWithEventsString' . $tracking);
- $status = $this->helper->getObject(Status::class);
- $this->statusFactory->method('create')
- ->willReturn($status);
- $this->carrier->getTracking($tracking);
- $tracks = $this->carrier->getResult()->getAllTrackings();
- $this->assertEquals(1, count($tracks));
- $current = $tracks[0];
- $this->assertNotEmpty($current['progressdetail']);
- $this->assertEquals(1, count($current['progressdetail']));
- $event = $current['progressdetail'][0];
- $fields = ['activity', 'deliverylocation'];
- array_walk($fields, function ($field) use ($event) {
- $this->assertNotEmpty($event[$field]);
- });
- $this->assertEquals($expectedDate, $event['deliverydate']);
- $this->assertEquals($expectedTime, $event['deliverytime']);
- }
- /**
- * Init RateErrorFactory and RateResultErrors mocks
- * @return void
- */
- private function initRateErrorFactory()
- {
- $this->error = $this->getMockBuilder(RateResultError::class)
- ->disableOriginalConstructor()
- ->setMethods(['setCarrier', 'setCarrierTitle', 'setErrorMessage'])
- ->getMock();
- $this->errorFactory = $this->getMockBuilder(RateErrorFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->errorFactory->expects($this->any())
- ->method('create')
- ->willReturn($this->error);
- }
- /**
- * Creates mock rate result factory
- * @return RateResultFactory|MockObject
- */
- private function getRateFactory()
- {
- $rate = $this->getMockBuilder(RateResult::class)
- ->disableOriginalConstructor()
- ->setMethods(['getError'])
- ->getMock();
- $rateFactory = $this->getMockBuilder(RateResultFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $rateFactory->expects($this->any())
- ->method('create')
- ->willReturn($rate);
- return $rateFactory;
- }
- /**
- * Creates mock object for CountryFactory class
- * @return CountryFactory|MockObject
- */
- private function getCountryFactory()
- {
- $country = $this->getMockBuilder(Country::class)
- ->disableOriginalConstructor()
- ->setMethods(['load', 'getData'])
- ->getMock();
- $country->expects($this->any())
- ->method('load')
- ->willReturnSelf();
- $countryFactory = $this->getMockBuilder(CountryFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $countryFactory->expects($this->any())
- ->method('create')
- ->willReturn($country);
- return $countryFactory;
- }
- /**
- * Creates mock object for ResultFactory class
- * @return ResultFactory|MockObject
- */
- private function getResultFactory()
- {
- $resultFactory = $this->getMockBuilder(ResultFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $this->result = $this->helper->getObject(Result::class);
- $resultFactory->expects($this->any())
- ->method('create')
- ->willReturn($this->result);
- return $resultFactory;
- }
- /**
- * Creates mock object for store manager
- * @return StoreManagerInterface|MockObject
- */
- private function getStoreManager()
- {
- $store = $this->getMockBuilder(Store::class)
- ->disableOriginalConstructor()
- ->setMethods(['getBaseCurrencyCode'])
- ->getMock();
- $storeManager = $this->createMock(StoreManagerInterface::class);
- $storeManager->expects($this->any())
- ->method('getStore')
- ->willReturn($store);
- return $storeManager;
- }
- /**
- * Creates mock object for rate method factory
- * @return MethodFactory|MockObject
- */
- private function getRateMethodFactory()
- {
- $priceCurrency = $this->createMock(PriceCurrencyInterface::class);
- $rateMethod = $this->getMockBuilder(Method::class)
- ->setConstructorArgs(['priceCurrency' => $priceCurrency])
- ->setMethods(null)
- ->getMock();
- $rateMethodFactory = $this->getMockBuilder(MethodFactory::class)
- ->disableOriginalConstructor()
- ->setMethods(['create'])
- ->getMock();
- $rateMethodFactory->expects($this->any())
- ->method('create')
- ->willReturn($rateMethod);
- return $rateMethodFactory;
- }
- }
|