LoginTest.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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\Customer\Test\Unit\Controller\Ajax;
  8. use Magento\Customer\Api\Data\CustomerInterface;
  9. use Magento\Customer\Controller\Ajax\Login;
  10. use Magento\Customer\Model\Account\Redirect;
  11. use Magento\Customer\Model\AccountManagement;
  12. use Magento\Customer\Model\Session;
  13. use Magento\Framework\App\Action\Context;
  14. use Magento\Framework\App\Config\ScopeConfigInterface;
  15. use Magento\Framework\App\Request\Http;
  16. use Magento\Framework\App\Response\RedirectInterface;
  17. use Magento\Framework\App\ResponseInterface;
  18. use Magento\Framework\Controller\Result\Json;
  19. use Magento\Framework\Controller\Result\JsonFactory;
  20. use Magento\Framework\Controller\Result\Raw;
  21. use Magento\Framework\Controller\Result\RawFactory;
  22. use Magento\Framework\Exception\InvalidEmailOrPasswordException;
  23. use Magento\Framework\Json\Helper\Data;
  24. use Magento\Framework\ObjectManager\ObjectManager as FakeObjectManager;
  25. use Magento\Framework\Stdlib\Cookie\CookieMetadata;
  26. use Magento\Framework\Stdlib\Cookie\CookieMetadataFactory;
  27. use Magento\Framework\Stdlib\CookieManagerInterface;
  28. use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
  29. use PHPUnit_Framework_MockObject_MockObject as MockObject;
  30. /**
  31. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  32. */
  33. class LoginTest extends \PHPUnit\Framework\TestCase
  34. {
  35. /**
  36. * @var Login
  37. */
  38. private $controller;
  39. /**
  40. * @var Http|MockObject
  41. */
  42. private $request;
  43. /**
  44. * @var ResponseInterface|MockObject
  45. */
  46. private $response;
  47. /**
  48. * @var Session|MockObject
  49. */
  50. private $customerSession;
  51. /**
  52. * @var FakeObjectManager|MockObject
  53. */
  54. private $objectManager;
  55. /**
  56. * @var AccountManagement|MockObject
  57. */
  58. private $accountManagement;
  59. /**
  60. * @var Data|MockObject
  61. */
  62. private $jsonHelper;
  63. /**
  64. * @var Json|MockObject
  65. */
  66. private $resultJson;
  67. /**
  68. * @var JsonFactory|MockObject
  69. */
  70. private $resultJsonFactory;
  71. /**
  72. * @var Raw|MockObject
  73. */
  74. private $resultRaw;
  75. /**
  76. * @var RedirectInterface|MockObject
  77. */
  78. private $redirect;
  79. /**
  80. * @var CookieManagerInterface|MockObject
  81. */
  82. private $cookieManager;
  83. /**
  84. * @var CookieMetadataFactory|MockObject
  85. */
  86. private $cookieMetadataFactory;
  87. /**
  88. * @inheritdoc
  89. */
  90. protected function setUp(): void
  91. {
  92. $this->request = $this->getMockBuilder(Http::class)
  93. ->disableOriginalConstructor()
  94. ->getMock();
  95. $this->response = $this->createPartialMock(
  96. ResponseInterface::class,
  97. ['setRedirect', 'sendResponse', 'representJson', 'setHttpResponseCode']
  98. );
  99. $this->customerSession = $this->createPartialMock(
  100. Session::class,
  101. [
  102. 'isLoggedIn',
  103. 'getLastCustomerId',
  104. 'getBeforeAuthUrl',
  105. 'setBeforeAuthUrl',
  106. 'setCustomerDataAsLoggedIn',
  107. 'regenerateId',
  108. 'getData'
  109. ]
  110. );
  111. $this->objectManager = $this->createPartialMock(FakeObjectManager::class, ['get']);
  112. $this->accountManagement = $this->createPartialMock(AccountManagement::class, ['authenticate']);
  113. $this->jsonHelper = $this->createPartialMock(Data::class, ['jsonDecode']);
  114. $this->resultJson = $this->getMockBuilder(Json::class)
  115. ->disableOriginalConstructor()
  116. ->getMock();
  117. $this->resultJsonFactory = $this->getMockBuilder(JsonFactory::class)
  118. ->disableOriginalConstructor()
  119. ->setMethods(['create'])
  120. ->getMock();
  121. $this->cookieManager = $this->getMockBuilder(CookieManagerInterface::class)
  122. ->setMethods(['getCookie', 'deleteCookie'])
  123. ->getMockForAbstractClass();
  124. $this->cookieMetadataFactory = $this->getMockBuilder(CookieMetadataFactory::class)
  125. ->disableOriginalConstructor()
  126. ->getMock();
  127. $this->resultRaw = $this->getMockBuilder(Raw::class)
  128. ->disableOriginalConstructor()
  129. ->getMock();
  130. $resultRawFactory = $this->getMockBuilder(RawFactory::class)
  131. ->disableOriginalConstructor()
  132. ->setMethods(['create'])
  133. ->getMock();
  134. $resultRawFactory->method('create')
  135. ->willReturn($this->resultRaw);
  136. /** @var Context|MockObject $context */
  137. $context = $this->createMock(Context::class);
  138. $this->redirect = $this->createMock(RedirectInterface::class);
  139. $context->method('getRedirect')
  140. ->willReturn($this->redirect);
  141. $context->method('getRequest')
  142. ->willReturn($this->request);
  143. $objectManager = new ObjectManager($this);
  144. $this->controller = $objectManager->getObject(
  145. Login::class,
  146. [
  147. 'context' => $context,
  148. 'customerSession' => $this->customerSession,
  149. 'helper' => $this->jsonHelper,
  150. 'response' => $this->response,
  151. 'resultRawFactory' => $resultRawFactory,
  152. 'resultJsonFactory' => $this->resultJsonFactory,
  153. 'objectManager' => $this->objectManager,
  154. 'customerAccountManagement' => $this->accountManagement,
  155. 'cookieManager' => $this->cookieManager,
  156. 'cookieMetadataFactory' => $this->cookieMetadataFactory
  157. ]
  158. );
  159. }
  160. /**
  161. * Checks successful login.
  162. */
  163. public function testLogin(): void
  164. {
  165. $jsonRequest = '{"username":"customer@example.com", "password":"password"}';
  166. $loginSuccessResponse = '{"errors": false, "message":"Login successful."}';
  167. $this->withRequest($jsonRequest);
  168. $this->resultJsonFactory->method('create')
  169. ->willReturn($this->resultJson);
  170. $this->jsonHelper->method('jsonDecode')
  171. ->with($jsonRequest)
  172. ->willReturn(['username' => 'customer@example.com', 'password' => 'password']);
  173. /** @var CustomerInterface|MockObject $customer */
  174. $customer = $this->getMockForAbstractClass(CustomerInterface::class);
  175. $this->accountManagement->method('authenticate')
  176. ->with('customer@example.com', 'password')
  177. ->willReturn($customer);
  178. $this->customerSession->method('setCustomerDataAsLoggedIn')
  179. ->with($customer);
  180. $this->customerSession->method('regenerateId');
  181. /** @var Redirect|MockObject $redirect */
  182. $redirect = $this->createMock(Redirect::class);
  183. $this->controller->setAccountRedirect($redirect);
  184. $redirect->method('getRedirectCookie')
  185. ->willReturn('some_url1');
  186. $this->withCookieManager();
  187. $this->withScopeConfig();
  188. $this->redirect->method('success')
  189. ->willReturn('some_url2');
  190. $this->resultRaw->expects(self::never())
  191. ->method('setHttpResponseCode');
  192. $result = [
  193. 'errors' => false,
  194. 'message' => __('Login successful.'),
  195. 'redirectUrl' => 'some_url2',
  196. ];
  197. $this->resultJson->method('setData')
  198. ->with($result)
  199. ->willReturn($loginSuccessResponse);
  200. self::assertEquals($loginSuccessResponse, $this->controller->execute());
  201. }
  202. /**
  203. * Checks unsuccessful login.
  204. */
  205. public function testLoginFailure(): void
  206. {
  207. $jsonRequest = '{"username":"invalid@example.com", "password":"invalid"}';
  208. $loginFailureResponse = '{"message":"Invalid login or password."}';
  209. $this->withRequest($jsonRequest);
  210. $this->resultJsonFactory->method('create')
  211. ->willReturn($this->resultJson);
  212. $this->jsonHelper->method('jsonDecode')
  213. ->with($jsonRequest)
  214. ->willReturn(['username' => 'invalid@example.com', 'password' => 'invalid']);
  215. /** @var CustomerInterface|MockObject $customer */
  216. $customer = $this->getMockForAbstractClass(CustomerInterface::class);
  217. $this->accountManagement->method('authenticate')
  218. ->with('invalid@example.com', 'invalid')
  219. ->willThrowException(new InvalidEmailOrPasswordException(__('Invalid login or password.')));
  220. $this->customerSession->expects(self::never())
  221. ->method('setCustomerDataAsLoggedIn')
  222. ->with($customer);
  223. $this->customerSession->expects(self::never())
  224. ->method('regenerateId');
  225. $result = [
  226. 'errors' => true,
  227. 'message' => __('Invalid login or password.')
  228. ];
  229. $this->resultJson->method('setData')
  230. ->with($result)
  231. ->willReturn($loginFailureResponse);
  232. self::assertEquals($loginFailureResponse, $this->controller->execute());
  233. }
  234. /**
  235. * Emulates request behavior.
  236. *
  237. * @param string $jsonRequest
  238. */
  239. private function withRequest(string $jsonRequest): void
  240. {
  241. $this->request->method('getContent')
  242. ->willReturn($jsonRequest);
  243. $this->request->method('getMethod')
  244. ->willReturn('POST');
  245. $this->request->method('isXmlHttpRequest')
  246. ->willReturn(true);
  247. }
  248. /**
  249. * Emulates cookie manager behavior.
  250. */
  251. private function withCookieManager(): void
  252. {
  253. $this->cookieManager->method('getCookie')
  254. ->with('mage-cache-sessid')
  255. ->willReturn(true);
  256. $cookieMetadata = $this->getMockBuilder(CookieMetadata::class)
  257. ->disableOriginalConstructor()
  258. ->getMock();
  259. $this->cookieMetadataFactory->method('createCookieMetadata')
  260. ->willReturn($cookieMetadata);
  261. $cookieMetadata->method('setPath')
  262. ->with('/')
  263. ->willReturnSelf();
  264. $this->cookieManager->method('deleteCookie')
  265. ->with('mage-cache-sessid', $cookieMetadata)
  266. ->willReturnSelf();
  267. }
  268. /**
  269. * Emulates config behavior.
  270. */
  271. private function withScopeConfig(): void
  272. {
  273. /** @var ScopeConfigInterface|MockObject $scopeConfig */
  274. $scopeConfig = $this->createMock(ScopeConfigInterface::class);
  275. $this->controller->setScopeConfig($scopeConfig);
  276. $scopeConfig->method('getValue')
  277. ->with('customer/startup/redirect_dashboard')
  278. ->willReturn(0);
  279. }
  280. }