<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Vault\Test\Unit\Model\Ui\Adminhtml; use Magento\Backend\Model\Session\Quote; use Magento\Framework\Api\Filter; use Magento\Framework\Api\FilterBuilder; use Magento\Framework\Api\SearchCriteria; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\Exception\InputException; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Intl\DateTimeFactory; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; use Magento\Framework\TestFramework\Unit\Matcher\MethodInvokedAtIndex; use Magento\Payment\Helper\Data; use Magento\Sales\Api\Data\OrderInterface; use Magento\Sales\Api\Data\OrderPaymentInterface; use Magento\Sales\Api\OrderRepositoryInterface; use Magento\Store\Api\Data\StoreInterface; use Magento\Store\Model\StoreManagerInterface; use Magento\Vault\Api\Data\PaymentTokenInterface; use Magento\Vault\Api\Data\PaymentTokenSearchResultsInterface; use Magento\Vault\Api\PaymentTokenManagementInterface; use Magento\Vault\Api\PaymentTokenRepositoryInterface; use Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider; use Magento\Vault\Model\Ui\TokenUiComponentInterface; use Magento\Vault\Model\Ui\TokenUiComponentProviderInterface; use Magento\Vault\Model\VaultPaymentInterface; use PHPUnit_Framework_MockObject_MockObject as MockObject; /** * Class TokensConfigProviderTest * * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class TokensConfigProviderTest extends \PHPUnit\Framework\TestCase { /**#@+ * Global values */ const STORE_ID = 1; const ORDER_ID = 2; const ORDER_PAYMENT_ENTITY_ID = 3; const ENTITY_ID = 4; const VAULT_PAYMENT_CODE = 'vault_payment'; const VAULT_PROVIDER_CODE = 'payment'; /**#@-*/ /** * @var PaymentTokenRepositoryInterface|MockObject */ private $paymentTokenRepository; /** * @var FilterBuilder|MockObject */ private $filterBuilder; /** * @var SearchCriteriaBuilder|MockObject */ private $searchCriteriaBuilder; /** * @var Quote|MockObject */ private $session; /** * @var StoreManagerInterface|MockObject */ private $storeManager; /** * @var StoreInterface|MockObject */ private $store; /** * @var DateTimeFactory|MockObject */ private $dateTimeFactory; /** * @var Data|MockObject */ private $paymentDataHelper; /** * @var VaultPaymentInterface|MockObject */ private $vaultPayment; /** * @var PaymentTokenManagementInterface|MockObject */ private $paymentTokenManagement; /** * @var OrderRepositoryInterface|MockObject */ private $orderRepository; /** * @var TokenUiComponentProviderInterface|MockObject */ private $tokenComponentProvider; /** * @var ObjectManager */ private $objectManager; /** * @var TokensConfigProvider */ private $configProvider; protected function setUp() { $this->paymentTokenRepository = $this->getMockBuilder(PaymentTokenRepositoryInterface::class) ->getMockForAbstractClass(); $this->filterBuilder = $this->getMockBuilder(FilterBuilder::class) ->disableOriginalConstructor() ->getMock(); $this->searchCriteriaBuilder = $this->getMockBuilder(SearchCriteriaBuilder::class) ->disableOriginalConstructor() ->getMock(); $this->session = $this->getMockBuilder(Quote::class) ->disableOriginalConstructor() ->setMethods(['getCustomerId', 'getReordered']) ->getMock(); $this->dateTimeFactory = $this->getMockBuilder(DateTimeFactory::class) ->disableOriginalConstructor() ->getMock(); $this->paymentDataHelper = $this->getMockBuilder(Data::class) ->disableOriginalConstructor() ->setMethods(['getMethodInstance']) ->getMock(); $this->paymentTokenManagement = $this->getMockBuilder(PaymentTokenManagementInterface::class) ->getMockForAbstractClass(); $this->orderRepository = $this->getMockBuilder(OrderRepositoryInterface::class) ->getMockForAbstractClass(); $this->vaultPayment = $this->getMockForAbstractClass(VaultPaymentInterface::class); $this->objectManager = new ObjectManager($this); $this->initStoreMock(); $this->tokenComponentProvider = $this->createMock(TokenUiComponentProviderInterface::class); $this->configProvider = new TokensConfigProvider( $this->session, $this->paymentTokenRepository, $this->filterBuilder, $this->searchCriteriaBuilder, $this->storeManager, $this->dateTimeFactory, [ self::VAULT_PROVIDER_CODE => $this->tokenComponentProvider ] ); $this->objectManager->setBackwardCompatibleProperty( $this->configProvider, 'paymentDataHelper', $this->paymentDataHelper ); $this->objectManager->setBackwardCompatibleProperty( $this->configProvider, 'paymentTokenManagement', $this->paymentTokenManagement ); $this->objectManager->setBackwardCompatibleProperty( $this->configProvider, 'orderRepository', $this->orderRepository ); } /** * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents */ public function testGetTokensComponentsRegisteredCustomer() { $customerId = 1; $this->session->expects(static::once()) ->method('getCustomerId') ->willReturn($customerId); $this->paymentDataHelper->expects(static::once()) ->method('getMethodInstance') ->with(self::VAULT_PAYMENT_CODE) ->willReturn($this->vaultPayment); $this->vaultPayment->expects(static::once()) ->method('isActive') ->with(self::STORE_ID) ->willReturn(true); $this->vaultPayment->expects(static::once()) ->method('getProviderCode') ->willReturn(self::VAULT_PROVIDER_CODE); /** @var PaymentTokenInterface|MockObject $token */ $token = $this->getMockBuilder(PaymentTokenInterface::class) ->getMockForAbstractClass(); $tokenUiComponent = $this->getTokenUiComponentProvider($token); $searchCriteria = $this->getSearchCriteria($customerId, self::ENTITY_ID, self::VAULT_PROVIDER_CODE); $date = $this->getMockBuilder(\DateTime::class) ->disableOriginalConstructor() ->getMock(); $this->dateTimeFactory->expects(static::once()) ->method('create') ->with("now", new \DateTimeZone('UTC')) ->willReturn($date); $date->expects(static::once()) ->method('format') ->with('Y-m-d 00:00:00') ->willReturn('2015-01-01 00:00:00'); $searchResult = $this->getMockBuilder(PaymentTokenSearchResultsInterface::class) ->getMockForAbstractClass(); $this->paymentTokenRepository->expects(self::once()) ->method('getList') ->with($searchCriteria) ->willReturn($searchResult); $searchResult->expects(self::once()) ->method('getItems') ->willReturn([$token]); static::assertEquals([$tokenUiComponent], $this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE)); } /** * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents */ public function testGetTokensComponentsGuestCustomer() { $customerId = null; $this->initStoreMock(); $this->session->expects(static::once()) ->method('getCustomerId') ->willReturn($customerId); $this->paymentDataHelper->expects(static::once()) ->method('getMethodInstance') ->with(self::VAULT_PAYMENT_CODE) ->willReturn($this->vaultPayment); $this->vaultPayment->expects(static::once()) ->method('isActive') ->with(self::STORE_ID) ->willReturn(true); $this->vaultPayment->expects(static::once()) ->method('getProviderCode') ->willReturn(self::VAULT_PROVIDER_CODE); /** @var PaymentTokenInterface|MockObject $token */ $token = $this->getMockBuilder(PaymentTokenInterface::class) ->getMockForAbstractClass(); $this->session->expects(static::once()) ->method('getReordered') ->willReturn(self::ORDER_ID); $this->orderRepository->expects(static::once()) ->method('get') ->with(self::ORDER_ID) ->willReturn($this->getOrderMock()); $this->paymentTokenManagement->expects(static::once()) ->method('getByPaymentId') ->with(self::ORDER_PAYMENT_ENTITY_ID) ->willReturn($token); $token->expects(static::once()) ->method('getEntityId') ->willReturn(self::ENTITY_ID); $tokenUiComponent = $this->getTokenUiComponentProvider($token); $searchCriteria = $this->getSearchCriteria($customerId, self::ENTITY_ID, self::VAULT_PROVIDER_CODE); $date = $this->getMockBuilder('DateTime') ->disableOriginalConstructor() ->getMock(); $this->dateTimeFactory->expects(static::once()) ->method('create') ->with("now", new \DateTimeZone('UTC')) ->willReturn($date); $date->expects(static::once()) ->method('format') ->with('Y-m-d 00:00:00') ->willReturn('2015-01-01 00:00:00'); $searchResult = $this->getMockBuilder(PaymentTokenSearchResultsInterface::class) ->getMockForAbstractClass(); $this->paymentTokenRepository->expects(self::once()) ->method('getList') ->with($searchCriteria) ->willReturn($searchResult); $searchResult->expects(self::once()) ->method('getItems') ->willReturn([$token]); static::assertEquals([$tokenUiComponent], $this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE)); } /** * @param \Exception $exception * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents * @dataProvider getTokensComponentsGuestCustomerExceptionsProvider */ public function testGetTokensComponentsGuestCustomerOrderNotFound($exception) { $customerId = null; $this->session->expects(static::once()) ->method('getCustomerId') ->willReturn($customerId); $this->paymentDataHelper->expects(static::once()) ->method('getMethodInstance') ->with(self::VAULT_PAYMENT_CODE) ->willReturn($this->vaultPayment); $this->vaultPayment->expects(static::once()) ->method('isActive') ->with(self::STORE_ID) ->willReturn(true); $this->vaultPayment->expects(static::once()) ->method('getProviderCode') ->willReturn(self::VAULT_PROVIDER_CODE); $this->session->expects(static::once()) ->method('getReordered') ->willReturn(self::ORDER_ID); $this->orderRepository->expects(static::once()) ->method('get') ->with(self::ORDER_ID) ->willThrowException($exception); $this->filterBuilder->expects(static::once()) ->method('setField') ->with(PaymentTokenInterface::ENTITY_ID) ->willReturnSelf(); $this->filterBuilder->expects(static::never()) ->method('setValue'); $this->searchCriteriaBuilder->expects(self::never()) ->method('addFilters'); static::assertEmpty($this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE)); } /** * Set of catching exception types * @return array */ public function getTokensComponentsGuestCustomerExceptionsProvider() { return [ [new InputException()], [new NoSuchEntityException()], ]; } /** * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents */ public function testGetTokensComponentsEmptyComponentProvider() { $customerId = 1; $this->session->expects(static::once()) ->method('getCustomerId') ->willReturn($customerId); $this->initStoreMock(); $this->paymentDataHelper->expects(static::once()) ->method('getMethodInstance') ->with(self::VAULT_PAYMENT_CODE) ->willReturn($this->vaultPayment); $this->vaultPayment->expects(static::once()) ->method('isActive') ->with(self::STORE_ID) ->willReturn(false); $this->paymentTokenRepository->expects(static::never()) ->method('getList'); $configProvider = new TokensConfigProvider( $this->session, $this->paymentTokenRepository, $this->filterBuilder, $this->searchCriteriaBuilder, $this->storeManager, $this->dateTimeFactory ); $this->objectManager->setBackwardCompatibleProperty( $configProvider, 'paymentDataHelper', $this->paymentDataHelper ); static::assertEmpty($configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE)); } /** * @covers \Magento\Vault\Model\Ui\Adminhtml\TokensConfigProvider::getTokensComponents */ public function testGetTokensComponentsForGuestCustomerWithoutStoredTokens() { $this->session->expects(static::once()) ->method('getCustomerId') ->willReturn(null); $this->paymentDataHelper->expects(static::once()) ->method('getMethodInstance') ->with(self::VAULT_PAYMENT_CODE) ->willReturn($this->vaultPayment); $this->vaultPayment->expects(static::once()) ->method('isActive') ->with(self::STORE_ID) ->willReturn(true); $this->vaultPayment->expects(static::once()) ->method('getProviderCode') ->willReturn(self::VAULT_PROVIDER_CODE); $this->session->expects(static::once()) ->method('getReordered') ->willReturn(self::ORDER_ID); $this->orderRepository->expects(static::once()) ->method('get') ->with(self::ORDER_ID) ->willReturn($this->getOrderMock()); $this->paymentTokenManagement->expects(static::once()) ->method('getByPaymentId') ->with(self::ORDER_PAYMENT_ENTITY_ID) ->willReturn(null); $this->filterBuilder->expects(static::once()) ->method('setField') ->with(PaymentTokenInterface::ENTITY_ID) ->willReturnSelf(); $this->filterBuilder->expects(static::never()) ->method('setValue'); $this->searchCriteriaBuilder->expects(static::never()) ->method('addFilters'); static::assertEmpty($this->configProvider->getTokensComponents(self::VAULT_PAYMENT_CODE)); } /** * Create mock object for store */ private function initStoreMock() { $this->store = $this->createMock(StoreInterface::class); $this->store->expects(static::any()) ->method('getId') ->willReturn(self::STORE_ID); $this->storeManager = $this->createMock(StoreManagerInterface::class); $this->storeManager->expects(static::any()) ->method('getStore') ->with(null) ->willReturn($this->store); } /** * Returns order mock with order payment mock * @return OrderInterface */ private function getOrderMock() { /** @var OrderInterface|MockObject $order */ $order = $this->getMockBuilder(OrderInterface::class) ->getMockForAbstractClass(); /** @var OrderPaymentInterface|MockObject $orderPayment */ $orderPayment = $this->getMockBuilder(OrderPaymentInterface::class) ->getMockForAbstractClass(); $order->expects(static::once()) ->method('getPayment') ->willReturn($orderPayment); $orderPayment->expects(static::once()) ->method('getEntityId') ->willReturn(self::ORDER_PAYMENT_ENTITY_ID); return $order; } /** * Get mock for token ui component provider * @param PaymentTokenInterface $token * @return TokenUiComponentInterface|MockObject */ private function getTokenUiComponentProvider($token) { $tokenUiComponent = $this->createMock(TokenUiComponentInterface::class); $this->tokenComponentProvider->expects(static::once()) ->method('getComponentForToken') ->with($token) ->willReturn($tokenUiComponent); return $tokenUiComponent; } /** * @param string $field * @param mixed $value * @param int $atIndex * * @return \PHPUnit_Framework_MockObject_MockObject */ private function createExpectedFilter($field, $value, $atIndex) { $filterObject = $this->getMockBuilder(Filter::class) ->disableOriginalConstructor() ->getMock(); $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex)) ->method('setField') ->with($field) ->willReturnSelf(); $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex)) ->method('setValue') ->with($value) ->willReturnSelf(); $this->filterBuilder->expects(new MethodInvokedAtIndex($atIndex)) ->method('create') ->willReturn($filterObject); return $filterObject; } /** * Build search criteria * @param int $customerId * @param int $entityId * @param string $vaultProviderCode * @return \PHPUnit_Framework_MockObject_MockObject */ private function getSearchCriteria($customerId, $entityId, $vaultProviderCode) { $searchCriteria = $this->getMockBuilder(SearchCriteria::class) ->disableOriginalConstructor() ->getMock(); $customerFilter = $customerId ? $this->createExpectedFilter(PaymentTokenInterface::CUSTOMER_ID, $customerId, 0) : $this->createExpectedFilter(PaymentTokenInterface::ENTITY_ID, $entityId, 0); $codeFilter = $this->createExpectedFilter( PaymentTokenInterface::PAYMENT_METHOD_CODE, $vaultProviderCode, 1 ); $isActiveFilter = $this->createExpectedFilter(PaymentTokenInterface::IS_ACTIVE, 1, 2); // express at expectations $expiresAtFilter = $this->createExpectedFilter( PaymentTokenInterface::EXPIRES_AT, '2015-01-01 00:00:00', 3 ); $this->filterBuilder->expects(static::once()) ->method('setConditionType') ->with('gt') ->willReturnSelf(); $this->searchCriteriaBuilder->expects(self::exactly(4)) ->method('addFilters') ->willReturnMap( [ [$customerFilter, $this->searchCriteriaBuilder], [$codeFilter, $this->searchCriteriaBuilder], [$expiresAtFilter, $this->searchCriteriaBuilder], [$isActiveFilter, $this->searchCriteriaBuilder], ] ); $this->searchCriteriaBuilder->expects(self::once()) ->method('create') ->willReturn($searchCriteria); return $searchCriteria; } }