PlaceOrderTest.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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\Braintree\Controller\Paypal;
  8. use Braintree\Result\Successful;
  9. use Braintree\Transaction;
  10. use Magento\Braintree\Model\Adapter\BraintreeAdapter;
  11. use Magento\Braintree\Model\Adapter\BraintreeAdapterFactory;
  12. use Magento\Checkout\Model\Session;
  13. use Magento\Framework\Api\SearchCriteriaBuilder;
  14. use Magento\Framework\App\Request\Http as HttpRequest;
  15. use Magento\Framework\Message\MessageInterface;
  16. use Magento\Quote\Api\CartRepositoryInterface;
  17. use Magento\Quote\Api\Data\CartInterface;
  18. use Magento\Sales\Api\Data\OrderInterface;
  19. use Magento\Sales\Api\OrderRepositoryInterface;
  20. use Magento\TestFramework\TestCase\AbstractController;
  21. use PHPUnit\Framework\MockObject\MockObject;
  22. /**
  23. * PlaceOrderTest
  24. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  25. */
  26. class PlaceOrderTest extends AbstractController
  27. {
  28. /**
  29. * @var Session|MockObject
  30. */
  31. private $session;
  32. /**
  33. * @var BraintreeAdapter|MockObject
  34. */
  35. private $adapter;
  36. /**
  37. * @inheritdoc
  38. */
  39. protected function setUp()
  40. {
  41. parent::setUp();
  42. $this->session = $this->getMockBuilder(Session::class)
  43. ->disableOriginalConstructor()
  44. ->setMethods(['getQuote', 'setLastOrderStatus', 'unsLastBillingAgreementReferenceId'])
  45. ->getMock();
  46. $adapterFactory = $this->getMockBuilder(BraintreeAdapterFactory::class)
  47. ->disableOriginalConstructor()
  48. ->getMock();
  49. $this->adapter = $this->getMockBuilder(BraintreeAdapter::class)
  50. ->disableOriginalConstructor()
  51. ->getMock();
  52. $adapterFactory->method('create')
  53. ->willReturn($this->adapter);
  54. $this->_objectManager->addSharedInstance($this->session, Session::class);
  55. $this->_objectManager->addSharedInstance($adapterFactory, BraintreeAdapterFactory::class);
  56. }
  57. /**
  58. * @inheritdoc
  59. */
  60. protected function tearDown()
  61. {
  62. $this->_objectManager->removeSharedInstance(Session::class);
  63. $this->_objectManager->removeSharedInstance(BraintreeAdapterFactory::class);
  64. parent::tearDown();
  65. }
  66. /**
  67. * Tests a negative scenario for a place order flow when exception throws after placing an order.
  68. *
  69. * @magentoDataFixture Magento/Braintree/Fixtures/paypal_quote.php
  70. */
  71. public function testExecuteWithFailedOrder()
  72. {
  73. $reservedOrderId = 'test01';
  74. $quote = $this->getQuote($reservedOrderId);
  75. $this->session->method('getQuote')
  76. ->willReturn($quote);
  77. $this->adapter->method('sale')
  78. ->willReturn($this->getTransactionStub('authorized'));
  79. $this->adapter->method('void')
  80. ->willReturn($this->getTransactionStub('voided'));
  81. // emulates an error after placing the order
  82. $this->session->method('setLastOrderStatus')
  83. ->willThrowException(new \Exception('Test Exception'));
  84. $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
  85. $this->dispatch('braintree/paypal/placeOrder');
  86. self::assertRedirect(self::stringContains('checkout/cart'));
  87. self::assertSessionMessages(
  88. self::equalTo(['The order #' . $reservedOrderId . ' cannot be processed.']),
  89. MessageInterface::TYPE_ERROR
  90. );
  91. $order = $this->getOrder($reservedOrderId);
  92. self::assertEquals('canceled', $order->getState());
  93. }
  94. /**
  95. * Gets quote by reserved order ID.
  96. *
  97. * @param string $reservedOrderId
  98. * @return CartInterface
  99. */
  100. private function getQuote(string $reservedOrderId): CartInterface
  101. {
  102. $searchCriteria = $this->_objectManager->get(SearchCriteriaBuilder::class)
  103. ->addFilter('reserved_order_id', $reservedOrderId)
  104. ->create();
  105. /** @var CartRepositoryInterface $quoteRepository */
  106. $quoteRepository = $this->_objectManager->get(CartRepositoryInterface::class);
  107. $items = $quoteRepository->getList($searchCriteria)
  108. ->getItems();
  109. return array_pop($items);
  110. }
  111. /**
  112. * Gets order by increment ID.
  113. *
  114. * @param string $incrementId
  115. * @return OrderInterface
  116. */
  117. private function getOrder(string $incrementId): OrderInterface
  118. {
  119. $searchCriteria = $this->_objectManager->get(SearchCriteriaBuilder::class)
  120. ->addFilter('increment_id', $incrementId)
  121. ->create();
  122. /** @var OrderRepositoryInterface $repository */
  123. $repository = $this->_objectManager->get(OrderRepositoryInterface::class);
  124. $items = $repository->getList($searchCriteria)
  125. ->getItems();
  126. return array_pop($items);
  127. }
  128. /**
  129. * Creates stub for Braintree Transaction.
  130. *
  131. * @param string $status
  132. * @return Successful
  133. */
  134. private function getTransactionStub(string $status): Successful
  135. {
  136. $transaction = $this->getMockBuilder(Transaction::class)
  137. ->disableOriginalConstructor()
  138. ->getMock();
  139. $transaction->status = $status;
  140. $transaction->paypal = [
  141. 'paymentId' => 'pay-001',
  142. 'payerEmail' => 'test@test.com'
  143. ];
  144. $response = new Successful();
  145. $response->success = true;
  146. $response->transaction = $transaction;
  147. return $response;
  148. }
  149. }