Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
CarrierTest.php
Go to the documentation of this file.
1 <?php
7 
14 use Magento\Framework\HTTP\ZendClientFactory;
21 use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory;
23 use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory;
25 use Magento\Shipping\Helper\Carrier as CarrierHelper;
27 use Magento\Shipping\Model\Rate\ResultFactory;
30 use Magento\Shipping\Model\Simplexml\ElementFactory;
33 use PHPUnit_Framework_MockObject_MockObject as MockObject;
34 use Psr\Log\LoggerInterface;
36 
40 class CarrierTest extends \PHPUnit\Framework\TestCase
41 {
45  private $objectManager;
46 
50  private $httpResponse;
51 
55  private $model;
56 
60  private $error;
61 
65  private $errorFactory;
66 
70  private $scope;
71 
75  private $httpClient;
76 
80  private $xmlValidator;
81 
85  private $request;
86 
90  private $logger;
91 
95  protected function setUp()
96  {
97  $this->objectManager = new ObjectManager($this);
98 
99  $this->request = $this->getMockBuilder(Request::class)
100  ->disableOriginalConstructor()
101  ->setMethods(
102  [
103  'getPackages',
104  'getOrigCountryId',
105  'setPackages',
106  'setPackageWeight',
107  'setPackageValue',
108  'setValueWithDiscount',
109  'setPackageCustomsValue',
110  'setFreeMethodWeight',
111  'getPackageWeight',
112  'getFreeMethodWeight',
113  'getOrderShipment',
114  ]
115  )
116  ->getMock();
117 
118  $this->scope = $this->getMockForAbstractClass(ScopeConfigInterface::class);
119 
120  $xmlElFactory = $this->getXmlFactory();
121  $rateFactory = $this->getRateFactory();
122  $rateMethodFactory = $this->getRateMethodFactory();
123  $httpClientFactory = $this->getHttpClientFactory();
124  $configReader = $this->getConfigReader();
125  $readFactory = $this->getReadFactory();
126  $storeManager = $this->getStoreManager();
127 
128  $this->error = $this->getMockBuilder(Error::class)
129  ->setMethods(['setCarrier', 'setCarrierTitle', 'setErrorMessage'])
130  ->getMock();
131  $this->errorFactory = $this->getMockBuilder(ErrorFactory::class)
132  ->disableOriginalConstructor()
133  ->setMethods(['create'])
134  ->getMock();
135  $this->errorFactory->method('create')
136  ->willReturn($this->error);
137 
138  $carrierHelper = $this->getCarrierHelper();
139 
140  $this->xmlValidator = $this->getMockBuilder(XmlValidator::class)
141  ->disableOriginalConstructor()
142  ->getMock();
143 
144  $this->logger = $this->getMockForAbstractClass(LoggerInterface::class);
145 
146  $this->model = $this->objectManager->getObject(
147  Carrier::class,
148  [
149  'scopeConfig' => $this->scope,
150  'xmlSecurity' => new Security(),
151  'logger' => $this->logger,
152  'xmlElFactory' => $xmlElFactory,
153  'rateFactory' => $rateFactory,
154  'rateErrorFactory' => $this->errorFactory,
155  'rateMethodFactory' => $rateMethodFactory,
156  'httpClientFactory' => $httpClientFactory,
157  'readFactory' => $readFactory,
158  'storeManager' => $storeManager,
159  'configReader' => $configReader,
160  'carrierHelper' => $carrierHelper,
161  'data' => ['id' => 'dhl', 'store' => '1'],
162  'xmlValidator' => $this->xmlValidator,
163  ]
164  );
165  }
166 
173  public function scopeConfigGetValue($path)
174  {
175  $pathMap = [
176  'carriers/dhl/shipment_days' => 'Mon,Tue,Wed,Thu,Fri,Sat',
177  'carriers/dhl/intl_shipment_days' => 'Mon,Tue,Wed,Thu,Fri,Sat',
178  'carriers/dhl/allowed_methods' => 'IE',
179  'carriers/dhl/international_searvice' => 'IE',
180  'carriers/dhl/gateway_url' => 'https://xmlpi-ea.dhl.com/XMLShippingServlet',
181  'carriers/dhl/id' => 'some ID',
182  'carriers/dhl/password' => 'some password',
183  'carriers/dhl/content_type' => 'N',
184  'carriers/dhl/nondoc_methods' => '1,3,4,8,P,Q,E,F,H,J,M,V,Y',
185  'carriers/dhl/showmethod' => 1,
186  'carriers/dhl/title' => 'dhl Title',
187  'carriers/dhl/specificerrmsg' => 'dhl error message',
188  'carriers/dhl/unit_of_measure' => 'K',
189  'carriers/dhl/size' => '1',
190  'carriers/dhl/height' => '1.6',
191  'carriers/dhl/width' => '1.6',
192  'carriers/dhl/depth' => '1.6',
193  'carriers/dhl/debug' => 1,
194  'shipping/origin/country_id' => 'GB',
195  ];
196  return isset($pathMap[$path]) ? $pathMap[$path] : null;
197  }
198 
200  {
201  $xml = simplexml_load_file(
202  __DIR__ . '/_files/response_shipping_label.xml'
203  );
205  $this->assertEquals(1111, $result->getTrackingNumber());
206  $this->assertEquals(base64_decode('OutputImageContent'), $result->getShippingLabelContent());
207  }
208 
214  public function testPrepareShippingLabelContentException(\SimpleXMLElement $xml)
215  {
217  }
218 
223  {
224  $filesPath = __DIR__ . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR;
225  $empty = $billingNumberOnly = $outputImageOnly = simplexml_load_file(
226  $filesPath . 'response_shipping_label.xml'
227  );
228  unset(
229  $empty->{'AirwayBillNumber'},
230  $empty->{'LabelImage'},
231  $billingNumberOnly->{'LabelImage'},
232  $outputImageOnly->{'AirwayBillNumber'}
233  );
234 
235  return [[$empty], [$billingNumberOnly], [$outputImageOnly]];
236  }
237 
242  protected function _invokePrepareShippingLabelContent(\SimpleXMLElement $xml)
243  {
244  $model = $this->objectManager->getObject(Carrier::class);
245  $method = new \ReflectionMethod($model, '_prepareShippingLabelContent');
246  $method->setAccessible(true);
247  return $method->invoke($model, $xml);
248  }
249 
250  public function testCollectRates()
251  {
252  $this->scope->method('getValue')
253  ->willReturnCallback([$this, 'scopeConfigGetValue']);
254 
255  $this->scope->method('isSetFlag')
256  ->willReturn(true);
257 
258  $this->httpResponse->method('getBody')
259  ->willReturn(file_get_contents(__DIR__ . '/_files/success_dhl_response_rates.xml'));
260 
262  $request = $this->objectManager->getObject(
263  RateRequest::class,
264  require __DIR__ . '/_files/rates_request_data_dhl.php'
265  );
266 
267  $reflectionClass = new \ReflectionObject($this->httpClient);
268  $rawPostData = $reflectionClass->getProperty('raw_post_data');
269  $rawPostData->setAccessible(true);
270 
271  $this->logger->expects($this->once())
272  ->method('debug')
273  ->with($this->stringContains('<SiteID>****</SiteID><Password>****</Password>'));
274 
275  self::assertNotEmpty($this->model->collectRates($request)->getAllRates());
276  self::assertContains('<Weight>18.223</Weight>', $rawPostData->getValue($this->httpClient));
277  self::assertContains('<Height>0.630</Height>', $rawPostData->getValue($this->httpClient));
278  self::assertContains('<Width>0.630</Width>', $rawPostData->getValue($this->httpClient));
279  self::assertContains('<Depth>0.630</Depth>', $rawPostData->getValue($this->httpClient));
280  }
281 
283  {
284  $this->scope->method('getValue')
285  ->willReturnCallback([$this, 'scopeConfigGetValue']);
286 
287  $this->scope->expects($this->once())->method('isSetFlag')->willReturn(false);
288 
289  $this->error->expects($this->once())->method('setCarrier')->with('dhl');
290  $this->error->expects($this->once())->method('setCarrierTitle');
291  $this->error->expects($this->once())->method('setErrorMessage');
292 
293  $request = new RateRequest();
294  $request->setPackageWeight(1);
295 
296  $this->assertSame($this->error, $this->model->collectRates($request));
297  }
298 
299  public function testCollectRatesFail()
300  {
301  $this->scope->expects($this->once())->method('isSetFlag')->willReturn(true);
302 
303  $request = new RateRequest();
304  $request->setPackageWeight(1);
305 
306  $this->assertFalse(false, $this->model->collectRates($request));
307  }
308 
312  public function testRequestToShipment()
313  {
314  $this->scope->method('getValue')
315  ->willReturnCallback([$this, 'scopeConfigGetValue']);
316 
317  $this->httpResponse->method('getBody')
318  ->willReturn(utf8_encode(file_get_contents(__DIR__ . '/_files/response_shipping_label.xml')));
319 
320  $packages = [
321  'package' => [
322  'params' => [
323  'width' => '3',
324  'length' => '3',
325  'height' => '3',
326  'dimension_units' => 'INCH',
327  'weight_units' => 'POUND',
328  'weight' => '0.454000000001',
329  'customs_value' => '10.00',
330  'container' => Carrier::DHL_CONTENT_TYPE_NON_DOC,
331  ],
332  'items' => [
333  'item1' => [
334  'name' => 'item_name',
335  ],
336  ],
337  ],
338  ];
339 
340  $order = $this->getMockBuilder(Order::class)
341  ->disableOriginalConstructor()
342  ->getMock();
343  $order->method('getSubtotal')
344  ->willReturn('10.00');
345 
346  $shipment = $this->getMockBuilder(Order\Shipment::class)
347  ->disableOriginalConstructor()
348  ->getMock();
349  $shipment->method('getOrder')
350  ->willReturn($order);
351 
352  $this->request->method('getPackages')
353  ->willReturn($packages);
354  $this->request->method('getOrigCountryId')
355  ->willReturn('GB');
356  $this->request->method('setPackages')
357  ->willReturnSelf();
358  $this->request->method('setPackageWeight')
359  ->willReturnSelf();
360  $this->request->method('setPackageValue')
361  ->willReturnSelf();
362  $this->request->method('setValueWithDiscount')
363  ->willReturnSelf();
364  $this->request->method('setPackageCustomsValue')
365  ->willReturnSelf();
366  $this->request->method('setFreeMethodWeight')
367  ->willReturnSelf();
368  $this->request->method('getPackageWeight')
369  ->willReturn('0.454000000001');
370  $this->request->method('getFreeMethodWeight')
371  ->willReturn('0.454000000001');
372  $this->request->method('getOrderShipment')
373  ->willReturn($shipment);
374 
375  $this->logger->method('debug')
376  ->with($this->stringContains('<SiteID>****</SiteID><Password>****</Password>'));
377 
378  $result = $this->model->requestToShipment($this->request);
379 
380  $reflectionClass = new \ReflectionObject($this->httpClient);
381  $rawPostData = $reflectionClass->getProperty('raw_post_data');
382  $rawPostData->setAccessible(true);
383 
384  $this->assertNotNull($result);
385  $this->assertContains('<Weight>0.454</Weight>', $rawPostData->getValue($this->httpClient));
386  }
387 
394  {
395  return [
396  [
397  'GB'
398  ],
399  [
400  null
401  ]
402  ];
403  }
404 
411  {
412  $this->scope->method('getValue')
413  ->willReturnMap(
414  [
415  ['shipping/origin/country_id', ScopeInterface::SCOPE_STORE, null, 'SG'],
416  ['carriers/dhl/gateway_url', ScopeInterface::SCOPE_STORE, null, 'https://xmlpi-ea.dhl.com'],
417  ]
418  );
419 
420  $this->httpResponse->method('getBody')
421  ->willReturn(utf8_encode(file_get_contents(__DIR__ . '/_files/response_shipping_label.xml')));
422 
423  $packages = [
424  'package' => [
425  'params' => [
426  'width' => '1',
427  'length' => '1',
428  'height' => '1',
429  'dimension_units' => 'INCH',
430  'weight_units' => 'POUND',
431  'weight' => '0.45',
432  'customs_value' => '10.00',
433  'container' => Carrier::DHL_CONTENT_TYPE_NON_DOC,
434  ],
435  'items' => [
436  'item1' => [
437  'name' => 'item_name',
438  ],
439  ],
440  ],
441  ];
442 
443  $this->request->method('getPackages')->willReturn($packages);
444  $this->request->method('getOrigCountryId')->willReturn('SG');
445  $this->request->method('setPackages')->willReturnSelf();
446  $this->request->method('setPackageWeight')->willReturnSelf();
447  $this->request->method('setPackageValue')->willReturnSelf();
448  $this->request->method('setValueWithDiscount')->willReturnSelf();
449  $this->request->method('setPackageCustomsValue')->willReturnSelf();
450 
451  $result = $this->model->requestToShipment($this->request);
452 
453  $reflectionClass = new \ReflectionObject($this->httpClient);
454  $rawPostData = $reflectionClass->getProperty('raw_post_data');
455  $rawPostData->setAccessible(true);
456 
457  $this->assertNotNull($result);
458  $requestXml = $rawPostData->getValue($this->httpClient);
459 
460  $this->assertNotContains(
461  'NewShipper',
462  $requestXml,
463  'NewShipper is restricted field for AP region'
464  );
465  $this->assertNotContains(
466  'Division',
467  $requestXml,
468  'Division is restricted field for AP region'
469  );
470  $this->assertNotContains(
471  'RegisteredAccount',
472  $requestXml,
473  'RegisteredAccount is restricted field for AP region'
474  );
475  }
476 
483  public function testGetDhlProducts(string $docType, array $products)
484  {
485  $this->assertEquals($products, $this->model->getDhlProducts($docType));
486  }
487 
491  public function dhlProductsDataProvider() : array
492  {
493  return [
494  'doc' => [
495  'docType' => Carrier::DHL_CONTENT_TYPE_DOC,
496  'products' => [
497  '2' => 'Easy shop',
498  '5' => 'Sprintline',
499  '6' => 'Secureline',
500  '7' => 'Express easy',
501  '9' => 'Europack',
502  'B' => 'Break bulk express',
503  'C' => 'Medical express',
504  'D' => 'Express worldwide',
505  'U' => 'Express worldwide',
506  'K' => 'Express 9:00',
507  'L' => 'Express 10:30',
508  'G' => 'Domestic economy select',
509  'W' => 'Economy select',
510  'I' => 'Domestic express 9:00',
511  'N' => 'Domestic express',
512  'O' => 'Others',
513  'R' => 'Globalmail business',
514  'S' => 'Same day',
515  'T' => 'Express 12:00',
516  'X' => 'Express envelope',
517  ],
518  ],
519  'non-doc' => [
520  'docType' => Carrier::DHL_CONTENT_TYPE_NON_DOC,
521  'products' => [
522  '1' => 'Domestic express 12:00',
523  '3' => 'Easy shop',
524  '4' => 'Jetline',
525  '8' => 'Express easy',
526  'P' => 'Express worldwide',
527  'Q' => 'Medical express',
528  'E' => 'Express 9:00',
529  'F' => 'Freight worldwide',
530  'H' => 'Economy select',
531  'J' => 'Jumbo box',
532  'M' => 'Express 10:30',
533  'V' => 'Europack',
534  'Y' => 'Express 12:00',
535  ],
536  ],
537  ];
538  }
539 
545  private function getXmlFactory(): MockObject
546  {
547  $xmlElFactory = $this->getMockBuilder(ElementFactory::class)
548  ->disableOriginalConstructor()
549  ->setMethods(['create'])
550  ->getMock();
551  $xmlElFactory->method('create')
552  ->willReturnCallback(
553  function ($data) {
554  $helper = new ObjectManager($this);
555 
556  return $helper->getObject(
557  Element::class,
558  ['data' => $data['data']]
559  );
560  }
561  );
562 
563  return $xmlElFactory;
564  }
565 
571  private function getRateFactory(): MockObject
572  {
573  $rateFactory = $this->getMockBuilder(ResultFactory::class)
574  ->disableOriginalConstructor()
575  ->setMethods(['create'])
576  ->getMock();
577  $rateResult = $this->getMockBuilder(Result::class)
578  ->disableOriginalConstructor()
579  ->setMethods(null)
580  ->getMock();
581  $rateFactory->method('create')
582  ->willReturn($rateResult);
583 
584  return $rateFactory;
585  }
586 
592  private function getRateMethodFactory(): MockObject
593  {
594  $rateMethodFactory = $this->getMockBuilder(MethodFactory::class)
595  ->disableOriginalConstructor()
596  ->setMethods(['create'])
597  ->getMock();
598  $rateMethod = $this->getMockBuilder(Method::class)
599  ->disableOriginalConstructor()
600  ->setMethods(['setPrice'])
601  ->getMock();
602  $rateMethod->method('setPrice')
603  ->willReturnSelf();
604  $rateMethodFactory->method('create')
605  ->willReturn($rateMethod);
606 
607  return $rateMethodFactory;
608  }
609 
613  private function getConfigReader(): MockObject
614  {
615  $configReader = $this->getMockBuilder(Reader::class)
616  ->disableOriginalConstructor()
617  ->getMock();
618  $configReader->method('getModuleDir')
619  ->willReturn('/etc/path');
620 
621  return $configReader;
622  }
623 
627  private function getReadFactory(): MockObject
628  {
629  $modulesDirectory = $this->getMockBuilder(Read::class)
630  ->disableOriginalConstructor()
631  ->setMethods(['getRelativePath', 'readFile'])
632  ->getMock();
633  $modulesDirectory->method('readFile')
634  ->willReturn(file_get_contents(__DIR__ . '/_files/countries.xml'));
635  $readFactory = $this->createMock(ReadFactory::class);
636  $readFactory->method('create')
637  ->willReturn($modulesDirectory);
638 
639  return $readFactory;
640  }
641 
645  private function getStoreManager(): MockObject
646  {
647  $storeManager = $this->getMockBuilder(StoreManager::class)
648  ->disableOriginalConstructor()
649  ->setMethods(['getWebsite'])
650  ->getMock();
651  $website = $this->getMockBuilder(Website::class)
652  ->disableOriginalConstructor()
653  ->setMethods(['getBaseCurrencyCode', '__wakeup'])
654  ->getMock();
655  $website->method('getBaseCurrencyCode')
656  ->willReturn('USD');
657  $storeManager->method('getWebsite')
658  ->willReturn($website);
659 
660  return $storeManager;
661  }
662 
666  private function getCarrierHelper(): CarrierHelper
667  {
668  $localeResolver = $this->getMockForAbstractClass(ResolverInterface::class);
669  $localeResolver->method('getLocale')
670  ->willReturn('fr_FR');
671  $carrierHelper = $this->objectManager->getObject(
672  CarrierHelper::class,
673  [
674  'localeResolver' => $localeResolver,
675  ]
676  );
677 
678  return $carrierHelper;
679  }
680 
684  private function getHttpClientFactory(): MockObject
685  {
686  $this->httpResponse = $this->getMockBuilder(\Zend_Http_Response::class)
687  ->disableOriginalConstructor()
688  ->getMock();
689  $this->httpClient = $this->getMockBuilder(ZendClient::class)
690  ->disableOriginalConstructor()
691  ->setMethods(['request'])
692  ->getMock();
693  $this->httpClient->method('request')
694  ->willReturn($this->httpResponse);
695  $httpClientFactory = $this->getMockBuilder(ZendClientFactory::class)
696  ->disableOriginalConstructor()
697  ->getMock();
698  $httpClientFactory->method('create')
699  ->willReturn($this->httpClient);
700 
701  return $httpClientFactory;
702  }
703 }
$helper
Definition: iframe.phtml:13
testPrepareShippingLabelContentException(\SimpleXMLElement $xml)
defined('TESTS_BP')||define('TESTS_BP' __DIR__
Definition: _bootstrap.php:60
$order
Definition: order.php:55
$storeManager
$reflectionClass
Definition: categories.php:25
testGetDhlProducts(string $docType, array $products)
$method
Definition: info.phtml:13
foreach($order->getItems() as $orderItem) $shipment
_invokePrepareShippingLabelContent(\SimpleXMLElement $xml)