AccountTest.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Controller;
  7. use Magento\Customer\Api\CustomerRepositoryInterface;
  8. use Magento\Customer\Api\Data\CustomerInterface;
  9. use Magento\Customer\Model\Account\Redirect;
  10. use Magento\Customer\Model\Session;
  11. use Magento\Framework\Api\FilterBuilder;
  12. use Magento\Framework\Api\SearchCriteriaBuilder;
  13. use Magento\Framework\App\Config\ScopeConfigInterface;
  14. use Magento\Framework\App\Config\Value;
  15. use Magento\Framework\App\Http;
  16. use Magento\Framework\Data\Form\FormKey;
  17. use Magento\Framework\Message\MessageInterface;
  18. use Magento\TestFramework\Helper\Bootstrap;
  19. use Magento\TestFramework\Request;
  20. use Magento\TestFramework\Response;
  21. use Zend\Stdlib\Parameters;
  22. use Magento\Framework\App\Request\Http as HttpRequest;
  23. use Magento\TestFramework\Mail\Template\TransportBuilderMock;
  24. use Magento\Framework\Serialize\Serializer\Json;
  25. use Magento\Framework\Stdlib\CookieManagerInterface;
  26. use Magento\Theme\Controller\Result\MessagePlugin;
  27. /**
  28. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  29. */
  30. class AccountTest extends \Magento\TestFramework\TestCase\AbstractController
  31. {
  32. /**
  33. * @var TransportBuilderMock
  34. */
  35. private $transportBuilderMock;
  36. /**
  37. * @inheritdoc
  38. */
  39. protected function setUp()
  40. {
  41. parent::setUp();
  42. $this->transportBuilderMock = $this->_objectManager->get(TransportBuilderMock::class);
  43. }
  44. /**
  45. * Login the user
  46. *
  47. * @param string $customerId Customer to mark as logged in for the session
  48. * @return void
  49. */
  50. protected function login($customerId)
  51. {
  52. /** @var \Magento\Customer\Model\Session $session */
  53. $session = Bootstrap::getObjectManager()
  54. ->get(\Magento\Customer\Model\Session::class);
  55. $session->loginById($customerId);
  56. }
  57. /**
  58. * @magentoDataFixture Magento/Customer/_files/customer.php
  59. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  60. */
  61. public function testIndexAction()
  62. {
  63. $this->login(1);
  64. $this->dispatch('customer/account/index');
  65. $body = $this->getResponse()->getBody();
  66. $this->assertContains('Green str, 67', $body);
  67. }
  68. /**
  69. * @magentoDataFixture Magento/Customer/_files/customer_no_password.php
  70. */
  71. public function testLoginWithIncorrectPassword()
  72. {
  73. $expectedMessage = 'The account sign-in was incorrect or your account is disabled temporarily. '
  74. . 'Please wait and try again later.';
  75. $this->getRequest()
  76. ->setMethod('POST')
  77. ->setPostValue(
  78. [
  79. 'login' => [
  80. 'username' => 'customer@example.com',
  81. 'password' => '123123q'
  82. ]
  83. ]
  84. );
  85. $this->dispatch('customer/account/loginPost');
  86. $this->assertRedirect($this->stringContains('customer/account/login'));
  87. $this->assertSessionMessages(
  88. $this->equalTo(
  89. [
  90. $expectedMessage
  91. ]
  92. )
  93. );
  94. }
  95. /**
  96. * Test sign up form displaying.
  97. */
  98. public function testCreateAction()
  99. {
  100. $this->dispatch('customer/account/create');
  101. $body = $this->getResponse()->getBody();
  102. $this->assertRegExp('~<input type="text"[^>]*id="firstname"~', $body);
  103. $this->assertRegExp('~<input type="text"[^>]*id="lastname"~', $body);
  104. $this->assertRegExp('~<input type="checkbox"[^>]*id="is_subscribed"~', $body);
  105. $this->assertRegExp('~<input type="email"[^>]*id="email_address"~', $body);
  106. $this->assertRegExp('~<input type="password"[^>]*id="password"~', $body);
  107. $this->assertRegExp('~<input type="password"[^>]*id="password-confirmation"~', $body);
  108. }
  109. /**
  110. * @magentoDataFixture Magento/Customer/_files/customer.php
  111. */
  112. public function testLogoutAction()
  113. {
  114. $this->login(1);
  115. $this->dispatch('customer/account/logout');
  116. $this->assertRedirect($this->stringContains('customer/account/logoutSuccess'));
  117. }
  118. /**
  119. * Test that forgot password email message displays special characters correctly.
  120. *
  121. * @codingStandardsIgnoreStart
  122. * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0
  123. * @magentoConfigFixture current_store customer/password/forgot_email_template customer_password_forgot_email_template
  124. * @magentoConfigFixture current_store customer/password/forgot_email_identity support
  125. * @magentoConfigFixture current_store general/store_information/name Test special' characters
  126. * @magentoConfigFixture current_store customer/captcha/enable 0
  127. * @magentoDataFixture Magento/Customer/_files/customer.php
  128. * @codingStandardsIgnoreEnd
  129. */
  130. public function testForgotPasswordEmailMessageWithSpecialCharacters()
  131. {
  132. $email = 'customer@example.com';
  133. $this->getRequest()->setPostValue(['email' => $email]);
  134. $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
  135. $this->dispatch('customer/account/forgotPasswordPost');
  136. $this->assertRedirect($this->stringContains('customer/account/'));
  137. $subject = $this->transportBuilderMock->getSentMessage()->getSubject();
  138. $this->assertContains(
  139. 'Test special\' characters',
  140. $subject
  141. );
  142. }
  143. /**
  144. * @magentoDataFixture Magento/Customer/_files/customer.php
  145. */
  146. public function testCreatepasswordActionWithDirectLink()
  147. {
  148. /** @var \Magento\Customer\Model\Customer $customer */
  149. $customer = Bootstrap::getObjectManager()
  150. ->create(\Magento\Customer\Model\Customer::class)->load(1);
  151. $token = Bootstrap::getObjectManager()->get(\Magento\Framework\Math\Random::class)
  152. ->getUniqueHash();
  153. $customer->changeResetPasswordLinkToken($token);
  154. $customer->save();
  155. $this->getRequest()->setParam('token', $token);
  156. $this->dispatch('customer/account/createPassword');
  157. $response = $this->getResponse();
  158. $this->assertEquals(302, $response->getHttpResponseCode());
  159. $text = $response->getBody();
  160. $this->assertFalse((bool)preg_match('/' . $token . '/m', $text));
  161. $this->assertRedirect(
  162. $this->stringContains('customer/account/createpassword')
  163. );
  164. /** @var Session $customer */
  165. $session = Bootstrap::getObjectManager()->get(Session::class);
  166. $this->assertEquals($token, $session->getRpToken());
  167. $this->assertNotContains($token, $response->getHeader('Location')->getFieldValue());
  168. }
  169. /**
  170. * @magentoDataFixture Magento/Customer/_files/customer.php
  171. */
  172. public function testCreatepasswordActionWithSession()
  173. {
  174. /** @var \Magento\Customer\Model\Customer $customer */
  175. $customer = Bootstrap::getObjectManager()
  176. ->create(\Magento\Customer\Model\Customer::class)->load(1);
  177. $token = Bootstrap::getObjectManager()->get(\Magento\Framework\Math\Random::class)
  178. ->getUniqueHash();
  179. $customer->changeResetPasswordLinkToken($token);
  180. $customer->save();
  181. /** @var \Magento\Customer\Model\Session $customer */
  182. $session = Bootstrap::getObjectManager()->get(\Magento\Customer\Model\Session::class);
  183. $session->setRpToken($token);
  184. $session->setRpCustomerId($customer->getId());
  185. $this->dispatch('customer/account/createPassword');
  186. $response = $this->getResponse();
  187. $text = $response->getBody();
  188. $this->assertTrue((bool)preg_match('/' . $token . '/m', $text));
  189. }
  190. /**
  191. * @magentoDataFixture Magento/Customer/_files/customer.php
  192. */
  193. public function testCreatepasswordActionInvalidToken()
  194. {
  195. /** @var \Magento\Customer\Model\Customer $customer */
  196. $customer = Bootstrap::getObjectManager()
  197. ->create(\Magento\Customer\Model\Customer::class)->load(1);
  198. $token = Bootstrap::getObjectManager()->get(\Magento\Framework\Math\Random::class)
  199. ->getUniqueHash();
  200. $customer->changeResetPasswordLinkToken($token);
  201. $customer->save();
  202. $this->getRequest()->setParam('token', 'INVALIDTOKEN');
  203. $this->getRequest()->setParam('id', $customer->getId());
  204. $this->dispatch('customer/account/createPassword');
  205. // should be redirected to forgotpassword page
  206. $response = $this->getResponse();
  207. $this->assertEquals(302, $response->getHttpResponseCode());
  208. $this->assertContains('customer/account/forgotpassword', $response->getHeader('Location')->getFieldValue());
  209. }
  210. /**
  211. * @magentoDataFixture Magento/Customer/_files/customer.php
  212. */
  213. public function testConfirmActionAlreadyActive()
  214. {
  215. /** @var \Magento\Customer\Model\Customer $customer */
  216. $customer = Bootstrap::getObjectManager()
  217. ->create(\Magento\Customer\Model\Customer::class)->load(1);
  218. $this->getRequest()->setParam('key', 'abc');
  219. $this->getRequest()->setParam('id', $customer->getId());
  220. $this->dispatch('customer/account/confirm');
  221. $this->getResponse()->getBody();
  222. }
  223. /**
  224. * Tests that without form key user account won't be created
  225. * and user will be redirected on account creation page again.
  226. */
  227. public function testNoFormKeyCreatePostAction()
  228. {
  229. $this->fillRequestWithAccountData('test1@email.com');
  230. $this->getRequest()->setPostValue('form_key', null);
  231. $this->dispatch('customer/account/createPost');
  232. $this->assertNull($this->getCustomerByEmail('test1@email.com'));
  233. $this->assertRedirect($this->stringEndsWith('customer/account/create/'));
  234. }
  235. /**
  236. * @magentoDbIsolation enabled
  237. * @magentoAppIsolation enabled
  238. * @magentoDataFixture Magento/Customer/_files/customer_confirmation_config_disable.php
  239. */
  240. public function testNoConfirmCreatePostAction()
  241. {
  242. $this->fillRequestWithAccountDataAndFormKey('test1@email.com');
  243. $this->dispatch('customer/account/createPost');
  244. $this->assertRedirect($this->stringEndsWith('customer/account/'));
  245. $this->assertSessionMessages(
  246. $this->equalTo(['Thank you for registering with Main Website Store.']),
  247. MessageInterface::TYPE_SUCCESS
  248. );
  249. }
  250. /**
  251. * @magentoDbIsolation enabled
  252. * @magentoAppIsolation enabled
  253. * @magentoDataFixture Magento/Customer/_files/customer_confirmation_config_enable.php
  254. */
  255. public function testWithConfirmCreatePostAction()
  256. {
  257. $this->fillRequestWithAccountDataAndFormKey('test2@email.com');
  258. $this->dispatch('customer/account/createPost');
  259. $this->assertRedirect($this->stringContains('customer/account/index/'));
  260. $this->assertSessionMessages(
  261. $this->equalTo([
  262. 'You must confirm your account. Please check your email for the confirmation link or '
  263. . '<a href="http://localhost/index.php/customer/account/confirmation/'
  264. . '?email=test2%40email.com">click here</a> for a new link.'
  265. ]),
  266. MessageInterface::TYPE_SUCCESS
  267. );
  268. }
  269. /**
  270. * @magentoDataFixture Magento/Customer/_files/customer.php
  271. */
  272. public function testExistingEmailCreatePostAction()
  273. {
  274. $this->fillRequestWithAccountDataAndFormKey('customer@example.com');
  275. $this->dispatch('customer/account/createPost');
  276. $this->assertRedirect($this->stringContains('customer/account/create/'));
  277. $this->assertSessionMessages(
  278. $this->equalTo(['There is already an account with this email address. ' .
  279. 'If you are sure that it is your email address, ' .
  280. '<a href="http://localhost/index.php/customer/account/forgotpassword/">click here</a>' .
  281. ' to get your password and access your account.', ]),
  282. MessageInterface::TYPE_ERROR
  283. );
  284. }
  285. /**
  286. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  287. */
  288. public function testInactiveUserConfirmationAction()
  289. {
  290. $this->getRequest()
  291. ->setMethod('POST')
  292. ->setPostValue(['email' => 'customer@needAconfirmation.com']);
  293. $this->dispatch('customer/account/confirmation');
  294. $this->assertRedirect($this->stringContains('customer/account/index'));
  295. $this->assertSessionMessages(
  296. $this->equalTo(['Please check your email for confirmation key.']),
  297. MessageInterface::TYPE_SUCCESS
  298. );
  299. }
  300. /**
  301. * @magentoDataFixture Magento/Customer/_files/customer.php
  302. */
  303. public function testActiveUserConfirmationAction()
  304. {
  305. $this->getRequest()
  306. ->setMethod('POST')
  307. ->setPostValue([
  308. 'email' => 'customer@example.com',
  309. ]);
  310. $this->dispatch('customer/account/confirmation');
  311. $this->assertRedirect($this->stringContains('customer/account/index'));
  312. $this->assertSessionMessages(
  313. $this->equalTo(['This email does not require confirmation.']),
  314. MessageInterface::TYPE_SUCCESS
  315. );
  316. }
  317. /**
  318. * @codingStandardsIgnoreStart
  319. * @magentoConfigFixture current_store customer/password/limit_password_reset_requests_method 0
  320. * @magentoConfigFixture current_store customer/password/forgot_email_template customer_password_forgot_email_template
  321. * @magentoConfigFixture current_store customer/password/forgot_email_identity support
  322. * @magentoConfigFixture current_store customer/captcha/enable 0
  323. * @magentoDataFixture Magento/Customer/_files/customer.php
  324. * @codingStandardsIgnoreEnd
  325. */
  326. public function testForgotPasswordPostAction()
  327. {
  328. $email = 'customer@example.com';
  329. $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
  330. $this->getRequest()->setPostValue(['email' => $email]);
  331. $this->dispatch('customer/account/forgotPasswordPost');
  332. $this->assertRedirect($this->stringContains('customer/account/'));
  333. $message = __(
  334. 'If there is an account associated with %1 you will receive an email with a link to reset your password.',
  335. $email
  336. );
  337. $this->assertSessionMessages(
  338. $this->equalTo([$message]),
  339. MessageInterface::TYPE_SUCCESS
  340. );
  341. }
  342. /**
  343. * @magentoConfigFixture current_store customer/captcha/enable 0
  344. */
  345. public function testForgotPasswordPostWithBadEmailAction()
  346. {
  347. $this->getRequest()->setMethod(HttpRequest::METHOD_POST);
  348. $this->getRequest()
  349. ->setPostValue([
  350. 'email' => 'bad@email',
  351. ]);
  352. $this->dispatch('customer/account/forgotPasswordPost');
  353. $this->assertRedirect($this->stringContains('customer/account/forgotpassword'));
  354. $this->assertSessionMessages(
  355. $this->equalTo(['The email address is incorrect. Verify the email address and try again.']),
  356. MessageInterface::TYPE_ERROR
  357. );
  358. }
  359. /**
  360. * @magentoDataFixture Magento/Customer/_files/customer.php
  361. */
  362. public function testResetPasswordPostNoTokenAction()
  363. {
  364. $this->getRequest()
  365. ->setParam('id', 1)
  366. ->setParam('token', '8ed8677e6c79e68b94e61658bd756ea5')
  367. ->setMethod('POST')
  368. ->setPostValue([
  369. 'password' => 'new-password',
  370. 'password_confirmation' => 'new-password',
  371. ]);
  372. $this->dispatch('customer/account/resetPasswordPost');
  373. $this->assertRedirect($this->stringContains('customer/account/'));
  374. $this->assertSessionMessages(
  375. $this->equalTo(['Something went wrong while saving the new password.']),
  376. MessageInterface::TYPE_ERROR
  377. );
  378. }
  379. /**
  380. * @magentoDataFixture Magento/Customer/_files/customer_rp_token.php
  381. * @magentoConfigFixture customer/password/reset_link_expiration_period 10
  382. */
  383. public function testResetPasswordPostAction()
  384. {
  385. $this->getRequest()
  386. ->setQueryValue('id', 1)
  387. ->setQueryValue('token', '8ed8677e6c79e68b94e61658bd756ea5')
  388. ->setMethod('POST')
  389. ->setPostValue([
  390. 'password' => 'new-Password1',
  391. 'password_confirmation' => 'new-Password1',
  392. ]);
  393. $this->dispatch('customer/account/resetPasswordPost');
  394. $this->assertRedirect($this->stringContains('customer/account/login'));
  395. $this->assertSessionMessages(
  396. $this->equalTo(['You updated your password.']),
  397. MessageInterface::TYPE_SUCCESS
  398. );
  399. }
  400. /**
  401. * @magentoDataFixture Magento/Customer/_files/customer.php
  402. */
  403. public function testEditAction()
  404. {
  405. $this->login(1);
  406. $this->dispatch('customer/account/edit');
  407. $body = $this->getResponse()->getBody();
  408. $this->assertEquals(200, $this->getResponse()->getHttpResponseCode(), $body);
  409. $this->assertContains('<div class="field field-name-firstname required">', $body);
  410. // Verify the password check box is not checked
  411. $this->assertContains('<input type="checkbox" name="change_password" id="change-password" '
  412. . 'data-role="change-password" value="1" title="Change&#x20;Password" class="checkbox" />', $body);
  413. }
  414. /**
  415. * @magentoDataFixture Magento/Customer/_files/customer.php
  416. */
  417. public function testChangePasswordEditAction()
  418. {
  419. $this->login(1);
  420. $this->dispatch('customer/account/edit/changepass/1');
  421. $body = $this->getResponse()->getBody();
  422. $this->assertEquals(200, $this->getResponse()->getHttpResponseCode(), $body);
  423. $this->assertContains('<div class="field field-name-firstname required">', $body);
  424. // Verify the password check box is checked
  425. $this->assertContains(
  426. '<input type="checkbox" name="change_password" id="change-password" '
  427. . 'data-role="change-password" value="1" title="Change&#x20;Password" checked="checked" '
  428. . 'class="checkbox" />',
  429. $body
  430. );
  431. }
  432. /**
  433. * @codingStandardsIgnoreStart
  434. * @magentoConfigFixture current_store customer/account_information/change_email_template customer_account_information_change_email_and_password_template
  435. * @magentoConfigFixture current_store customer/password/forgot_email_identity support
  436. * @magentoDataFixture Magento/Customer/_files/customer.php
  437. * @codingStandardsIgnoreEnd
  438. */
  439. public function testEditPostAction()
  440. {
  441. /** @var $customerRepository CustomerRepositoryInterface */
  442. $customerRepository = Bootstrap::getObjectManager()
  443. ->get(CustomerRepositoryInterface::class);
  444. $customer = $customerRepository->getById(1);
  445. $this->assertEquals('John', $customer->getFirstname());
  446. $this->assertEquals('Smith', $customer->getLastname());
  447. $this->assertEquals('customer@example.com', $customer->getEmail());
  448. $this->login(1);
  449. $this->getRequest()
  450. ->setMethod('POST')
  451. ->setPostValue([
  452. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  453. 'firstname' => 'John',
  454. 'lastname' => 'Doe',
  455. 'email' => 'johndoe@email.com',
  456. 'change_email' => 1,
  457. 'current_password' => 'password'
  458. ]);
  459. $this->dispatch('customer/account/editPost');
  460. $this->assertRedirect($this->stringContains('customer/account/'));
  461. $this->assertSessionMessages(
  462. $this->equalTo(['You saved the account information.']),
  463. MessageInterface::TYPE_SUCCESS
  464. );
  465. $customer = $customerRepository->getById(1);
  466. $this->assertEquals('John', $customer->getFirstname());
  467. $this->assertEquals('Doe', $customer->getLastname());
  468. $this->assertEquals('johndoe@email.com', $customer->getEmail());
  469. }
  470. /**
  471. * @codingStandardsIgnoreStart
  472. * @magentoConfigFixture current_store customer/account_information/change_email_and_password_template customer_account_information_change_email_and_password_template
  473. * @magentoConfigFixture current_store customer/password/forgot_email_identity support
  474. * @magentoDataFixture Magento/Customer/_files/customer.php
  475. * @codingStandardsIgnoreEnd
  476. */
  477. public function testChangePasswordEditPostAction()
  478. {
  479. /** @var $customerRepository CustomerRepositoryInterface */
  480. $customerRepository = Bootstrap::getObjectManager()
  481. ->get(CustomerRepositoryInterface::class);
  482. $customer = $customerRepository->getById(1);
  483. $this->assertEquals('John', $customer->getFirstname());
  484. $this->assertEquals('Smith', $customer->getLastname());
  485. $this->assertEquals('customer@example.com', $customer->getEmail());
  486. $this->login(1);
  487. $this->getRequest()
  488. ->setMethod('POST')
  489. ->setPostValue(
  490. [
  491. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  492. 'firstname' => 'John',
  493. 'lastname' => 'Doe',
  494. 'email' => 'johndoe@email.com',
  495. 'change_password' => 1,
  496. 'change_email' => 1,
  497. 'current_password' => 'password',
  498. 'password' => 'new-Password1',
  499. 'password_confirmation' => 'new-Password1',
  500. ]
  501. );
  502. $this->dispatch('customer/account/editPost');
  503. $this->assertRedirect($this->stringContains('customer/account/'));
  504. $this->assertSessionMessages(
  505. $this->equalTo(['You saved the account information.']),
  506. MessageInterface::TYPE_SUCCESS
  507. );
  508. $customer = $customerRepository->getById(1);
  509. $this->assertEquals('John', $customer->getFirstname());
  510. $this->assertEquals('Doe', $customer->getLastname());
  511. $this->assertEquals('johndoe@email.com', $customer->getEmail());
  512. }
  513. /**
  514. * @magentoDataFixture Magento/Customer/_files/customer.php
  515. */
  516. public function testMissingDataEditPostAction()
  517. {
  518. $this->login(1);
  519. $this->getRequest()
  520. ->setMethod('POST')
  521. ->setPostValue(
  522. [
  523. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  524. 'firstname' => 'John',
  525. 'lastname' => 'Doe',
  526. 'change_email' => 1,
  527. 'current_password' => 'password',
  528. 'email' => 'bad-email',
  529. ]
  530. );
  531. $this->dispatch('customer/account/editPost');
  532. $this->assertRedirect($this->stringContains('customer/account/edit/'));
  533. $this->assertSessionMessages(
  534. $this->equalTo(['&quot;Email&quot; is not a valid email address.']),
  535. MessageInterface::TYPE_ERROR
  536. );
  537. }
  538. /**
  539. * @magentoDataFixture Magento/Customer/_files/customer.php
  540. */
  541. public function testWrongPasswordEditPostAction()
  542. {
  543. $this->login(1);
  544. $this->getRequest()
  545. ->setMethod('POST')
  546. ->setPostValue(
  547. [
  548. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  549. 'firstname' => 'John',
  550. 'lastname' => 'Doe',
  551. 'email' => 'johndoe@email.com',
  552. 'change_password' => 1,
  553. 'current_password' => 'wrong-password',
  554. 'password' => 'new-password',
  555. 'password_confirmation' => 'new-password',
  556. ]
  557. );
  558. $this->dispatch('customer/account/editPost');
  559. $this->assertRedirect($this->stringContains('customer/account/edit/'));
  560. // Not sure if its the most secure message. Not changing the behavior for now in the new AccountManagement APIs.
  561. $this->assertSessionMessages(
  562. $this->equalTo(["The password doesn&#039;t match this account. Verify the password and try again."]),
  563. MessageInterface::TYPE_ERROR
  564. );
  565. }
  566. /**
  567. * @magentoDataFixture Magento/Customer/_files/customer.php
  568. */
  569. public function testWrongConfirmationEditPostAction()
  570. {
  571. $this->login(1);
  572. $this->getRequest()
  573. ->setMethod('POST')
  574. ->setPostValue([
  575. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  576. 'firstname' => 'John',
  577. 'lastname' => 'Doe',
  578. 'email' => 'johndoe@email.com',
  579. 'change_password' => 1,
  580. 'current_password' => 'password',
  581. 'password' => 'new-password',
  582. 'password_confirmation' => 'new-password-no-match',
  583. ]);
  584. $this->dispatch('customer/account/editPost');
  585. $this->assertRedirect($this->stringContains('customer/account/edit/'));
  586. $this->assertSessionMessages(
  587. $this->equalTo(['Password confirmation doesn&#039;t match entered password.']),
  588. MessageInterface::TYPE_ERROR
  589. );
  590. }
  591. /**
  592. * Test redirect customer to account dashboard after logging in.
  593. *
  594. * @param bool|null $redirectDashboard
  595. * @param string $redirectUrl
  596. * @magentoDbIsolation enabled
  597. * @magentoAppIsolation enabled
  598. * @magentoDataFixture Magento/Customer/_files/customer.php
  599. * @dataProvider loginPostRedirectDataProvider
  600. */
  601. public function testLoginPostRedirect($redirectDashboard, string $redirectUrl)
  602. {
  603. if (isset($redirectDashboard)) {
  604. $this->_objectManager->get(ScopeConfigInterface::class)->setValue(
  605. 'customer/startup/redirect_dashboard',
  606. $redirectDashboard
  607. );
  608. }
  609. $this->_objectManager->get(Redirect::class)->setRedirectCookie('test');
  610. $configValue = $this->_objectManager->create(Value::class);
  611. $configValue->load('web/unsecure/base_url', 'path');
  612. $baseUrl = $configValue->getValue() ?: 'http://localhost/';
  613. $request = $this->prepareRequest();
  614. $app = $this->_objectManager->create(Http::class, ['_request' => $request]);
  615. $response = $app->launch();
  616. $this->assertResponseRedirect($response, $baseUrl . $redirectUrl);
  617. $this->assertTrue($this->_objectManager->get(Session::class)->isLoggedIn());
  618. }
  619. /**
  620. * Test that confirmation email address displays special characters correctly.
  621. *
  622. * @magentoDbIsolation enabled
  623. * @magentoDataFixture Magento/Customer/_files/customer_confirmation_email_address_with_special_chars.php
  624. *
  625. * @return void
  626. */
  627. public function testConfirmationEmailWithSpecialCharacters(): void
  628. {
  629. $email = 'customer+confirmation@example.com';
  630. $this->dispatch('customer/account/confirmation/email/customer%2Bconfirmation%40email.com');
  631. $this->getRequest()->setPostValue('email', $email);
  632. $this->dispatch('customer/account/confirmation/email/customer%2Bconfirmation%40email.com');
  633. $this->assertRedirect($this->stringContains('customer/account/index'));
  634. $this->assertSessionMessages(
  635. $this->equalTo(['Please check your email for confirmation key.']),
  636. MessageInterface::TYPE_SUCCESS
  637. );
  638. /** @var $message \Magento\Framework\Mail\Message */
  639. $message = $this->transportBuilderMock->getSentMessage();
  640. $rawMessage = $message->getRawMessage();
  641. $this->assertContains('To: ' . $email, $rawMessage);
  642. $content = $message->getBody()->getPartContent(0);
  643. $confirmationUrl = $this->getConfirmationUrlFromMessageContent($content);
  644. $this->setRequestInfo($confirmationUrl, 'confirm');
  645. $this->clearCookieMessagesList();
  646. $this->dispatch($confirmationUrl);
  647. $this->assertRedirect($this->stringContains('customer/account/index'));
  648. $this->assertSessionMessages(
  649. $this->equalTo(['Thank you for registering with Main Website Store.']),
  650. MessageInterface::TYPE_SUCCESS
  651. );
  652. }
  653. /**
  654. * Data provider for testLoginPostRedirect.
  655. *
  656. * @return array
  657. */
  658. public function loginPostRedirectDataProvider()
  659. {
  660. return [
  661. [null, 'index.php/'],
  662. [0, 'index.php/'],
  663. [1, 'index.php/customer/account/'],
  664. ];
  665. }
  666. /**
  667. * @magentoDataFixture Magento/Customer/_files/customer.php
  668. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  669. * @magentoAppArea frontend
  670. */
  671. public function testCheckVisitorModel()
  672. {
  673. /** @var \Magento\Customer\Model\Visitor $visitor */
  674. $visitor = $this->_objectManager->get(\Magento\Customer\Model\Visitor::class);
  675. $this->login(1);
  676. $this->assertNull($visitor->getId());
  677. $this->dispatch('customer/account/index');
  678. $this->assertNotNull($visitor->getId());
  679. }
  680. /**
  681. * @param string $email
  682. * @return void
  683. */
  684. private function fillRequestWithAccountData($email)
  685. {
  686. $this->getRequest()
  687. ->setMethod('POST')
  688. ->setParam('firstname', 'firstname1')
  689. ->setParam('lastname', 'lastname1')
  690. ->setParam('company', '')
  691. ->setParam('email', $email)
  692. ->setParam('password', '_Password1')
  693. ->setParam('password_confirmation', '_Password1')
  694. ->setParam('telephone', '5123334444')
  695. ->setParam('street', ['1234 fake street', ''])
  696. ->setParam('city', 'Austin')
  697. ->setParam('region_id', 57)
  698. ->setParam('region', '')
  699. ->setParam('postcode', '78701')
  700. ->setParam('country_id', 'US')
  701. ->setParam('default_billing', '1')
  702. ->setParam('default_shipping', '1')
  703. ->setParam('is_subscribed', '0')
  704. ->setPostValue('create_address', true);
  705. }
  706. /**
  707. * @param string $email
  708. * @return void
  709. */
  710. private function fillRequestWithAccountDataAndFormKey($email)
  711. {
  712. $this->fillRequestWithAccountData($email);
  713. $formKey = $this->_objectManager->get(FormKey::class);
  714. $this->getRequest()->setParam('form_key', $formKey->getFormKey());
  715. }
  716. /**
  717. * Returns stored customer by email.
  718. *
  719. * @param string $email
  720. * @return CustomerInterface
  721. */
  722. private function getCustomerByEmail($email)
  723. {
  724. /** @var FilterBuilder $filterBuilder */
  725. $filterBuilder = $this->_objectManager->get(FilterBuilder::class);
  726. $filters = [
  727. $filterBuilder->setField(CustomerInterface::EMAIL)
  728. ->setValue($email)
  729. ->create()
  730. ];
  731. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  732. $searchCriteriaBuilder = $this->_objectManager->get(SearchCriteriaBuilder::class);
  733. $searchCriteria = $searchCriteriaBuilder->addFilters($filters)
  734. ->create();
  735. $customerRepository = $this->_objectManager->get(CustomerRepositoryInterface::class);
  736. $customers = $customerRepository->getList($searchCriteria)
  737. ->getItems();
  738. $customer = array_pop($customers);
  739. return $customer;
  740. }
  741. /**
  742. * Prepare request for customer login.
  743. *
  744. * @return Request
  745. */
  746. private function prepareRequest()
  747. {
  748. $post = new Parameters([
  749. 'form_key' => $this->_objectManager->get(FormKey::class)->getFormKey(),
  750. 'login' => [
  751. 'username' => 'customer@example.com',
  752. 'password' => 'password'
  753. ]
  754. ]);
  755. $request = $this->getRequest();
  756. $formKey = $this->_objectManager->get(FormKey::class);
  757. $request->setParam('form_key', $formKey->getFormKey());
  758. $request->setMethod(Request::METHOD_POST);
  759. $request->setRequestUri('customer/account/loginPost/');
  760. $request->setPost($post);
  761. return $request;
  762. }
  763. /**
  764. * Assert response is redirect.
  765. *
  766. * @param Response $response
  767. * @param string $redirectUrl
  768. * @return void
  769. */
  770. private function assertResponseRedirect(Response $response, string $redirectUrl)
  771. {
  772. $this->assertTrue($response->isRedirect());
  773. $this->assertSame($redirectUrl, $response->getHeader('Location')->getUri());
  774. }
  775. /**
  776. * Add new request info (request uri, path info, action name).
  777. *
  778. * @param string $uri
  779. * @param string $actionName
  780. * @return void
  781. */
  782. private function setRequestInfo(string $uri, string $actionName): void
  783. {
  784. $this->getRequest()
  785. ->setRequestUri($uri)
  786. ->setPathInfo()
  787. ->setActionName($actionName);
  788. }
  789. /**
  790. * Clear cookie messages list.
  791. *
  792. * @return void
  793. */
  794. private function clearCookieMessagesList(): void
  795. {
  796. $cookieManager = $this->_objectManager->get(CookieManagerInterface::class);
  797. $jsonSerializer = $this->_objectManager->get(Json::class);
  798. $cookieManager->setPublicCookie(
  799. MessagePlugin::MESSAGES_COOKIES_NAME,
  800. $jsonSerializer->serialize([])
  801. );
  802. }
  803. /**
  804. * Get confirmation URL from message content.
  805. *
  806. * @param string $content
  807. * @return string
  808. */
  809. private function getConfirmationUrlFromMessageContent(string $content): string
  810. {
  811. $confirmationUrl = '';
  812. if (preg_match('<a\s*href="(?<url>.*?)".*>', $content, $matches)) {
  813. $confirmationUrl = $matches['url'];
  814. $confirmationUrl = str_replace('http://localhost/index.php/', '', $confirmationUrl);
  815. $confirmationUrl = html_entity_decode($confirmationUrl);
  816. }
  817. return $confirmationUrl;
  818. }
  819. }