IndexTest.php 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  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\Checkout\Test\Unit\Controller\Index;
  8. use Magento\Customer\Model\Session;
  9. use Magento\Framework\App\Request\Http;
  10. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  11. use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMocker;
  12. use PHPUnit\Framework\MockObject\Matcher\InvokedCount as InvokedCount;
  13. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  14. use Magento\Checkout\Helper\Data;
  15. use Magento\Quote\Model\Quote;
  16. use Magento\Framework\View\Result\Page;
  17. use Magento\Checkout\Controller\Index\Index;
  18. use Magento\Framework\ObjectManagerInterface;
  19. /**
  20. * @SuppressWarnings(PHPMD.TooManyFields)
  21. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  22. */
  23. class IndexTest extends \PHPUnit\Framework\TestCase
  24. {
  25. /**
  26. * @var ObjectManager
  27. */
  28. private $objectManager;
  29. /**
  30. * @var MockObject
  31. */
  32. private $objectManagerMock;
  33. /**
  34. * @var Data|MockObject
  35. */
  36. private $data;
  37. /**
  38. * @var MockObject
  39. */
  40. private $quote;
  41. /**
  42. * @var MockObject
  43. */
  44. private $contextMock;
  45. /**
  46. * @var Session|MockObject
  47. */
  48. private $session;
  49. /**
  50. * @var MockObject
  51. */
  52. private $onepageMock;
  53. /**
  54. * @var MockObject
  55. */
  56. private $layoutMock;
  57. /**
  58. * @var Http|MockObject
  59. */
  60. private $request;
  61. /**
  62. * @var MockObject
  63. */
  64. private $responseMock;
  65. /**
  66. * @var MockObject
  67. */
  68. private $redirectMock;
  69. /**
  70. * @var Index
  71. */
  72. private $model;
  73. /**
  74. * @var Page|MockObject
  75. */
  76. private $resultPage;
  77. /**
  78. * @var \Magento\Framework\View\Page\Config
  79. */
  80. private $pageConfigMock;
  81. /**
  82. * @var \Magento\Framework\View\Page\Title
  83. */
  84. private $titleMock;
  85. /**
  86. * @var \Magento\Framework\UrlInterface
  87. */
  88. private $url;
  89. /**
  90. * @var \Magento\Framework\Controller\Result\Redirect|MockObject
  91. */
  92. private $resultRedirectMock;
  93. protected function setUp()
  94. {
  95. // mock objects
  96. $this->objectManager = new ObjectManager($this);
  97. $this->objectManagerMock = $this->basicMock(ObjectManagerInterface::class);
  98. $this->data = $this->basicMock(Data::class);
  99. $this->quote = $this->createPartialMock(
  100. Quote::class,
  101. ['getHasError', 'hasItems', 'validateMinimumAmount', 'hasError']
  102. );
  103. $this->contextMock = $this->basicMock(\Magento\Framework\App\Action\Context::class);
  104. $this->session = $this->basicMock(Session::class);
  105. $this->onepageMock = $this->basicMock(\Magento\Checkout\Model\Type\Onepage::class);
  106. $this->layoutMock = $this->basicMock(\Magento\Framework\View\Layout::class);
  107. $this->request = $this->getMockBuilder(Http::class)
  108. ->disableOriginalConstructor()
  109. ->setMethods(['isSecure', 'getHeader'])
  110. ->getMock();
  111. $this->responseMock = $this->basicMock(\Magento\Framework\App\ResponseInterface::class);
  112. $this->redirectMock = $this->basicMock(\Magento\Framework\App\Response\RedirectInterface::class);
  113. $this->resultPage = $this->basicMock(Page::class);
  114. $this->pageConfigMock = $this->basicMock(\Magento\Framework\View\Page\Config::class);
  115. $this->titleMock = $this->basicMock(\Magento\Framework\View\Page\Title::class);
  116. $this->url = $this->createMock(\Magento\Framework\UrlInterface::class);
  117. $this->resultRedirectMock = $this->basicMock(\Magento\Framework\Controller\Result\Redirect::class);
  118. $resultPageFactoryMock = $this->getMockBuilder(\Magento\Framework\View\Result\PageFactory::class)
  119. ->disableOriginalConstructor()
  120. ->setMethods(['create'])
  121. ->getMock();
  122. $resultPageFactoryMock->expects($this->any())
  123. ->method('create')
  124. ->willReturn($this->resultPage);
  125. $resultRedirectFactoryMock = $this->getMockBuilder(\Magento\Framework\Controller\Result\RedirectFactory::class)
  126. ->disableOriginalConstructor()
  127. ->setMethods(['create'])
  128. ->getMock();
  129. $resultRedirectFactoryMock->expects($this->any())
  130. ->method('create')
  131. ->willReturn($this->resultRedirectMock);
  132. // stubs
  133. $this->basicStub($this->onepageMock, 'getQuote')->willReturn($this->quote);
  134. $this->basicStub($this->resultPage, 'getLayout')->willReturn($this->layoutMock);
  135. $this->basicStub($this->layoutMock, 'getBlock')
  136. ->willReturn($this->basicMock(\Magento\Theme\Block\Html\Header::class));
  137. $this->basicStub($this->resultPage, 'getConfig')->willReturn($this->pageConfigMock);
  138. $this->basicStub($this->pageConfigMock, 'getTitle')->willReturn($this->titleMock);
  139. $this->basicStub($this->titleMock, 'set')->willReturn($this->titleMock);
  140. // objectManagerMock
  141. $objectManagerReturns = [
  142. [Data::class, $this->data],
  143. [\Magento\Checkout\Model\Type\Onepage::class, $this->onepageMock],
  144. [\Magento\Checkout\Model\Session::class, $this->basicMock(\Magento\Checkout\Model\Session::class)],
  145. [Session::class, $this->basicMock(Session::class)],
  146. ];
  147. $this->objectManagerMock->expects($this->any())
  148. ->method('get')
  149. ->will($this->returnValueMap($objectManagerReturns));
  150. $this->basicStub($this->objectManagerMock, 'create')
  151. ->willReturn($this->basicMock(\Magento\Framework\UrlInterface::class));
  152. // context stubs
  153. $this->basicStub($this->contextMock, 'getObjectManager')->willReturn($this->objectManagerMock);
  154. $this->basicStub($this->contextMock, 'getRequest')->willReturn($this->request);
  155. $this->basicStub($this->contextMock, 'getResponse')->willReturn($this->responseMock);
  156. $this->basicStub($this->contextMock, 'getMessageManager')
  157. ->willReturn($this->basicMock(\Magento\Framework\Message\ManagerInterface::class));
  158. $this->basicStub($this->contextMock, 'getRedirect')->willReturn($this->redirectMock);
  159. $this->basicStub($this->contextMock, 'getUrl')->willReturn($this->url);
  160. $this->basicStub($this->contextMock, 'getResultRedirectFactory')->willReturn($resultRedirectFactoryMock);
  161. // SUT
  162. $this->model = $this->objectManager->getObject(
  163. Index::class,
  164. [
  165. 'context' => $this->contextMock,
  166. 'customerSession' => $this->session,
  167. 'resultPageFactory' => $resultPageFactoryMock,
  168. 'resultRedirectFactory' => $resultRedirectFactoryMock
  169. ]
  170. );
  171. }
  172. /**
  173. * Checks a case when session should be or not regenerated during the request.
  174. *
  175. * @param bool $secure
  176. * @param string $referer
  177. * @param InvokedCount $expectedCall
  178. * @dataProvider sessionRegenerationDataProvider
  179. */
  180. public function testRegenerateSessionIdOnExecute(bool $secure, string $referer, InvokedCount $expectedCall)
  181. {
  182. $this->data->method('canOnepageCheckout')
  183. ->willReturn(true);
  184. $this->quote->method('hasItems')
  185. ->willReturn(true);
  186. $this->quote->method('getHasError')
  187. ->willReturn(false);
  188. $this->quote->method('validateMinimumAmount')
  189. ->willReturn(true);
  190. $this->session->method('isLoggedIn')
  191. ->willReturn(true);
  192. $this->request->method('isSecure')
  193. ->willReturn($secure);
  194. $this->request->method('getHeader')
  195. ->with('referer')
  196. ->willReturn($referer);
  197. $this->session->expects($expectedCall)
  198. ->method('regenerateId');
  199. $this->assertSame($this->resultPage, $this->model->execute());
  200. }
  201. /**
  202. * Gets list of variations for generating new session.
  203. *
  204. * @return array
  205. */
  206. public function sessionRegenerationDataProvider(): array
  207. {
  208. return [
  209. [
  210. 'secure' => false,
  211. 'referer' => 'https://test.domain.com/',
  212. 'expectedCall' => self::once()
  213. ],
  214. [
  215. 'secure' => true,
  216. 'referer' => false,
  217. 'expectedCall' => self::once()
  218. ],
  219. [
  220. 'secure' => true,
  221. 'referer' => 'http://test.domain.com/',
  222. 'expectedCall' => self::once()
  223. ],
  224. // This is the only case in which session regeneration can be skipped
  225. [
  226. 'secure' => true,
  227. 'referer' => 'https://test.domain.com/',
  228. 'expectedCall' => self::never()
  229. ],
  230. ];
  231. }
  232. public function testOnepageCheckoutNotAvailable()
  233. {
  234. $this->basicStub($this->data, 'canOnepageCheckout')->willReturn(false);
  235. $expectedPath = 'checkout/cart';
  236. $this->resultRedirectMock->expects($this->once())
  237. ->method('setPath')
  238. ->with($expectedPath)
  239. ->willReturnSelf();
  240. $this->assertSame($this->resultRedirectMock, $this->model->execute());
  241. }
  242. public function testInvalidQuote()
  243. {
  244. $this->basicStub($this->quote, 'hasError')->willReturn(true);
  245. $expectedPath = 'checkout/cart';
  246. $this->resultRedirectMock->expects($this->once())
  247. ->method('setPath')
  248. ->with($expectedPath)
  249. ->willReturnSelf();
  250. $this->assertSame($this->resultRedirectMock, $this->model->execute());
  251. }
  252. /**
  253. * @param MockObject $mock
  254. * @param string $method
  255. *
  256. * @return InvocationMocker
  257. */
  258. private function basicStub($mock, $method): InvocationMocker
  259. {
  260. return $mock->method($method)
  261. ->withAnyParameters();
  262. }
  263. /**
  264. * @param string $className
  265. * @return MockObject
  266. */
  267. private function basicMock(string $className): MockObject
  268. {
  269. return $this->getMockBuilder($className)
  270. ->disableOriginalConstructor()
  271. ->getMock();
  272. }
  273. }