TokensConfigProviderTest.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Vault\Test\Unit\Model\Ui\Adminhtml;
  7. use Magento\Backend\Model\Session\Quote;
  8. use Magento\Framework\Api\Filter;
  9. use Magento\Framework\Api\FilterBuilder;
  10. use Magento\Framework\Api\SearchCriteria;
  11. use Magento\Framework\Api\SearchCriteriaBuilder;
  12. use Magento\Framework\Exception\InputException;
  13. use Magento\Framework\Exception\NoSuchEntityException;
  14. use Magento\Framework\Intl\DateTimeFactory;
  15. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  16. use Magento\Framework\TestFramework\Unit\Matcher\MethodInvokedAtIndex;
  17. use Magento\Payment\Helper\Data;
  18. use Magento\Sales\Api\Data\OrderInterface;
  19. use Magento\Sales\Api\Data\OrderPaymentInterface;
  20. use Magento\Sales\Api\OrderRepositoryInterface;
  21. use Magento\Store\Api\Data\StoreInterface;
  22. use Magento\Store\Model\StoreManagerInterface;
  23. use Magento\Vault\Api\Data\PaymentTokenInterface;
  24. use Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface;
  25. use Magento\Vault\Api\PaymentTokenManagementInterface;
  26. use Magento\Vault\Api\PaymentTokenRepositoryInterface;
  27. use Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider;
  28. use Magento\Vault\Model\Ui\TokenUiComponentInterface;
  29. use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface;
  30. use Magento\Vault\Model\VaultPaymentInterface;
  31. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  32. /**
  33. * Class TokensConfigProviderTest
  34. *
  35. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  36. */
  37. class TokensConfigProviderTest extends \PHPUnit\Framework\TestCase
  38. {
  39. /**#@+
  40. * Global values
  41. */
  42. const STORE_ID = 1;
  43. const ORDER_ID = 2;
  44. const ORDER_PAYMENT_ENTITY_ID = 3;
  45. const ENTITY_ID = 4;
  46. const VAULT_PAYMENT_CODE = 'vault_payment';
  47. const VAULT_PROVIDER_CODE = 'payment';
  48. /**#@-*/
  49. /**
  50. * @var PaymentTokenRepositoryInterface|MockObject
  51. */
  52. private $paymentTokenRepository;
  53. /**
  54. * @var FilterBuilder|MockObject
  55. */
  56. private $filterBuilder;
  57. /**
  58. * @var SearchCriteriaBuilder|MockObject
  59. */
  60. private $searchCriteriaBuilder;
  61. /**
  62. * @var Quote|MockObject
  63. */
  64. private $session;
  65. /**
  66. * @var StoreManagerInterface|MockObject
  67. */
  68. private $storeManager;
  69. /**
  70. * @var StoreInterface|MockObject
  71. */
  72. private $store;
  73. /**
  74. * @var DateTimeFactory|MockObject
  75. */
  76. private $dateTimeFactory;
  77. /**
  78. * @var Data|MockObject
  79. */
  80. private $paymentDataHelper;
  81. /**
  82. * @var VaultPaymentInterface|MockObject
  83. */
  84. private $vaultPayment;
  85. /**
  86. * @var PaymentTokenManagementInterface|MockObject
  87. */
  88. private $paymentTokenManagement;
  89. /**
  90. * @var OrderRepositoryInterface|MockObject
  91. */
  92. private $orderRepository;
  93. /**
  94. * @var TokenUiComponentProviderInterface|MockObject
  95. */
  96. private $tokenComponentProvider;
  97. /**
  98. * @var ObjectManager
  99. */
  100. private $objectManager;
  101. /**
  102. * @var TokensConfigProvider
  103. */
  104. private $configProvider;
  105. protected function setUp()
  106. {
  107. $this->paymentTokenRepository = $this->getMockBuilder(PaymentTokenRepositoryInterface::class)
  108. ->getMockForAbstractClass();
  109. $this->filterBuilder = $this->getMockBuilder(FilterBuilder::class)
  110. ->disableOriginalConstructor()
  111. ->getMock();
  112. $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class)
  113. ->disableOriginalConstructor()
  114. ->getMock();
  115. $this->session = $this->getMockBuilder(Quote::class)
  116. ->disableOriginalConstructor()
  117. ->setMethods(['getCustomerId', 'getReordered'])
  118. ->getMock();
  119. $this->dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class)
  120. ->disableOriginalConstructor()
  121. ->getMock();
  122. $this->paymentDataHelper = $this->getMockBuilder(Data::class)
  123. ->disableOriginalConstructor()
  124. ->setMethods(['getMethodInstance'])
  125. ->getMock();
  126. $this->paymentTokenManagement = $this->getMockBuilder(PaymentTokenManagementInterface::class)
  127. ->getMockForAbstractClass();
  128. $this->orderRepository = $this->getMockBuilder(OrderRepositoryInterface::class)
  129. ->getMockForAbstractClass();
  130. $this->vaultPayment = $this->getMockForAbstractClass(VaultPaymentInterface::class);
  131. $this->objectManager = new ObjectManager($this);
  132. $this->initStoreMock();
  133. $this->tokenComponentProvider = $this->createMock(TokenUiComponentProviderInterface::class);
  134. $this->configProvider = new TokensConfigProvider(
  135. $this->session,
  136. $this->paymentTokenRepository,
  137. $this->filterBuilder,
  138. $this->searchCriteriaBuilder,
  139. $this->storeManager,
  140. $this->dateTimeFactory,
  141. [
  142. self::VAULT_PROVIDER_CODE => $this->tokenComponentProvider
  143. ]
  144. );
  145. $this->objectManager->setBackwardCompatibleProperty(
  146. $this->configProvider,
  147. 'paymentDataHelper',
  148. $this->paymentDataHelper
  149. );
  150. $this->objectManager->setBackwardCompatibleProperty(
  151. $this->configProvider,
  152. 'paymentTokenManagement',
  153. $this->paymentTokenManagement
  154. );
  155. $this->objectManager->setBackwardCompatibleProperty(
  156. $this->configProvider,
  157. 'orderRepository',
  158. $this->orderRepository
  159. );
  160. }
  161. /**
  162. * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents
  163. */
  164. public function testGetTokensComponentsRegisteredCustomer()
  165. {
  166. $customerId = 1;
  167. $this->session->expects(static::once())
  168. ->method('getCustomerId')
  169. ->willReturn($customerId);
  170. $this->paymentDataHelper->expects(static::once())
  171. ->method('getMethodInstance')
  172. ->with(self::VAULT_PAYMENT_CODE)
  173. ->willReturn($this->vaultPayment);
  174. $this->vaultPayment->expects(static::once())
  175. ->method('isActive')
  176. ->with(self::STORE_ID)
  177. ->willReturn(true);
  178. $this->vaultPayment->expects(static::once())
  179. ->method('getProviderCode')
  180. ->willReturn(self::VAULT_PROVIDER_CODE);
  181. /** @var PaymentTokenInterface|MockObject $token */
  182. $token = $this->getMockBuilder(PaymentTokenInterface::class)
  183. ->getMockForAbstractClass();
  184. $tokenUiComponent = $this->getTokenUiComponentProvider($token);
  185. $searchCriteria = $this->getSearchCriteria($customerId, self::ENTITY_ID, self::VAULT_PROVIDER_CODE);
  186. $date = $this->getMockBuilder(\DateTime::class)
  187. ->disableOriginalConstructor()
  188. ->getMock();
  189. $this->dateTimeFactory->expects(static::once())
  190. ->method('create')
  191. ->with("now", new \DateTimeZone('UTC'))
  192. ->willReturn($date);
  193. $date->expects(static::once())
  194. ->method('format')
  195. ->with('Y-m-d 00:00:00')
  196. ->willReturn('2015-01-01 00:00:00');
  197. $searchResult = $this->getMockBuilder(PaymentTokenSearchResultsInterface::class)
  198. ->getMockForAbstractClass();
  199. $this->paymentTokenRepository->expects(self::once())
  200. ->method('getList')
  201. ->with($searchCriteria)
  202. ->willReturn($searchResult);
  203. $searchResult->expects(self::once())
  204. ->method('getItems')
  205. ->willReturn([$token]);
  206. static::assertEquals([$tokenUiComponent], $this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE));
  207. }
  208. /**
  209. * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents
  210. */
  211. public function testGetTokensComponentsGuestCustomer()
  212. {
  213. $customerId = null;
  214. $this->initStoreMock();
  215. $this->session->expects(static::once())
  216. ->method('getCustomerId')
  217. ->willReturn($customerId);
  218. $this->paymentDataHelper->expects(static::once())
  219. ->method('getMethodInstance')
  220. ->with(self::VAULT_PAYMENT_CODE)
  221. ->willReturn($this->vaultPayment);
  222. $this->vaultPayment->expects(static::once())
  223. ->method('isActive')
  224. ->with(self::STORE_ID)
  225. ->willReturn(true);
  226. $this->vaultPayment->expects(static::once())
  227. ->method('getProviderCode')
  228. ->willReturn(self::VAULT_PROVIDER_CODE);
  229. /** @var PaymentTokenInterface|MockObject $token */
  230. $token = $this->getMockBuilder(PaymentTokenInterface::class)
  231. ->getMockForAbstractClass();
  232. $this->session->expects(static::once())
  233. ->method('getReordered')
  234. ->willReturn(self::ORDER_ID);
  235. $this->orderRepository->expects(static::once())
  236. ->method('get')
  237. ->with(self::ORDER_ID)
  238. ->willReturn($this->getOrderMock());
  239. $this->paymentTokenManagement->expects(static::once())
  240. ->method('getByPaymentId')
  241. ->with(self::ORDER_PAYMENT_ENTITY_ID)
  242. ->willReturn($token);
  243. $token->expects(static::once())
  244. ->method('getEntityId')
  245. ->willReturn(self::ENTITY_ID);
  246. $tokenUiComponent = $this->getTokenUiComponentProvider($token);
  247. $searchCriteria = $this->getSearchCriteria($customerId, self::ENTITY_ID, self::VAULT_PROVIDER_CODE);
  248. $date = $this->getMockBuilder('DateTime')
  249. ->disableOriginalConstructor()
  250. ->getMock();
  251. $this->dateTimeFactory->expects(static::once())
  252. ->method('create')
  253. ->with("now", new \DateTimeZone('UTC'))
  254. ->willReturn($date);
  255. $date->expects(static::once())
  256. ->method('format')
  257. ->with('Y-m-d 00:00:00')
  258. ->willReturn('2015-01-01 00:00:00');
  259. $searchResult = $this->getMockBuilder(PaymentTokenSearchResultsInterface::class)
  260. ->getMockForAbstractClass();
  261. $this->paymentTokenRepository->expects(self::once())
  262. ->method('getList')
  263. ->with($searchCriteria)
  264. ->willReturn($searchResult);
  265. $searchResult->expects(self::once())
  266. ->method('getItems')
  267. ->willReturn([$token]);
  268. static::assertEquals([$tokenUiComponent], $this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE));
  269. }
  270. /**
  271. * @param \Exception $exception
  272. * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents
  273. * @dataProvider getTokensComponentsGuestCustomerExceptionsProvider
  274. */
  275. public function testGetTokensComponentsGuestCustomerOrderNotFound($exception)
  276. {
  277. $customerId = null;
  278. $this->session->expects(static::once())
  279. ->method('getCustomerId')
  280. ->willReturn($customerId);
  281. $this->paymentDataHelper->expects(static::once())
  282. ->method('getMethodInstance')
  283. ->with(self::VAULT_PAYMENT_CODE)
  284. ->willReturn($this->vaultPayment);
  285. $this->vaultPayment->expects(static::once())
  286. ->method('isActive')
  287. ->with(self::STORE_ID)
  288. ->willReturn(true);
  289. $this->vaultPayment->expects(static::once())
  290. ->method('getProviderCode')
  291. ->willReturn(self::VAULT_PROVIDER_CODE);
  292. $this->session->expects(static::once())
  293. ->method('getReordered')
  294. ->willReturn(self::ORDER_ID);
  295. $this->orderRepository->expects(static::once())
  296. ->method('get')
  297. ->with(self::ORDER_ID)
  298. ->willThrowException($exception);
  299. $this->filterBuilder->expects(static::once())
  300. ->method('setField')
  301. ->with(PaymentTokenInterface::ENTITY_ID)
  302. ->willReturnSelf();
  303. $this->filterBuilder->expects(static::never())
  304. ->method('setValue');
  305. $this->searchCriteriaBuilder->expects(self::never())
  306. ->method('addFilters');
  307. static::assertEmpty($this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE));
  308. }
  309. /**
  310. * Set of catching exception types
  311. * @return array
  312. */
  313. public function getTokensComponentsGuestCustomerExceptionsProvider()
  314. {
  315. return [
  316. [new InputException()],
  317. [new NoSuchEntityException()],
  318. ];
  319. }
  320. /**
  321. * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents
  322. */
  323. public function testGetTokensComponentsEmptyComponentProvider()
  324. {
  325. $customerId = 1;
  326. $this->session->expects(static::once())
  327. ->method('getCustomerId')
  328. ->willReturn($customerId);
  329. $this->initStoreMock();
  330. $this->paymentDataHelper->expects(static::once())
  331. ->method('getMethodInstance')
  332. ->with(self::VAULT_PAYMENT_CODE)
  333. ->willReturn($this->vaultPayment);
  334. $this->vaultPayment->expects(static::once())
  335. ->method('isActive')
  336. ->with(self::STORE_ID)
  337. ->willReturn(false);
  338. $this->paymentTokenRepository->expects(static::never())
  339. ->method('getList');
  340. $configProvider = new TokensConfigProvider(
  341. $this->session,
  342. $this->paymentTokenRepository,
  343. $this->filterBuilder,
  344. $this->searchCriteriaBuilder,
  345. $this->storeManager,
  346. $this->dateTimeFactory
  347. );
  348. $this->objectManager->setBackwardCompatibleProperty(
  349. $configProvider,
  350. 'paymentDataHelper',
  351. $this->paymentDataHelper
  352. );
  353. static::assertEmpty($configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE));
  354. }
  355. /**
  356. * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents
  357. */
  358. public function testGetTokensComponentsForGuestCustomerWithoutStoredTokens()
  359. {
  360. $this->session->expects(static::once())
  361. ->method('getCustomerId')
  362. ->willReturn(null);
  363. $this->paymentDataHelper->expects(static::once())
  364. ->method('getMethodInstance')
  365. ->with(self::VAULT_PAYMENT_CODE)
  366. ->willReturn($this->vaultPayment);
  367. $this->vaultPayment->expects(static::once())
  368. ->method('isActive')
  369. ->with(self::STORE_ID)
  370. ->willReturn(true);
  371. $this->vaultPayment->expects(static::once())
  372. ->method('getProviderCode')
  373. ->willReturn(self::VAULT_PROVIDER_CODE);
  374. $this->session->expects(static::once())
  375. ->method('getReordered')
  376. ->willReturn(self::ORDER_ID);
  377. $this->orderRepository->expects(static::once())
  378. ->method('get')
  379. ->with(self::ORDER_ID)
  380. ->willReturn($this->getOrderMock());
  381. $this->paymentTokenManagement->expects(static::once())
  382. ->method('getByPaymentId')
  383. ->with(self::ORDER_PAYMENT_ENTITY_ID)
  384. ->willReturn(null);
  385. $this->filterBuilder->expects(static::once())
  386. ->method('setField')
  387. ->with(PaymentTokenInterface::ENTITY_ID)
  388. ->willReturnSelf();
  389. $this->filterBuilder->expects(static::never())
  390. ->method('setValue');
  391. $this->searchCriteriaBuilder->expects(static::never())
  392. ->method('addFilters');
  393. static::assertEmpty($this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE));
  394. }
  395. /**
  396. * Create mock object for store
  397. */
  398. private function initStoreMock()
  399. {
  400. $this->store = $this->createMock(StoreInterface::class);
  401. $this->store->expects(static::any())
  402. ->method('getId')
  403. ->willReturn(self::STORE_ID);
  404. $this->storeManager = $this->createMock(StoreManagerInterface::class);
  405. $this->storeManager->expects(static::any())
  406. ->method('getStore')
  407. ->with(null)
  408. ->willReturn($this->store);
  409. }
  410. /**
  411. * Returns order mock with order payment mock
  412. * @return OrderInterface
  413. */
  414. private function getOrderMock()
  415. {
  416. /** @var OrderInterface|MockObject $order */
  417. $order = $this->getMockBuilder(OrderInterface::class)
  418. ->getMockForAbstractClass();
  419. /** @var OrderPaymentInterface|MockObject $orderPayment */
  420. $orderPayment = $this->getMockBuilder(OrderPaymentInterface::class)
  421. ->getMockForAbstractClass();
  422. $order->expects(static::once())
  423. ->method('getPayment')
  424. ->willReturn($orderPayment);
  425. $orderPayment->expects(static::once())
  426. ->method('getEntityId')
  427. ->willReturn(self::ORDER_PAYMENT_ENTITY_ID);
  428. return $order;
  429. }
  430. /**
  431. * Get mock for token ui component provider
  432. * @param PaymentTokenInterface $token
  433. * @return TokenUiComponentInterface|MockObject
  434. */
  435. private function getTokenUiComponentProvider($token)
  436. {
  437. $tokenUiComponent = $this->createMock(TokenUiComponentInterface::class);
  438. $this->tokenComponentProvider->expects(static::once())
  439. ->method('getComponentForToken')
  440. ->with($token)
  441. ->willReturn($tokenUiComponent);
  442. return $tokenUiComponent;
  443. }
  444. /**
  445. * @param string $field
  446. * @param mixed $value
  447. * @param int $atIndex
  448. *
  449. * @return \PHPUnit_Framework_MockObject_MockObject
  450. */
  451. private function createExpectedFilter($field, $value, $atIndex)
  452. {
  453. $filterObject = $this->getMockBuilder(Filter::class)
  454. ->disableOriginalConstructor()
  455. ->getMock();
  456. $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex))
  457. ->method('setField')
  458. ->with($field)
  459. ->willReturnSelf();
  460. $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex))
  461. ->method('setValue')
  462. ->with($value)
  463. ->willReturnSelf();
  464. $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex))
  465. ->method('create')
  466. ->willReturn($filterObject);
  467. return $filterObject;
  468. }
  469. /**
  470. * Build search criteria
  471. * @param int $customerId
  472. * @param int $entityId
  473. * @param string $vaultProviderCode
  474. * @return \PHPUnit_Framework_MockObject_MockObject
  475. */
  476. private function getSearchCriteria($customerId, $entityId, $vaultProviderCode)
  477. {
  478. $searchCriteria = $this->getMockBuilder(SearchCriteria::class)
  479. ->disableOriginalConstructor()
  480. ->getMock();
  481. $customerFilter = $customerId ? $this->createExpectedFilter(PaymentTokenInterface::CUSTOMER_ID, $customerId, 0)
  482. : $this->createExpectedFilter(PaymentTokenInterface::ENTITY_ID, $entityId, 0);
  483. $codeFilter = $this->createExpectedFilter(
  484. PaymentTokenInterface::PAYMENT_METHOD_CODE,
  485. $vaultProviderCode,
  486. 1
  487. );
  488. $isActiveFilter = $this->createExpectedFilter(PaymentTokenInterface::IS_ACTIVE, 1, 2);
  489. // express at expectations
  490. $expiresAtFilter = $this->createExpectedFilter(
  491. PaymentTokenInterface::EXPIRES_AT,
  492. '2015-01-01 00:00:00',
  493. 3
  494. );
  495. $this->filterBuilder->expects(static::once())
  496. ->method('setConditionType')
  497. ->with('gt')
  498. ->willReturnSelf();
  499. $this->searchCriteriaBuilder->expects(self::exactly(4))
  500. ->method('addFilters')
  501. ->willReturnMap(
  502. [
  503. [$customerFilter, $this->searchCriteriaBuilder],
  504. [$codeFilter, $this->searchCriteriaBuilder],
  505. [$expiresAtFilter, $this->searchCriteriaBuilder],
  506. [$isActiveFilter, $this->searchCriteriaBuilder],
  507. ]
  508. );
  509. $this->searchCriteriaBuilder->expects(self::once())
  510. ->method('create')
  511. ->willReturn($searchCriteria);
  512. return $searchCriteria;
  513. }
  514. }