|
9 | 9 | use Magento\Customer\Api\CustomerRepositoryInterface;
|
10 | 10 | use Magento\Customer\Api\Data\CustomerInterface;
|
11 | 11 | use Magento\Customer\Model\Account\Redirect;
|
| 12 | +use Magento\Customer\Model\CustomerRegistry; |
12 | 13 | use Magento\Customer\Model\Session;
|
13 | 14 | use Magento\Framework\Api\FilterBuilder;
|
14 | 15 | use Magento\Framework\Api\SearchCriteriaBuilder;
|
|
25 | 26 | use Magento\TestFramework\Request;
|
26 | 27 | use Magento\TestFramework\Response;
|
27 | 28 | use Magento\Theme\Controller\Result\MessagePlugin;
|
| 29 | +use PHPUnit\Framework\Constraint\StringContains; |
28 | 30 | use Zend\Stdlib\Parameters;
|
29 | 31 |
|
30 | 32 | /**
|
@@ -796,6 +798,141 @@ public function testConfirmationEmailWithSpecialCharacters(): void
|
796 | 798 | );
|
797 | 799 | }
|
798 | 800 |
|
| 801 | + /** |
| 802 | + * Check that Customer which change email can't log in with old email. |
| 803 | + * |
| 804 | + * @magentoDataFixture Magento/Customer/_files/customer.php |
| 805 | + * @magentoConfigFixture current_store customer/captcha/enable 0 |
| 806 | + * |
| 807 | + * @return void |
| 808 | + */ |
| 809 | + public function testResetPasswordWhenEmailChanged(): void |
| 810 | + { |
| 811 | + $email = 'customer@example.com'; |
| 812 | + $newEmail = 'new_customer@example.com'; |
| 813 | + |
| 814 | + /* Reset password and check mail with token */ |
| 815 | + $this->getRequest()->setPostValue(['email' => $email]); |
| 816 | + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); |
| 817 | + |
| 818 | + $this->dispatch('customer/account/forgotPasswordPost'); |
| 819 | + $this->assertRedirect($this->stringContains('customer/account/')); |
| 820 | + $this->assertSessionMessages( |
| 821 | + $this->equalTo( |
| 822 | + [ |
| 823 | + "If there is an account associated with {$email} you will receive an email with a link " |
| 824 | + . "to reset your password." |
| 825 | + ] |
| 826 | + ), |
| 827 | + MessageInterface::TYPE_SUCCESS |
| 828 | + ); |
| 829 | + |
| 830 | + /** @var CustomerRegistry $customerRegistry */ |
| 831 | + $customerRegistry = $this->_objectManager->get(CustomerRegistry::class); |
| 832 | + $customerData = $customerRegistry->retrieveByEmail($email); |
| 833 | + $token = $customerData->getRpToken(); |
| 834 | + $this->assertForgotPasswordEmailContent($token); |
| 835 | + |
| 836 | + /* Set new email */ |
| 837 | + /** @var CustomerRepositoryInterface $customerRepository */ |
| 838 | + $customerRepository = $this->_objectManager->create(CustomerRepositoryInterface::class); |
| 839 | + /** @var \Magento\Customer\Api\Data\CustomerInterface $customer */ |
| 840 | + $customer = $customerRepository->getById($customerData->getId()); |
| 841 | + $customer->setEmail($newEmail); |
| 842 | + $customerRepository->save($customer); |
| 843 | + |
| 844 | + /* Goes through the link in a mail */ |
| 845 | + $this->resetRequest(); |
| 846 | + $this->getRequest() |
| 847 | + ->setParam('token', $token) |
| 848 | + ->setParam('id', $customerData->getId()); |
| 849 | + |
| 850 | + $this->dispatch('customer/account/createPassword'); |
| 851 | + |
| 852 | + $this->assertRedirect($this->stringContains('customer/account/forgotpassword')); |
| 853 | + $this->assertSessionMessages( |
| 854 | + $this->equalTo(['Your password reset link has expired.']), |
| 855 | + MessageInterface::TYPE_ERROR |
| 856 | + ); |
| 857 | + /* Trying to log in with old email */ |
| 858 | + $this->resetRequest(); |
| 859 | + $this->clearCookieMessagesList(); |
| 860 | + $customerRegistry->removeByEmail($email); |
| 861 | + |
| 862 | + $this->dispatchLoginPostAction($email, 'password'); |
| 863 | + $this->assertSessionMessages( |
| 864 | + $this->equalTo( |
| 865 | + [ |
| 866 | + 'The account sign-in was incorrect or your account is disabled temporarily. ' |
| 867 | + . 'Please wait and try again later.' |
| 868 | + ] |
| 869 | + ), |
| 870 | + MessageInterface::TYPE_ERROR |
| 871 | + ); |
| 872 | + $this->assertRedirect($this->stringContains('customer/account/login')); |
| 873 | + /** @var Session $session */ |
| 874 | + $session = $this->_objectManager->get(Session::class); |
| 875 | + $this->assertFalse($session->isLoggedIn()); |
| 876 | + |
| 877 | + /* Trying to log in with correct(new) email */ |
| 878 | + $this->resetRequest(); |
| 879 | + $this->dispatchLoginPostAction($newEmail, 'password'); |
| 880 | + $this->assertRedirect($this->stringContains('customer/account/')); |
| 881 | + $this->assertTrue($session->isLoggedIn()); |
| 882 | + $session->logout(); |
| 883 | + } |
| 884 | + |
| 885 | + /** |
| 886 | + * Set needed parameters and dispatch Customer loginPost action. |
| 887 | + * |
| 888 | + * @param string $email |
| 889 | + * @param string $password |
| 890 | + * @return void |
| 891 | + */ |
| 892 | + private function dispatchLoginPostAction(string $email, string $password): void |
| 893 | + { |
| 894 | + $this->getRequest()->setMethod(HttpRequest::METHOD_POST); |
| 895 | + $this->getRequest()->setPostValue( |
| 896 | + [ |
| 897 | + 'login' => [ |
| 898 | + 'username' => $email, |
| 899 | + 'password' => $password, |
| 900 | + ], |
| 901 | + ] |
| 902 | + ); |
| 903 | + $this->dispatch('customer/account/loginPost'); |
| 904 | + } |
| 905 | + |
| 906 | + /** |
| 907 | + * Check that 'Forgot password' email contains correct data. |
| 908 | + * |
| 909 | + * @param string $token |
| 910 | + * @return void |
| 911 | + */ |
| 912 | + private function assertForgotPasswordEmailContent(string $token): void |
| 913 | + { |
| 914 | + $message = $this->transportBuilderMock->getSentMessage(); |
| 915 | + $pattern = "/<a.+customer\/account\/createPassword\/\?token={$token}.+Set\s+a\s+New\s+Password<\/a\>/"; |
| 916 | + $rawMessage = $message->getBody()->getParts()[0]->getRawContent(); |
| 917 | + $messageConstraint = $this->logicalAnd( |
| 918 | + new StringContains('There was recently a request to change the password for your account.'), |
| 919 | + $this->matchesRegularExpression($pattern) |
| 920 | + ); |
| 921 | + $this->assertThat($rawMessage, $messageConstraint); |
| 922 | + } |
| 923 | + |
| 924 | + /** |
| 925 | + * Clear request object. |
| 926 | + * |
| 927 | + * @return void |
| 928 | + */ |
| 929 | + private function resetRequest(): void |
| 930 | + { |
| 931 | + $this->_objectManager->removeSharedInstance(Http::class); |
| 932 | + $this->_objectManager->removeSharedInstance(Request::class); |
| 933 | + $this->_request = null; |
| 934 | + } |
| 935 | + |
799 | 936 | /**
|
800 | 937 | * Data provider for testLoginPostRedirect.
|
801 | 938 | *
|
|
0 commit comments