From 030b223efa3c7e5811ccddbf064d33fb7224c888 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Fri, 21 Sep 2018 15:06:05 +0300 Subject: [PATCH 1/8] Fix the issue with reset password when customer has address from not allowed country --- .../Customer/Model/AccountManagement.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index fe17adcb09c0d..95bc942355dfc 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -326,6 +326,11 @@ class AccountManagement implements AccountManagementInterface */ private $accountConfirmation; + /** + * @var AddressRegistry + */ + private $addressRegistry; + /** * @param CustomerFactory $customerFactory * @param ManagerInterface $eventManager @@ -356,6 +361,7 @@ class AccountManagement implements AccountManagementInterface * @param SessionManagerInterface|null $sessionManager * @param SaveHandlerInterface|null $saveHandler * @param CollectionFactory|null $visitorCollectionFactory + * @param AddressRegistry|null $addressRegistry * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -387,7 +393,8 @@ public function __construct( AccountConfirmation $accountConfirmation = null, SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, - CollectionFactory $visitorCollectionFactory = null + CollectionFactory $visitorCollectionFactory = null, + AddressRegistry $addressRegistry ) { $this->customerFactory = $customerFactory; $this->eventManager = $eventManager; @@ -423,6 +430,8 @@ public function __construct( ?: ObjectManager::getInstance()->get(SaveHandlerInterface::class); $this->visitorCollectionFactory = $visitorCollectionFactory ?: ObjectManager::getInstance()->get(CollectionFactory::class); + $this->addressRegistry = $addressRegistry + ?: ObjectManager::getInstance()->get(AddressRegistry::class); } /** @@ -568,6 +577,12 @@ public function initiatePasswordReset($email, $template, $websiteId = null) // load customer by email $customer = $this->customerRepository->get($email, $websiteId); + foreach ($customer->getAddresses() as $address) { + // No need to validate customer address while saving customer reset password token + $addressModel = $this->addressRegistry->retrieve($address->getId()); + $addressModel->setShouldIgnoreValidation(true); + } + $newPasswordToken = $this->mathRandom->getUniqueHash(); $this->changeResetPasswordLinkToken($customer, $newPasswordToken); From 54b6382b4b8c142e99afa62382c6adc729e82adb Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Sat, 22 Sep 2018 15:30:30 +0300 Subject: [PATCH 2/8] Updated the unit test, fix and additional issue #18170 --- .../Customer/Model/AccountManagement.php | 2 +- .../Test/Unit/Model/AccountManagementTest.php | 33 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 95bc942355dfc..a7db70d14fad1 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -394,7 +394,7 @@ public function __construct( SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, CollectionFactory $visitorCollectionFactory = null, - AddressRegistry $addressRegistry + AddressRegistry $addressRegistry = null ) { $this->customerFactory = $customerFactory; $this->eventManager = $eventManager; diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index aad20f757e91e..0190ebcc4457e 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -142,6 +142,11 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase */ private $saveHandler; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\AddressRegistry + */ + private $addressRegistryMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -176,6 +181,7 @@ protected function setUp() $this->dateTime = $this->createMock(\Magento\Framework\Stdlib\DateTime::class); $this->customer = $this->createMock(\Magento\Customer\Model\Customer::class); $this->objectFactory = $this->createMock(\Magento\Framework\DataObjectFactory::class); + $this->addressRegistryMock = $this->createMock(\Magento\Customer\Model\AddressRegistry::class); $this->extensibleDataObjectConverter = $this->createMock( \Magento\Framework\Api\ExtensibleDataObjectConverter::class ); @@ -239,6 +245,7 @@ protected function setUp() 'sessionManager' => $this->sessionManager, 'saveHandler' => $this->saveHandler, 'visitorCollectionFactory' => $this->visitorCollectionFactory, + 'addressRegistry' => $this->addressRegistryMock, ] ); $this->objectManagerHelper->setBackwardCompatibleProperty( @@ -1071,6 +1078,7 @@ public function testSendPasswordReminderEmail() protected function prepareInitiatePasswordReset($email, $templateIdentifier, $sender, $storeId, $customerId, $hash) { $websiteId = 1; + $addressId = 5; $datetime = $this->prepareDateTimeFactory(); @@ -1088,6 +1096,17 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se ->method('getStore') ->willReturn($this->store); + /** @var \Magento\Customer\Model\Address|\PHPUnit_Framework_MockObject_MockObject $addressModel */ + $addressModel = $this->getMockBuilder(\Magento\Customer\Model\Address::class)->disableOriginalConstructor() + ->setMethods(['setShouldIgnoreValidation'])->getMock(); + + /** @var \Magento\Customer\Api\Data\AddressInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ + $address = $this->createMock(\Magento\Customer\Api\Data\AddressInterface::class); + $address->expects($this->once()) + ->method('getId') + ->willReturn($addressId); + + /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) ->getMock(); $customer->expects($this->any()) @@ -1099,6 +1118,20 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se $customer->expects($this->any()) ->method('getStoreId') ->willReturn($storeId); + $customer->expects($this->any()) + ->method('getAddresses') + ->willReturn([$address]); + + $this->customerRepository->expects($this->once()) + ->method('get') + ->willReturn($customer); + $this->addressRegistryMock->expects($this->once()) + ->method('retrieve') + ->with($addressId) + ->willReturn($addressModel); + $addressModel->expects($this->once()) + ->method('setShouldIgnoreValidation') + ->with(true); $this->customerRepository->expects($this->once()) ->method('get') From 406d00003ee1190714ee90b53577a4eaf4c062ad Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Wed, 26 Sep 2018 17:04:42 +0300 Subject: [PATCH 3/8] Fix code stryling issues #18170 --- app/code/Magento/Customer/Model/AccountManagement.php | 4 ++++ .../Customer/Test/Unit/Model/AccountManagementTest.php | 10 ---------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index a7db70d14fad1..c2f46b24985af 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -970,6 +970,8 @@ protected function createPasswordHash($password) } /** + * Get attribute validator + * * @return Backend */ private function getEavValidator() @@ -1168,6 +1170,8 @@ protected function getWebsiteStoreId($customer, $defaultStoreId = null) } /** + * Get available email template types + * * @return array * @deprecated 100.1.0 */ diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 0190ebcc4457e..27880e44a7239 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -1079,9 +1079,7 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se { $websiteId = 1; $addressId = 5; - $datetime = $this->prepareDateTimeFactory(); - $customerData = ['key' => 'value']; $customerName = 'Customer Name'; @@ -1091,7 +1089,6 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se $this->store->expects($this->any()) ->method('getId') ->willReturn($storeId); - $this->storeManager->expects($this->any()) ->method('getStore') ->willReturn($this->store); @@ -1121,7 +1118,6 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se $customer->expects($this->any()) ->method('getAddresses') ->willReturn([$address]); - $this->customerRepository->expects($this->once()) ->method('get') ->willReturn($customer); @@ -1132,7 +1128,6 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se $addressModel->expects($this->once()) ->method('setShouldIgnoreValidation') ->with(true); - $this->customerRepository->expects($this->once()) ->method('get') ->with($email, $websiteId) @@ -1141,16 +1136,13 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se ->method('save') ->with($customer) ->willReturnSelf(); - $this->random->expects($this->once()) ->method('getUniqueHash') ->willReturn($hash); - $this->customerViewHelper->expects($this->any()) ->method('getCustomerName') ->with($customer) ->willReturn($customerName); - $this->customerSecure->expects($this->any()) ->method('setRpToken') ->with($hash) @@ -1167,12 +1159,10 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se ->method('setData') ->with('name', $customerName) ->willReturnSelf(); - $this->customerRegistry->expects($this->any()) ->method('retrieveSecureData') ->with($customerId) ->willReturn($this->customerSecure); - $this->dataObjectProcessor->expects($this->any()) ->method('buildOutputDataArray') ->with($customer, \Magento\Customer\Api\Data\CustomerInterface::class) From ebd39d36bb3422eec41a939f5c20a9b1ae2efde3 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Thu, 27 Sep 2018 08:41:47 +0300 Subject: [PATCH 4/8] Fix the minor code styling issue --- .../Magento/Customer/Model/AccountManagement.php | 10 +++++----- .../Test/Unit/Model/AccountManagementTest.php | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index c2f46b24985af..99aa494e9981f 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -259,7 +259,7 @@ class AccountManagement implements AccountManagementInterface /** * @var CollectionFactory */ - private $visitorCollectionFactory; + private $visitorColFactory; /** * @var DataObjectProcessor @@ -360,7 +360,7 @@ class AccountManagement implements AccountManagementInterface * @param AccountConfirmation|null $accountConfirmation * @param SessionManagerInterface|null $sessionManager * @param SaveHandlerInterface|null $saveHandler - * @param CollectionFactory|null $visitorCollectionFactory + * @param CollectionFactory|null $visitorColFactory * @param AddressRegistry|null $addressRegistry * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -393,7 +393,7 @@ public function __construct( AccountConfirmation $accountConfirmation = null, SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, - CollectionFactory $visitorCollectionFactory = null, + CollectionFactory $visitorColFactory = null, AddressRegistry $addressRegistry = null ) { $this->customerFactory = $customerFactory; @@ -428,7 +428,7 @@ public function __construct( ?: ObjectManager::getInstance()->get(SessionManagerInterface::class); $this->saveHandler = $saveHandler ?: ObjectManager::getInstance()->get(SaveHandlerInterface::class); - $this->visitorCollectionFactory = $visitorCollectionFactory + $this->visitorColFactory = $visitorColFactory ?: ObjectManager::getInstance()->get(CollectionFactory::class); $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); @@ -1480,7 +1480,7 @@ private function destroyCustomerSessions($customerId) $activeSessionsTime = $dateTime->setTimestamp($dateTime->getTimestamp() - $sessionLifetime) ->format(DateTime::DATETIME_PHP_FORMAT); /** @var \Magento\Customer\Model\ResourceModel\Visitor\Collection $visitorCollection */ - $visitorCollection = $this->visitorCollectionFactory->create(); + $visitorCollection = $this->visitorColFactory->create(); $visitorCollection->addFieldToFilter('customer_id', $customerId); $visitorCollection->addFieldToFilter('last_visit_at', ['from' => $activeSessionsTime]); $visitorCollection->addFieldToFilter('session_id', ['neq' => $this->sessionManager->getSessionId()]); diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 27880e44a7239..b1e1967aaa630 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -135,7 +135,7 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory */ - private $visitorCollectionFactory; + private $visitorColFactory; /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Session\SaveHandlerInterface @@ -200,7 +200,7 @@ protected function setUp() $this->dateTimeFactory = $this->createMock(DateTimeFactory::class); $this->accountConfirmation = $this->createMock(AccountConfirmation::class); - $this->visitorCollectionFactory = $this->getMockBuilder( + $this->visitorColFactory = $this->getMockBuilder( \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class ) ->disableOriginalConstructor() @@ -244,7 +244,7 @@ protected function setUp() 'accountConfirmation' => $this->accountConfirmation, 'sessionManager' => $this->sessionManager, 'saveHandler' => $this->saveHandler, - 'visitorCollectionFactory' => $this->visitorCollectionFactory, + 'visitorColFactory' => $this->visitorColFactory, 'addressRegistry' => $this->addressRegistryMock, ] ); @@ -1385,7 +1385,7 @@ private function reInitModel() $this->sessionManager = $this->getMockBuilder(\Magento\Framework\Session\SessionManagerInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->visitorCollectionFactory = $this->getMockBuilder( + $this->visitorColFactory = $this->getMockBuilder( \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class ) ->disableOriginalConstructor() @@ -1431,7 +1431,7 @@ private function reInitModel() 'stringHelper' => $this->string, 'scopeConfig' => $this->scopeConfig, 'sessionManager' => $this->sessionManager, - 'visitorCollectionFactory' => $this->visitorCollectionFactory, + 'visitorColFactory' => $this->visitorColFactory, 'saveHandler' => $this->saveHandler, 'encryptor' => $this->encryptor, 'dataProcessor' => $this->dataObjectProcessor, @@ -1530,7 +1530,7 @@ public function testChangePassword() ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') + $this->visitorColFactory->expects($this->atLeastOnce())->method('create') ->willReturn($visitorCollection); $this->saveHandler->expects($this->atLeastOnce())->method('destroy') ->withConsecutive( @@ -1584,7 +1584,7 @@ function ($string) { ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') + $this->visitorColFactory->expects($this->atLeastOnce())->method('create') ->willReturn($visitorCollection); $this->saveHandler->expects($this->atLeastOnce())->method('destroy') ->withConsecutive( From 91275d606be59a30b6dc327309c7d7faa2cdefa5 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Sat, 29 Sep 2018 08:59:50 +0300 Subject: [PATCH 5/8] Revert "Fix the minor code styling issue" This reverts commit ebd39d36bb3422eec41a939f5c20a9b1ae2efde3. --- .../Magento/Customer/Model/AccountManagement.php | 10 +++++----- .../Test/Unit/Model/AccountManagementTest.php | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 99aa494e9981f..c2f46b24985af 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -259,7 +259,7 @@ class AccountManagement implements AccountManagementInterface /** * @var CollectionFactory */ - private $visitorColFactory; + private $visitorCollectionFactory; /** * @var DataObjectProcessor @@ -360,7 +360,7 @@ class AccountManagement implements AccountManagementInterface * @param AccountConfirmation|null $accountConfirmation * @param SessionManagerInterface|null $sessionManager * @param SaveHandlerInterface|null $saveHandler - * @param CollectionFactory|null $visitorColFactory + * @param CollectionFactory|null $visitorCollectionFactory * @param AddressRegistry|null $addressRegistry * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ @@ -393,7 +393,7 @@ public function __construct( AccountConfirmation $accountConfirmation = null, SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, - CollectionFactory $visitorColFactory = null, + CollectionFactory $visitorCollectionFactory = null, AddressRegistry $addressRegistry = null ) { $this->customerFactory = $customerFactory; @@ -428,7 +428,7 @@ public function __construct( ?: ObjectManager::getInstance()->get(SessionManagerInterface::class); $this->saveHandler = $saveHandler ?: ObjectManager::getInstance()->get(SaveHandlerInterface::class); - $this->visitorColFactory = $visitorColFactory + $this->visitorCollectionFactory = $visitorCollectionFactory ?: ObjectManager::getInstance()->get(CollectionFactory::class); $this->addressRegistry = $addressRegistry ?: ObjectManager::getInstance()->get(AddressRegistry::class); @@ -1480,7 +1480,7 @@ private function destroyCustomerSessions($customerId) $activeSessionsTime = $dateTime->setTimestamp($dateTime->getTimestamp() - $sessionLifetime) ->format(DateTime::DATETIME_PHP_FORMAT); /** @var \Magento\Customer\Model\ResourceModel\Visitor\Collection $visitorCollection */ - $visitorCollection = $this->visitorColFactory->create(); + $visitorCollection = $this->visitorCollectionFactory->create(); $visitorCollection->addFieldToFilter('customer_id', $customerId); $visitorCollection->addFieldToFilter('last_visit_at', ['from' => $activeSessionsTime]); $visitorCollection->addFieldToFilter('session_id', ['neq' => $this->sessionManager->getSessionId()]); diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index b1e1967aaa630..27880e44a7239 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -135,7 +135,7 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory */ - private $visitorColFactory; + private $visitorCollectionFactory; /** * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Session\SaveHandlerInterface @@ -200,7 +200,7 @@ protected function setUp() $this->dateTimeFactory = $this->createMock(DateTimeFactory::class); $this->accountConfirmation = $this->createMock(AccountConfirmation::class); - $this->visitorColFactory = $this->getMockBuilder( + $this->visitorCollectionFactory = $this->getMockBuilder( \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class ) ->disableOriginalConstructor() @@ -244,7 +244,7 @@ protected function setUp() 'accountConfirmation' => $this->accountConfirmation, 'sessionManager' => $this->sessionManager, 'saveHandler' => $this->saveHandler, - 'visitorColFactory' => $this->visitorColFactory, + 'visitorCollectionFactory' => $this->visitorCollectionFactory, 'addressRegistry' => $this->addressRegistryMock, ] ); @@ -1385,7 +1385,7 @@ private function reInitModel() $this->sessionManager = $this->getMockBuilder(\Magento\Framework\Session\SessionManagerInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); - $this->visitorColFactory = $this->getMockBuilder( + $this->visitorCollectionFactory = $this->getMockBuilder( \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class ) ->disableOriginalConstructor() @@ -1431,7 +1431,7 @@ private function reInitModel() 'stringHelper' => $this->string, 'scopeConfig' => $this->scopeConfig, 'sessionManager' => $this->sessionManager, - 'visitorColFactory' => $this->visitorColFactory, + 'visitorCollectionFactory' => $this->visitorCollectionFactory, 'saveHandler' => $this->saveHandler, 'encryptor' => $this->encryptor, 'dataProcessor' => $this->dataObjectProcessor, @@ -1530,7 +1530,7 @@ public function testChangePassword() ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorColFactory->expects($this->atLeastOnce())->method('create') + $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') ->willReturn($visitorCollection); $this->saveHandler->expects($this->atLeastOnce())->method('destroy') ->withConsecutive( @@ -1584,7 +1584,7 @@ function ($string) { ->disableOriginalConstructor()->setMethods(['addFieldToFilter', 'getItems'])->getMock(); $visitorCollection->expects($this->atLeastOnce())->method('addFieldToFilter')->willReturnSelf(); $visitorCollection->expects($this->atLeastOnce())->method('getItems')->willReturn([$visitor, $visitor]); - $this->visitorColFactory->expects($this->atLeastOnce())->method('create') + $this->visitorCollectionFactory->expects($this->atLeastOnce())->method('create') ->willReturn($visitorCollection); $this->saveHandler->expects($this->atLeastOnce())->method('destroy') ->withConsecutive( From 97632b368698137434a055bf6f8145fa9c355c65 Mon Sep 17 00:00:00 2001 From: Dmytro Cheshun Date: Mon, 26 Nov 2018 23:06:30 +0200 Subject: [PATCH 6/8] Update the fix for reset password issue when a country is not allowed, update the PHPUnit tests #18170 --- .../Customer/Model/AccountManagement.php | 54 +++++++++++++++++-- .../Test/Unit/Model/AccountManagementTest.php | 37 +++++++++++-- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 8beecffd1c865..1064692e5992f 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -18,6 +18,7 @@ use Magento\Customer\Model\Customer as CustomerModel; use Magento\Customer\Model\Customer\CredentialsValidator; use Magento\Customer\Model\Metadata\Validator; +use Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory; use Magento\Eav\Model\Validator\Attribute\Backend; use Magento\Framework\Api\ExtensibleDataObjectConverter; use Magento\Framework\Api\SearchCriteriaBuilder; @@ -45,14 +46,13 @@ use Magento\Framework\Phrase; use Magento\Framework\Reflection\DataObjectProcessor; use Magento\Framework\Registry; +use Magento\Framework\Session\SaveHandlerInterface; +use Magento\Framework\Session\SessionManagerInterface; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\Stdlib\StringUtils as StringHelper; use Magento\Store\Model\ScopeInterface; use Magento\Store\Model\StoreManagerInterface; use Psr\Log\LoggerInterface as PsrLogger; -use Magento\Framework\Session\SessionManagerInterface; -use Magento\Framework\Session\SaveHandlerInterface; -use Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory; /** * Handle various customer account actions @@ -333,6 +333,11 @@ class AccountManagement implements AccountManagementInterface */ private $searchCriteriaBuilder; + /** + * @var AddressRegistry + */ + private $addressRegistry; + /** * @param CustomerFactory $customerFactory * @param ManagerInterface $eventManager @@ -364,6 +369,7 @@ class AccountManagement implements AccountManagementInterface * @param SaveHandlerInterface|null $saveHandler * @param CollectionFactory|null $visitorCollectionFactory * @param SearchCriteriaBuilder|null $searchCriteriaBuilder + * @param AddressRegistry|null $addressRegistry * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ public function __construct( @@ -396,7 +402,8 @@ public function __construct( SessionManagerInterface $sessionManager = null, SaveHandlerInterface $saveHandler = null, CollectionFactory $visitorCollectionFactory = null, - SearchCriteriaBuilder $searchCriteriaBuilder = null + SearchCriteriaBuilder $searchCriteriaBuilder = null, + AddressRegistry $addressRegistry = null ) { $this->customerFactory = $customerFactory; $this->eventManager = $eventManager; @@ -434,6 +441,8 @@ public function __construct( ?: ObjectManager::getInstance()->get(CollectionFactory::class); $this->searchCriteriaBuilder = $searchCriteriaBuilder ?: ObjectManager::getInstance()->get(SearchCriteriaBuilder::class); + $this->addressRegistry = $addressRegistry + ?: ObjectManager::getInstance()->get(AddressRegistry::class); } /** @@ -579,6 +588,9 @@ public function initiatePasswordReset($email, $template, $websiteId = null) // load customer by email $customer = $this->customerRepository->get($email, $websiteId); + // No need to validate customer address while saving customer reset password token + $this->disableAddressValidation($customer); + $newPasswordToken = $this->mathRandom->getUniqueHash(); $this->changeResetPasswordLinkToken($customer, $newPasswordToken); @@ -669,6 +681,10 @@ public function resetPassword($email, $resetToken, $newPassword) } else { $customer = $this->customerRepository->get($email); } + + // No need to validate customer address while saving customer reset password token + $this->disableAddressValidation($customer); + //Validate Token and new password strength $this->validateResetPasswordToken($customer->getId(), $resetToken); $this->credentialsValidator->checkPasswordDifferentFromEmail( @@ -921,6 +937,8 @@ public function getDefaultShippingAddress($customerId) * @param CustomerInterface $customer * @param string $redirectUrl * @return void + * @throws LocalizedException + * @throws NoSuchEntityException */ protected function sendEmailConfirmation(CustomerInterface $customer, $redirectUrl) { @@ -975,7 +993,10 @@ public function changePasswordById($customerId, $currentPassword, $newPassword) * @param string $newPassword * @return bool true on success * @throws InputException + * @throws InputMismatchException * @throws InvalidEmailOrPasswordException + * @throws LocalizedException + * @throws NoSuchEntityException * @throws UserLockedException */ private function changePasswordForCustomer($customer, $currentPassword, $newPassword) @@ -1190,6 +1211,8 @@ protected function sendNewAccountEmail( * * @param CustomerInterface $customer * @return $this + * @throws LocalizedException + * @throws NoSuchEntityException * @deprecated 100.1.0 */ protected function sendPasswordResetNotificationEmail($customer) @@ -1252,6 +1275,7 @@ protected function getTemplateTypes() * @param int|null $storeId * @param string $email * @return $this + * @throws MailException * @deprecated 100.1.0 */ protected function sendEmailTemplate( @@ -1367,6 +1391,9 @@ public function isResetPasswordLinkTokenExpired($rpToken, $rpTokenCreatedAt) * @param string $passwordLinkToken * @return bool * @throws InputException + * @throws InputMismatchException + * @throws LocalizedException + * @throws NoSuchEntityException */ public function changeResetPasswordLinkToken($customer, $passwordLinkToken) { @@ -1394,6 +1421,8 @@ public function changeResetPasswordLinkToken($customer, $passwordLinkToken) * * @param CustomerInterface $customer * @return $this + * @throws LocalizedException + * @throws NoSuchEntityException * @deprecated 100.1.0 */ public function sendPasswordReminderEmail($customer) @@ -1421,6 +1450,8 @@ public function sendPasswordReminderEmail($customer) * * @param CustomerInterface $customer * @return $this + * @throws LocalizedException + * @throws NoSuchEntityException * @deprecated 100.1.0 */ public function sendPasswordResetConfirmationEmail($customer) @@ -1465,6 +1496,7 @@ protected function getAddressById(CustomerInterface $customer, $addressId) * * @param CustomerInterface $customer * @return Data\CustomerSecure + * @throws NoSuchEntityException * @deprecated 100.1.0 */ protected function getFullCustomerObject($customer) @@ -1492,6 +1524,20 @@ public function getPasswordHash($password) return $this->encryptor->getHash($password); } + /** + * Disable Customer Address Validation + * + * @param CustomerInterface $customer + * @throws NoSuchEntityException + */ + private function disableAddressValidation($customer) + { + foreach ($customer->getAddresses() as $address) { + $addressModel = $this->addressRegistry->retrieve($address->getId()); + $addressModel->setShouldIgnoreValidation(true); + } + } + /** * Get email notification * diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 27880e44a7239..1a8bf0506620b 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -6,10 +6,11 @@ namespace Magento\Customer\Test\Unit\Model; -use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\AccountConfirmation; +use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\AuthenticationInterface; use Magento\Customer\Model\EmailNotificationInterface; +use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\App\Area; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\Intl\DateTimeFactory; @@ -147,6 +148,11 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase */ private $addressRegistryMock; + /** + * @var \PHPUnit_Framework_MockObject_MockObject|SearchCriteriaBuilder + */ + private $searchCriteriaBuilderMock; + /** * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ @@ -199,6 +205,7 @@ protected function setUp() $this->dateTimeFactory = $this->createMock(DateTimeFactory::class); $this->accountConfirmation = $this->createMock(AccountConfirmation::class); + $this->searchCriteriaBuilderMock = $this->createMock(SearchCriteriaBuilder::class); $this->visitorCollectionFactory = $this->getMockBuilder( \Magento\Customer\Model\ResourceModel\Visitor\CollectionFactory::class @@ -245,6 +252,7 @@ protected function setUp() 'sessionManager' => $this->sessionManager, 'saveHandler' => $this->saveHandler, 'visitorCollectionFactory' => $this->visitorCollectionFactory, + 'searchCriteriaBuilder' => $this->searchCriteriaBuilderMock, 'addressRegistry' => $this->addressRegistryMock, ] ); @@ -1289,11 +1297,11 @@ public function testInitiatePasswordResetNoTemplate() /** * @expectedException \Magento\Framework\Exception\InputException - * @expectedExceptionMessage Invalid value of "" provided for the customerId field + * @expectedExceptionMessage Invalid value of "0" provided for the customerId field */ public function testValidateResetPasswordTokenBadCustomerId() { - $this->accountManagement->validateResetPasswordLinkToken(null, ''); + $this->accountManagement->validateResetPasswordLinkToken(0, ''); } /** @@ -1436,6 +1444,7 @@ private function reInitModel() 'encryptor' => $this->encryptor, 'dataProcessor' => $this->dataObjectProcessor, 'storeManager' => $this->storeManager, + 'addressRegistry' => $this->addressRegistryMock, 'transportBuilder' => $this->transportBuilder, ] ); @@ -1548,12 +1557,34 @@ public function testResetPassword() { $customerEmail = 'customer@example.com'; $customerId = '1'; + $addressId = 5; $resetToken = 'newStringToken'; $newPassword = 'new_password'; $this->reInitModel(); + /** @var \Magento\Customer\Model\Address|\PHPUnit_Framework_MockObject_MockObject $addressModel */ + $addressModel = $this->getMockBuilder(\Magento\Customer\Model\Address::class)->disableOriginalConstructor() + ->setMethods(['setShouldIgnoreValidation'])->getMock(); + + /** @var \Magento\Customer\Api\Data\AddressInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ + $address = $this->createMock(\Magento\Customer\Api\Data\AddressInterface::class); + $address->expects($this->any()) + ->method('getId') + ->willReturn($addressId); + + /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); $customer->expects($this->any())->method('getId')->willReturn($customerId); + $customer->expects($this->any()) + ->method('getAddresses') + ->willReturn([$address]); + $this->addressRegistryMock->expects($this->once()) + ->method('retrieve') + ->with($addressId) + ->willReturn($addressModel); + $addressModel->expects($this->once()) + ->method('setShouldIgnoreValidation') + ->with(true); $this->customerRepository->expects($this->atLeastOnce())->method('get')->with($customerEmail) ->willReturn($customer); $this->customer->expects($this->atLeastOnce())->method('getResetPasswordLinkExpirationPeriod') From 338d568cfdb7979cb644d9b561846bb281bc81a8 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Mon, 10 Dec 2018 15:34:19 +0200 Subject: [PATCH 7/8] ENGCOM-3056: Static tests fixed. --- app/code/Magento/Customer/Model/AccountManagement.php | 1 + 1 file changed, 1 insertion(+) diff --git a/app/code/Magento/Customer/Model/AccountManagement.php b/app/code/Magento/Customer/Model/AccountManagement.php index 1064692e5992f..86ff0b6ad93a5 100644 --- a/app/code/Magento/Customer/Model/AccountManagement.php +++ b/app/code/Magento/Customer/Model/AccountManagement.php @@ -371,6 +371,7 @@ class AccountManagement implements AccountManagementInterface * @param SearchCriteriaBuilder|null $searchCriteriaBuilder * @param AddressRegistry|null $addressRegistry * @SuppressWarnings(PHPMD.ExcessiveParameterList) + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function __construct( CustomerFactory $customerFactory, From 13e2ceea60105bccff32709a350737b4ee26a945 Mon Sep 17 00:00:00 2001 From: Pavel Bystritsky Date: Fri, 14 Dec 2018 11:56:56 +0200 Subject: [PATCH 8/8] ENGCOM-3056: Unit tests fix. --- .../Test/Unit/Model/AccountManagementTest.php | 61 +++++++++++-------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php index 1a8bf0506620b..0273c445bdd2a 100644 --- a/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php +++ b/app/code/Magento/Customer/Test/Unit/Model/AccountManagementTest.php @@ -6,9 +6,11 @@ namespace Magento\Customer\Test\Unit\Model; +use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Model\AccountConfirmation; use Magento\Customer\Model\AccountManagement; use Magento\Customer\Model\AuthenticationInterface; +use Magento\Customer\Model\Data\Customer; use Magento\Customer\Model\EmailNotificationInterface; use Magento\Framework\Api\SearchCriteriaBuilder; use Magento\Framework\App\Area; @@ -283,7 +285,7 @@ public function testCreateAccountWithPasswordHashWithExistingCustomer() $website->expects($this->once()) ->method('getStoreIds') ->willReturn([1, 2, 3]); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->once()) ->method('getId') ->willReturn($customerId); @@ -339,7 +341,7 @@ public function testCreateAccountWithPasswordHashWithCustomerWithoutStoreId() $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -415,7 +417,7 @@ public function testCreateAccountWithPasswordHashWithLocalizedException() $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -494,7 +496,7 @@ public function testCreateAccountWithPasswordHashWithAddressException() $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -563,8 +565,9 @@ public function testCreateAccountWithPasswordHashWithNewCustomerAndLocalizedExce $websiteId = 1; $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); + $customerMock = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() + ->getMock(); $customerMock->expects($this->atLeastOnce()) ->method('getId') @@ -655,7 +658,7 @@ public function testCreateAccountWithoutPassword() $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -800,7 +803,7 @@ public function testCreateAccountWithPasswordInputException( $minCharacterSetsNum . '. Classes of characters: Lower Case, Upper Case, Digits, Special Characters.'); } - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $this->accountManagement->createAccount($customer, $password); } @@ -821,7 +824,7 @@ public function testCreateAccountInputExceptionExtraLongPassword() $this->expectException(\Magento\Framework\Exception\InputException::class); $this->expectExceptionMessage('Please enter a password with at most 256 characters.'); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $this->accountManagement->createAccount($customer, $password); } @@ -900,7 +903,7 @@ public function testCreateAccountWithPassword() $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -984,7 +987,8 @@ public function testSendPasswordReminderEmail() $templateIdentifier = 'Template Identifier'; $sender = 'Sender'; - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + $customer = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() ->getMock(); $customer->expects($this->any()) ->method('getStoreId') @@ -1016,7 +1020,7 @@ public function testSendPasswordReminderEmail() $this->dataObjectProcessor->expects($this->once()) ->method('buildOutputDataArray') - ->with($customer, \Magento\Customer\Api\Data\CustomerInterface::class) + ->with($customer, CustomerInterface::class) ->willReturn($customerData); $this->customerViewHelper->expects($this->any()) @@ -1111,8 +1115,9 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se ->method('getId') ->willReturn($addressId); - /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + /** @var Customer|\PHPUnit_Framework_MockObject_MockObject $customer */ + $customer = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() ->getMock(); $customer->expects($this->any()) ->method('getEmail') @@ -1173,7 +1178,7 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se ->willReturn($this->customerSecure); $this->dataObjectProcessor->expects($this->any()) ->method('buildOutputDataArray') - ->with($customer, \Magento\Customer\Api\Data\CustomerInterface::class) + ->with($customer, Customer::class) ->willReturn($customerData); $this->prepareEmailSend($email, $templateIdentifier, $sender, $storeId, $customerName); @@ -1467,7 +1472,8 @@ public function testChangePassword() $passwordHash = '1a2b3f4c'; $this->reInitModel(); - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + $customer = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() ->getMock(); $customer->expects($this->any()) ->method('getId') @@ -1572,8 +1578,8 @@ public function testResetPassword() ->method('getId') ->willReturn($addressId); - /** @var \Magento\Customer\Api\Data\CustomerInterface|\PHPUnit_Framework_MockObject_MockObject $customer */ - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + /** @var Customer|\PHPUnit_Framework_MockObject_MockObject $customer */ + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer->expects($this->any())->method('getId')->willReturn($customerId); $customer->expects($this->any()) ->method('getAddresses') @@ -1658,7 +1664,8 @@ public function testAuthenticate() $password = '1234567'; $passwordHash = '1a2b3f4c'; - $customerData = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + $customerData = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() ->getMock(); $customerModel = $this->getMockBuilder(\Magento\Customer\Model\Customer::class) @@ -1723,7 +1730,7 @@ public function testGetConfirmationStatus( $customerId = 1; $customerEmail = 'test1@example.com'; - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) + $customerMock = $this->getMockBuilder(Customer::class) ->disableOriginalConstructor() ->getMock(); $customerMock->expects($this->once()) @@ -1793,8 +1800,9 @@ public function testCreateAccountWithPasswordHashForGuest() ->method('getStore') ->willReturn($storeMock); - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); + $customerMock = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() + ->getMock(); $customerMock->expects($this->exactly(2)) ->method('getId') ->willReturn(null); @@ -1877,7 +1885,7 @@ public function testCreateAccountWithPasswordHashWithCustomerAddresses() ->method("setId") ->with(null); //Handle Customer calls - $customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)->getMock(); + $customer = $this->getMockBuilder(Customer::class)->disableOriginalConstructor()->getMock(); $customer ->expects($this->atLeastOnce()) ->method('getWebsiteId') @@ -2003,7 +2011,7 @@ public function testCreateAccountUnexpectedValueException(): void $website->expects($this->once()) ->method('getDefaultStore') ->willReturn($store); - $customer = $this->createMock(\Magento\Customer\Api\Data\CustomerInterface::class); + $customer = $this->createMock(Customer::class); $customer->expects($this->atLeastOnce()) ->method('getId') ->willReturn($customerId); @@ -2082,8 +2090,9 @@ public function testCreateAccountWithStoreNotInWebsite() $storeId = 1; $websiteId = 1; $hash = '4nj54lkj5jfi03j49f8bgujfgsd'; - $customerMock = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class) - ->getMockForAbstractClass(); + $customerMock = $this->getMockBuilder(Customer::class) + ->disableOriginalConstructor() + ->getMock(); $customerMock->expects($this->atLeastOnce()) ->method('getId') ->willReturn(null);