NvpTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Paypal\Test\Unit\Model\Api;
  7. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
  8. use Magento\Paypal\Model\Info;
  9. /**
  10. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  11. */
  12. class NvpTest extends \PHPUnit\Framework\TestCase
  13. {
  14. /** @var \Magento\Paypal\Model\Api\Nvp */
  15. protected $model;
  16. /** @var \Magento\Customer\Helper\Address|\PHPUnit_Framework_MockObject_MockObject */
  17. protected $customerAddressHelper;
  18. /** @var \Psr\Log\LoggerInterface|\PHPUnit_Framework_MockObject_MockObject */
  19. protected $logger;
  20. /** @var \Magento\Framework\Locale\ResolverInterface|\PHPUnit_Framework_MockObject_MockObject */
  21. protected $resolver;
  22. /** @var \Magento\Directory\Model\RegionFactory|\PHPUnit_Framework_MockObject_MockObject */
  23. protected $regionFactory;
  24. /** @var \Magento\Directory\Model\CountryFactory|\PHPUnit_Framework_MockObject_MockObject */
  25. protected $countryFactory;
  26. /** @var \Magento\Paypal\Model\Api\ProcessableException|\PHPUnit_Framework_MockObject_MockObject */
  27. protected $processableException;
  28. /** @var \Magento\Framework\Exception\LocalizedException|\PHPUnit_Framework_MockObject_MockObject */
  29. protected $exception;
  30. /** @var \Magento\Framework\HTTP\Adapter\Curl|\PHPUnit_Framework_MockObject_MockObject */
  31. protected $curl;
  32. /** @var \Magento\Paypal\Model\Config|\PHPUnit_Framework_MockObject_MockObject */
  33. protected $config;
  34. /** @var \Magento\Payment\Model\Method\Logger|\PHPUnit_Framework_MockObject_MockObject */
  35. protected $customLoggerMock;
  36. protected function setUp()
  37. {
  38. $this->customerAddressHelper = $this->createMock(\Magento\Customer\Helper\Address::class);
  39. $this->logger = $this->createMock(\Psr\Log\LoggerInterface::class);
  40. $this->customLoggerMock = $this->getMockBuilder(\Magento\Payment\Model\Method\Logger::class)
  41. ->setConstructorArgs([$this->getMockForAbstractClass(\Psr\Log\LoggerInterface::class)])
  42. ->setMethods(['debug'])
  43. ->getMock();
  44. $this->resolver = $this->createMock(\Magento\Framework\Locale\ResolverInterface::class);
  45. $this->regionFactory = $this->createMock(\Magento\Directory\Model\RegionFactory::class);
  46. $this->countryFactory = $this->createMock(\Magento\Directory\Model\CountryFactory::class);
  47. $processableExceptionFactory = $this->createPartialMock(
  48. \Magento\Paypal\Model\Api\ProcessableExceptionFactory::class,
  49. ['create']
  50. );
  51. $processableExceptionFactory->expects($this->any())
  52. ->method('create')
  53. ->will($this->returnCallback(function ($arguments) {
  54. $this->processableException = $this->getMockBuilder(
  55. \Magento\Paypal\Model\Api\ProcessableException::class
  56. )
  57. ->setConstructorArgs([$arguments['phrase'], null, $arguments['code']])
  58. ->getMock();
  59. return $this->processableException;
  60. }));
  61. $exceptionFactory = $this->createPartialMock(
  62. \Magento\Framework\Exception\LocalizedExceptionFactory::class,
  63. ['create']
  64. );
  65. $exceptionFactory->expects($this->any())
  66. ->method('create')
  67. ->will($this->returnCallback(function ($arguments) {
  68. $this->exception = $this->getMockBuilder(\Magento\Framework\Exception\LocalizedException::class)
  69. ->setConstructorArgs([$arguments['phrase']])
  70. ->getMock();
  71. return $this->exception;
  72. }));
  73. $this->curl = $this->createMock(\Magento\Framework\HTTP\Adapter\Curl::class);
  74. $curlFactory = $this->createPartialMock(\Magento\Framework\HTTP\Adapter\CurlFactory::class, ['create']);
  75. $curlFactory->expects($this->any())->method('create')->will($this->returnValue($this->curl));
  76. $this->config = $this->createMock(\Magento\Paypal\Model\Config::class);
  77. $helper = new ObjectManagerHelper($this);
  78. $this->model = $helper->getObject(
  79. \Magento\Paypal\Model\Api\Nvp::class,
  80. [
  81. 'customerAddress' => $this->customerAddressHelper,
  82. 'logger' => $this->logger,
  83. 'customLogger' => $this->customLoggerMock,
  84. 'localeResolver' => $this->resolver,
  85. 'regionFactory' => $this->regionFactory,
  86. 'countryFactory' => $this->countryFactory,
  87. 'processableExceptionFactory' => $processableExceptionFactory,
  88. 'frameworkExceptionFactory' => $exceptionFactory,
  89. 'curlFactory' => $curlFactory,
  90. ]
  91. );
  92. $this->model->setConfigObject($this->config);
  93. }
  94. /**
  95. * @param \Magento\Paypal\Model\Api\Nvp $nvpObject
  96. * @param string $property
  97. * @return mixed
  98. */
  99. protected function _invokeNvpProperty(\Magento\Paypal\Model\Api\Nvp $nvpObject, $property)
  100. {
  101. $object = new \ReflectionClass($nvpObject);
  102. $property = $object->getProperty($property);
  103. $property->setAccessible(true);
  104. return $property->getValue($nvpObject);
  105. }
  106. /**
  107. * @param string $response
  108. * @param array $processableErrors
  109. * @param null|string $exception
  110. * @param string $exceptionMessage
  111. * @param null|int $exceptionCode
  112. * @dataProvider callDataProvider
  113. */
  114. public function testCall($response, $processableErrors, $exception, $exceptionMessage = '', $exceptionCode = null)
  115. {
  116. if (isset($exception)) {
  117. $this->expectException($exception);
  118. $this->expectExceptionMessage($exceptionMessage);
  119. $this->expectExceptionCode($exceptionCode);
  120. }
  121. $this->curl->expects($this->once())
  122. ->method('read')
  123. ->will($this->returnValue($response));
  124. $this->model->setProcessableErrors($processableErrors);
  125. $this->customLoggerMock->expects($this->once())
  126. ->method('debug');
  127. $this->model->call('some method', ['data' => 'some data']);
  128. }
  129. /**
  130. * @return array
  131. */
  132. public function callDataProvider()
  133. {
  134. return [
  135. ['', [], null],
  136. [
  137. "\r\n" . 'ACK=Failure&L_ERRORCODE0=10417&L_SHORTMESSAGE0=Message.&L_LONGMESSAGE0=Long%20Message.',
  138. [],
  139. \Magento\Framework\Exception\LocalizedException::class,
  140. 'PayPal gateway has rejected request. Long Message (#10417: Message).',
  141. 0
  142. ],
  143. [
  144. "\r\n" . 'ACK=Failure&L_ERRORCODE0=10417&L_SHORTMESSAGE0=Message.&L_LONGMESSAGE0=Long%20Message.',
  145. [10417, 10422],
  146. \Magento\Paypal\Model\Api\ProcessableException::class,
  147. 'PayPal gateway has rejected request. Long Message (#10417: Message).',
  148. 10417
  149. ],
  150. [
  151. "\r\n" . 'ACK[7]=Failure&L_ERRORCODE0[5]=10417'
  152. . '&L_SHORTMESSAGE0[8]=Message.&L_LONGMESSAGE0[15]=Long%20Message.',
  153. [10417, 10422],
  154. \Magento\Paypal\Model\Api\ProcessableException::class,
  155. 'PayPal gateway has rejected request. Long Message (#10417: Message).',
  156. 10417
  157. ],
  158. [
  159. "\r\n" . 'ACK[7]=Failure&L_ERRORCODE0[5]=10417&L_SHORTMESSAGE0[8]=Message.',
  160. [10417, 10422],
  161. \Magento\Paypal\Model\Api\ProcessableException::class,
  162. 'PayPal gateway has rejected request. #10417: Message.',
  163. 10417
  164. ],
  165. ];
  166. }
  167. public function testCallGetExpressCheckoutDetails()
  168. {
  169. $this->curl->expects($this->once())
  170. ->method('read')
  171. ->will($this->returnValue(
  172. "\r\n" . 'ACK=Success&SHIPTONAME=Ship%20To%20Name'
  173. . '&SHIPTOSTREET=testStreet'
  174. . '&SHIPTOSTREET2=testApartment'
  175. . '&BUSINESS=testCompany'
  176. . '&SHIPTOCITY=testCity'
  177. . '&PHONENUM=223322'
  178. . '&STATE=testSTATE'
  179. ));
  180. $this->model->callGetExpressCheckoutDetails();
  181. $address = $this->model->getExportedShippingAddress();
  182. $this->assertEquals('Ship To Name', $address->getData('firstname'));
  183. $this->assertEquals(implode("\n", ['testStreet','testApartment']), $address->getStreet());
  184. $this->assertEquals('testCompany', $address->getCompany());
  185. $this->assertEquals('testCity', $address->getCity());
  186. $this->assertEquals('223322', $address->getTelephone());
  187. $this->assertEquals('testSTATE', $address->getRegion());
  188. }
  189. /**
  190. * Tests that callDoReauthorization method is called without errors and
  191. * needed data is imported from response.
  192. */
  193. public function testCallDoReauthorization()
  194. {
  195. $authorizationId = 555;
  196. $paymentStatus = 'Completed';
  197. $pendingReason = 'none';
  198. $protectionEligibility = 'Eligible';
  199. $protectionEligibilityType = 'ItemNotReceivedEligible';
  200. $this->curl->expects($this->once())
  201. ->method('read')
  202. ->willReturn(
  203. "\r\n" . 'ACK=Success'
  204. . '&AUTHORIZATIONID=' . $authorizationId
  205. . '&PAYMENTSTATUS=' . $paymentStatus
  206. . '&PENDINGREASON=' . $pendingReason
  207. . '&PROTECTIONELIGIBILITY=' . $protectionEligibility
  208. . '&PROTECTIONELIGIBILITYTYPE=' . $protectionEligibilityType
  209. );
  210. $this->model->callDoReauthorization();
  211. $expectedImportedData = [
  212. 'authorization_id' => $authorizationId,
  213. 'payment_status' => Info::PAYMENTSTATUS_COMPLETED,
  214. 'pending_reason' => $pendingReason,
  215. 'protection_eligibility' => $protectionEligibility
  216. ];
  217. $this->assertNotContains($protectionEligibilityType, $this->model->getData());
  218. $this->assertEquals($expectedImportedData, $this->model->getData());
  219. }
  220. public function testGetDebugReplacePrivateDataKeys()
  221. {
  222. $debugReplacePrivateDataKeys = $this->_invokeNvpProperty($this->model, '_debugReplacePrivateDataKeys');
  223. $this->assertEquals($debugReplacePrivateDataKeys, $this->model->getDebugReplacePrivateDataKeys());
  224. }
  225. /**
  226. * Tests case if obtained response with code 10415 'Transaction has already
  227. * been completed for this token'. It must does not throws the exception and
  228. * must returns response array.
  229. */
  230. public function testCallTransactionHasBeenCompleted()
  231. {
  232. $response = "\r\n" . 'ACK[7]=Failure&L_ERRORCODE0[5]=10415'
  233. . '&L_SHORTMESSAGE0[8]=Message.&L_LONGMESSAGE0[15]=Long%20Message.';
  234. $processableErrors =[10415];
  235. $this->curl->expects($this->once())
  236. ->method('read')
  237. ->will($this->returnValue($response));
  238. $this->model->setProcessableErrors($processableErrors);
  239. $this->customLoggerMock->expects($this->once())
  240. ->method('debug');
  241. $expectedResponse = [
  242. 'ACK' => 'Failure',
  243. 'L_ERRORCODE0' => '10415',
  244. 'L_SHORTMESSAGE0' => 'Message.',
  245. 'L_LONGMESSAGE0' => 'Long Message.'
  246. ];
  247. $this->assertEquals($expectedResponse, $this->model->call('some method', ['data' => 'some data']));
  248. }
  249. }