CarrierTest.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\Dhl\Model;
  8. use Magento\Framework\HTTP\ZendClient;
  9. use Magento\Framework\HTTP\ZendClientFactory;
  10. use Magento\Framework\Simplexml\Element;
  11. use Magento\Shipping\Model\Tracking\Result\Error;
  12. use Magento\Shipping\Model\Tracking\Result\Status;
  13. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  14. class CarrierTest extends \PHPUnit\Framework\TestCase
  15. {
  16. /**
  17. * @var \Magento\Dhl\Model\Carrier
  18. */
  19. private $dhlCarrier;
  20. /**
  21. * @var ZendClient|MockObject
  22. */
  23. private $httpClientMock;
  24. /**
  25. * @var \Zend_Http_Response|MockObject
  26. */
  27. private $httpResponseMock;
  28. protected function setUp()
  29. {
  30. $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  31. $this->dhlCarrier = $objectManager->create(
  32. \Magento\Dhl\Model\Carrier::class,
  33. ['httpClientFactory' => $this->getHttpClientFactory()]
  34. );
  35. }
  36. /**
  37. * @magentoConfigFixture default_store carriers/dhl/id CustomerSiteID
  38. * @magentoConfigFixture default_store carriers/dhl/password CustomerPassword
  39. * @param string[] $trackingNumbers
  40. * @param string $responseXml
  41. * @param $expectedTrackingData
  42. * @param string $expectedRequestXml
  43. * @dataProvider getTrackingDataProvider
  44. */
  45. public function testGetTracking(
  46. $trackingNumbers,
  47. string $responseXml,
  48. $expectedTrackingData,
  49. string $expectedRequestXml = ''
  50. ) {
  51. $this->httpResponseMock->method('getBody')
  52. ->willReturn($responseXml);
  53. $trackingResult = $this->dhlCarrier->getTracking($trackingNumbers);
  54. $this->assertTrackingResult($expectedTrackingData, $trackingResult->getAllTrackings());
  55. if ($expectedRequestXml !== '') {
  56. $method = new \ReflectionMethod($this->httpClientMock, '_prepareBody');
  57. $method->setAccessible(true);
  58. $requestXml = $method->invoke($this->httpClientMock);
  59. $this->assertRequest($expectedRequestXml, $requestXml);
  60. }
  61. }
  62. /**
  63. * Get tracking data provider
  64. * @return array
  65. */
  66. public function getTrackingDataProvider() : array
  67. {
  68. $expectedMultiAWBRequestXml = file_get_contents(__DIR__ . '/../_files/TrackingRequest_MultipleAWB.xml');
  69. $multiAWBResponseXml = file_get_contents(__DIR__ . '/../_files/TrackingResponse_MultipleAWB.xml');
  70. $expectedSingleAWBRequestXml = file_get_contents(__DIR__ . '/../_files/TrackingRequest_SingleAWB.xml');
  71. $singleAWBResponseXml = file_get_contents(__DIR__ . '/../_files/TrackingResponse_SingleAWB.xml');
  72. $singleNoDataResponseXml = file_get_contents(__DIR__ . '/../_files/SingleknownTrackResponse-no-data-found.xml');
  73. $failedResponseXml = file_get_contents(__DIR__ . '/../_files/Track-res-XML-Parse-Err.xml');
  74. $expectedTrackingDataA = [
  75. 'carrier' => 'dhl',
  76. 'carrier_title' => 'DHL',
  77. 'tracking' => 4781584780,
  78. 'service' => 'DOCUMENT',
  79. 'progressdetail' => [
  80. [
  81. 'activity' => 'SD Shipment information received',
  82. 'deliverydate' => '2017-12-25',
  83. 'deliverytime' => '14:38:00',
  84. 'deliverylocation' => 'BEIJING-CHN [PEK]'
  85. ]
  86. ],
  87. 'weight' => '0.5 K',
  88. ];
  89. $expectedTrackingDataB = [
  90. 'carrier' => 'dhl',
  91. 'carrier_title' => 'DHL',
  92. 'tracking' => 4781585060,
  93. 'service' => 'NOT RESTRICTED FOR TRANSPORT,',
  94. 'progressdetail' => [
  95. [
  96. 'activity' => 'SD Shipment information received',
  97. 'deliverydate' => '2017-12-24',
  98. 'deliverytime' => '13:35:00',
  99. 'deliverylocation' => 'HONG KONG-HKG [HKG]'
  100. ]
  101. ],
  102. 'weight' => '2.0 K',
  103. ];
  104. $expectedTrackingDataC = [
  105. 'carrier' => 'dhl',
  106. 'carrier_title' => 'DHL',
  107. 'tracking' => 5702254250,
  108. 'service' => 'CD',
  109. 'progressdetail' => [
  110. [
  111. 'activity' => 'SD Shipment information received',
  112. 'deliverydate' => '2017-12-24',
  113. 'deliverytime' => '04:12:00',
  114. 'deliverylocation' => 'BIRMINGHAM-GBR [BHX]'
  115. ]
  116. ],
  117. 'weight' => '0.12 K',
  118. ];
  119. $expectedTrackingDataD = [
  120. 'carrier' => 'dhl',
  121. 'carrier_title' => 'DHL',
  122. 'tracking' => 4781585060,
  123. 'error_message' => __('Unable to retrieve tracking')
  124. ];
  125. $expectedTrackingDataE = [
  126. 'carrier' => 'dhl',
  127. 'carrier_title' => 'DHL',
  128. 'tracking' => 111,
  129. 'error_message' => __(
  130. 'Error #%1 : %2',
  131. '111',
  132. ' Error Parsing incoming request XML
  133. Error: The content of element type
  134. "ShipperReference" must match
  135. "(ReferenceID,ReferenceType?)". at line
  136. 16, column 22'
  137. )
  138. ];
  139. return [
  140. 'multi-AWB' => [
  141. ['4781584780', '4781585060', '5702254250'],
  142. $multiAWBResponseXml,
  143. [$expectedTrackingDataA, $expectedTrackingDataB, $expectedTrackingDataC],
  144. $expectedMultiAWBRequestXml
  145. ],
  146. 'single-AWB' => [
  147. ['4781585060'],
  148. $singleAWBResponseXml,
  149. [$expectedTrackingDataB],
  150. $expectedSingleAWBRequestXml
  151. ],
  152. 'single-AWB-no-data' => [
  153. ['4781585061'],
  154. $singleNoDataResponseXml,
  155. [$expectedTrackingDataD]
  156. ],
  157. 'failed-response' => [
  158. ['4781585060-failed'],
  159. $failedResponseXml,
  160. [$expectedTrackingDataE]
  161. ]
  162. ];
  163. }
  164. /**
  165. * Get mocked Http Client Factory
  166. *
  167. * @return MockObject
  168. */
  169. private function getHttpClientFactory(): MockObject
  170. {
  171. $this->httpResponseMock = $this->getMockBuilder(\Zend_Http_Response::class)
  172. ->disableOriginalConstructor()
  173. ->getMock();
  174. $this->httpClientMock = $this->getMockBuilder(ZendClient::class)
  175. ->disableOriginalConstructor()
  176. ->setMethods(['request'])
  177. ->getMock();
  178. $this->httpClientMock->method('request')
  179. ->willReturn($this->httpResponseMock);
  180. /** @var ZendClientFactory|MockObject $httpClientFactoryMock */
  181. $httpClientFactoryMock = $this->getMockBuilder(ZendClientFactory::class)
  182. ->disableOriginalConstructor()
  183. ->getMock();
  184. $httpClientFactoryMock->method('create')
  185. ->willReturn($this->httpClientMock);
  186. return $httpClientFactoryMock;
  187. }
  188. /**
  189. * Assert request
  190. *
  191. * @param string $expectedRequestXml
  192. * @param string $requestXml
  193. */
  194. private function assertRequest(string $expectedRequestXml, string $requestXml): void
  195. {
  196. $expectedRequestElement = new Element($expectedRequestXml);
  197. $requestElement = new Element($requestXml);
  198. $requestMessageTime = $requestElement->Request->ServiceHeader->MessageTime->__toString();
  199. $this->assertEquals(
  200. 1,
  201. preg_match("/\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}\+\d{2}\:\d{2}/", $requestMessageTime)
  202. );
  203. $expectedRequestElement->Request->ServiceHeader->MessageTime = $requestMessageTime;
  204. $messageReference = $requestElement->Request->ServiceHeader->MessageReference->__toString();
  205. $this->assertStringStartsWith('MAGE_TRCK_', $messageReference);
  206. $this->assertGreaterThanOrEqual(28, strlen($messageReference));
  207. $this->assertLessThanOrEqual(32, strlen($messageReference));
  208. $requestElement->Request->ServiceHeader->MessageReference = 'MAGE_TRCK_28TO32_Char_CHECKED';
  209. $this->assertXmlStringEqualsXmlString($expectedRequestElement->asXML(), $requestElement->asXML());
  210. }
  211. /**
  212. * Assert tracking
  213. *
  214. * @param array|null $expectedTrackingData
  215. * @param Status[]|null $trackingResults
  216. * @return void
  217. */
  218. private function assertTrackingResult($expectedTrackingData, $trackingResults): void
  219. {
  220. if (null === $expectedTrackingData) {
  221. $this->assertNull($trackingResults);
  222. } else {
  223. $ctr = 0;
  224. foreach ($trackingResults as $trackingResult) {
  225. $this->assertEquals($expectedTrackingData[$ctr++], $trackingResult->getData());
  226. }
  227. }
  228. }
  229. }