Skip to content

Fix AcountManagementTest unit test fail randomly #11605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 42 additions & 33 deletions app/code/Magento/Customer/Model/AccountManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@
use Magento\Customer\Api\Data\AddressInterface;
use Magento\Customer\Api\Data\CustomerInterface;
use Magento\Customer\Api\Data\ValidationResultsInterfaceFactory;
use Magento\Customer\Model\EmailNotificationInterface;
use Magento\Customer\Helper\View as CustomerViewHelper;
use Magento\Customer\Model\Config\Share as ConfigShare;
use Magento\Customer\Model\Customer as CustomerModel;
use Magento\Customer\Model\Customer\CredentialsValidator;
use Magento\Customer\Model\Metadata\Validator;
use Magento\Eav\Model\Validator\Attribute\Backend;
use Magento\Framework\Api\ExtensibleDataObjectConverter;
use Magento\Framework\App\Area;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\DataObjectFactory as ObjectFactory;
use Magento\Framework\Encryption\EncryptorInterface as Encryptor;
use Magento\Framework\Encryption\Helper\Security;
use Magento\Framework\Event\ManagerInterface;
Expand All @@ -30,23 +31,22 @@
use Magento\Framework\Exception\InputException;
use Magento\Framework\Exception\InvalidEmailOrPasswordException;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Exception\State\ExpiredException;
use Magento\Framework\Exception\State\InputMismatchException;
use Magento\Framework\Exception\State\InvalidTransitionException;
use Magento\Framework\DataObjectFactory as ObjectFactory;
use Magento\Framework\Exception\State\UserLockedException;
use Magento\Framework\Registry;
use Magento\Store\Model\ScopeInterface;
use Psr\Log\LoggerInterface as PsrLogger;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Intl\DateTimeFactory;
use Magento\Framework\Mail\Template\TransportBuilder;
use Magento\Framework\Math\Random;
use Magento\Framework\Reflection\DataObjectProcessor;
use Magento\Framework\Registry;
use Magento\Framework\Stdlib\DateTime;
use Magento\Framework\Stdlib\StringUtils as StringHelper;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Customer\Model\Customer\CredentialsValidator;
use Psr\Log\LoggerInterface as PsrLogger;

/**
* Handle various customer account actions
Expand Down Expand Up @@ -293,6 +293,11 @@ class AccountManagement implements AccountManagementInterface
*/
private $credentialsValidator;

/**
* @var DateTimeFactory
*/
private $dateTimeFactory;

/**
* @param CustomerFactory $customerFactory
* @param ManagerInterface $eventManager
Expand All @@ -318,6 +323,7 @@ class AccountManagement implements AccountManagementInterface
* @param ObjectFactory $objectFactory
* @param ExtensibleDataObjectConverter $extensibleDataObjectConverter
* @param CredentialsValidator|null $credentialsValidator
* @param DateTimeFactory $dateTimeFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Expand All @@ -344,7 +350,8 @@ public function __construct(
CustomerModel $customerModel,
ObjectFactory $objectFactory,
ExtensibleDataObjectConverter $extensibleDataObjectConverter,
CredentialsValidator $credentialsValidator = null
CredentialsValidator $credentialsValidator = null,
DateTimeFactory $dateTimeFactory = null
) {
$this->customerFactory = $customerFactory;
$this->eventManager = $eventManager;
Expand All @@ -369,8 +376,9 @@ public function __construct(
$this->customerModel = $customerModel;
$this->objectFactory = $objectFactory;
$this->extensibleDataObjectConverter = $extensibleDataObjectConverter;
$this->credentialsValidator = $credentialsValidator ?: ObjectManager::getInstance()
->get(CredentialsValidator::class);
$this->credentialsValidator =
$credentialsValidator ?: ObjectManager::getInstance()->get(CredentialsValidator::class);
$this->dateTimeFactory = $dateTimeFactory ?: ObjectManager::getInstance()->get(DateTimeFactory::class);
}

/**
Expand All @@ -380,7 +388,6 @@ public function __construct(
*/
private function getAuthentication()
{

if (!($this->authentication instanceof AuthenticationInterface)) {
return \Magento\Framework\App\ObjectManager::getInstance()->get(
\Magento\Customer\Model\AuthenticationInterface::class
Expand Down Expand Up @@ -613,16 +620,16 @@ protected function makeRequiredCharactersCheck($password)
$return = 0;

if (preg_match('/[0-9]+/', $password)) {
$counter ++;
$counter++;
}
if (preg_match('/[A-Z]+/', $password)) {
$counter ++;
$counter++;
}
if (preg_match('/[a-z]+/', $password)) {
$counter ++;
$counter++;
}
if (preg_match('/[^a-zA-Z0-9]+/', $password)) {
$counter ++;
$counter++;
}

if ($counter < $requiredNumber) {
Expand Down Expand Up @@ -890,16 +897,14 @@ public function validate(CustomerInterface $customer)

$result = $this->getEavValidator()->isValid($customerModel);
if ($result === false && is_array($this->getEavValidator()->getMessages())) {
return $validationResults->setIsValid(false)
->setMessages(
call_user_func_array(
'array_merge',
$this->getEavValidator()->getMessages()
)
);
return $validationResults->setIsValid(false)->setMessages(
call_user_func_array(
'array_merge',
$this->getEavValidator()->getMessages()
)
);
}
return $validationResults->setIsValid(true)
->setMessages([]);
return $validationResults->setIsValid(true)->setMessages([]);
}

/**
Expand Down Expand Up @@ -949,10 +954,12 @@ public function isCustomerInStore($customerWebsiteId, $storeId)
private function validateResetPasswordToken($customerId, $resetPasswordLinkToken)
{
if (empty($customerId) || $customerId < 0) {
throw new InputException(__(
'Invalid value of "%value" provided for the %fieldName field.',
['value' => $customerId, 'fieldName' => 'customerId']
));
throw new InputException(
__(
'Invalid value of "%value" provided for the %fieldName field.',
['value' => $customerId, 'fieldName' => 'customerId']
)
);
}
if (!is_string($resetPasswordLinkToken) || empty($resetPasswordLinkToken)) {
$params = ['fieldName' => 'resetPasswordLinkToken'];
Expand Down Expand Up @@ -1178,8 +1185,8 @@ public function isResetPasswordLinkTokenExpired($rpToken, $rpTokenCreatedAt)

$expirationPeriod = $this->customerModel->getResetPasswordLinkExpirationPeriod();

$currentTimestamp = (new \DateTime())->getTimestamp();
$tokenTimestamp = (new \DateTime($rpTokenCreatedAt))->getTimestamp();
$currentTimestamp = $this->dateTimeFactory->create()->getTimestamp();
$tokenTimestamp = $this->dateTimeFactory->create($rpTokenCreatedAt)->getTimestamp();
if ($tokenTimestamp > $currentTimestamp) {
return true;
}
Expand Down Expand Up @@ -1215,7 +1222,9 @@ public function changeResetPasswordLinkToken($customer, $passwordLinkToken)
if (is_string($passwordLinkToken) && !empty($passwordLinkToken)) {
$customerSecure = $this->customerRegistry->retrieveSecureData($customer->getId());
$customerSecure->setRpToken($passwordLinkToken);
$customerSecure->setRpTokenCreatedAt((new \DateTime())->format(DateTime::DATETIME_PHP_FORMAT));
$customerSecure->setRpTokenCreatedAt(
$this->dateTimeFactory->create()->format(DateTime::DATETIME_PHP_FORMAT)
);
$this->customerRepository->save($customer);
}
return true;
Expand Down Expand Up @@ -1304,8 +1313,8 @@ protected function getFullCustomerObject($customer)
// No need to flatten the custom attributes or nested objects since the only usage is for email templates and
// object passed for events
$mergedCustomerData = $this->customerRegistry->retrieveSecureData($customer->getId());
$customerData = $this->dataProcessor
->buildOutputDataArray($customer, \Magento\Customer\Api\Data\CustomerInterface::class);
$customerData =
$this->dataProcessor->buildOutputDataArray($customer, \Magento\Customer\Api\Data\CustomerInterface::class);
$mergedCustomerData->addData($customerData);
$mergedCustomerData->setData('name', $this->customerViewHelper->getCustomerName($customer));
return $mergedCustomerData;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Magento\Customer\Model\EmailNotificationInterface;
use Magento\Framework\App\Area;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Intl\DateTimeFactory;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
use Magento\Store\Model\ScopeInterface;

Expand Down Expand Up @@ -114,6 +115,11 @@ class AccountManagementTest extends \PHPUnit\Framework\TestCase
*/
protected $emailNotificationMock;

/**
* @var DateTimeFactory|\PHPUnit_Framework_MockObject_MockObject
*/
private $dateTimeFactory;

/**
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
Expand Down Expand Up @@ -163,6 +169,8 @@ protected function setUp()
->disableOriginalConstructor()
->getMock();

$this->dateTimeFactory = $this->createMock(DateTimeFactory::class);

$this->objectManagerHelper = new ObjectManagerHelper($this);
$this->accountManagement = $this->objectManagerHelper->getObject(
\Magento\Customer\Model\AccountManagement::class,
Expand Down Expand Up @@ -190,6 +198,7 @@ protected function setUp()
'customerModel' => $this->customer,
'objectFactory' => $this->objectFactory,
'extensibleDataObjectConverter' => $this->extensibleDataObjectConverter,
'dateTimeFactory' => $this->dateTimeFactory,
]
);
$reflection = new \ReflectionClass(get_class($this->accountManagement));
Expand Down Expand Up @@ -552,6 +561,8 @@ public function testCreateAccountWithoutPassword()
$customerEmail = '[email protected]';
$newLinkToken = '2jh43j5h2345jh23lh452h345hfuzasd96ofu';

$datetime = $this->prepareDateTimeFactory();

$address = $this->getMockBuilder(\Magento\Customer\Api\Data\AddressInterface::class)
->disableOriginalConstructor()
->getMock();
Expand Down Expand Up @@ -624,7 +635,9 @@ public function testCreateAccountWithoutPassword()
->method('setRpToken')
->with($newLinkToken);
$customerSecure->expects($this->any())
->method('setRpTokenCreatedAt');
->method('setRpTokenCreatedAt')
->with($datetime)
->willReturnSelf();
$customerSecure->expects($this->any())
->method('getPasswordHash')
->willReturn(null);
Expand Down Expand Up @@ -756,6 +769,8 @@ public function testCreateAccountWithPassword()
$minPasswordLength = 5;
$minCharacterSetsNum = 2;

$datetime = $this->prepareDateTimeFactory();

$this->scopeConfig->expects($this->any())
->method('getValue')
->willReturnMap(
Expand Down Expand Up @@ -865,7 +880,9 @@ public function testCreateAccountWithPassword()
->method('setRpToken')
->with($newLinkToken);
$customerSecure->expects($this->any())
->method('setRpTokenCreatedAt');
->method('setRpTokenCreatedAt')
->with($datetime)
->willReturnSelf();
$customerSecure->expects($this->any())
->method('getPasswordHash')
->willReturn($hash);
Expand Down Expand Up @@ -995,7 +1012,7 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se
{
$websiteId = 1;

$dateTime = date(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT);
$datetime = $this->prepareDateTimeFactory();

$customerData = ['key' => 'value'];
$customerName = 'Customer Name';
Expand Down Expand Up @@ -1047,7 +1064,7 @@ protected function prepareInitiatePasswordReset($email, $templateIdentifier, $se
->willReturnSelf();
$this->customerSecure->expects($this->any())
->method('setRpTokenCreatedAt')
->with($dateTime)
->with($datetime)
->willReturnSelf();
$this->customerSecure->expects($this->any())
->method('addData')
Expand Down Expand Up @@ -1257,18 +1274,20 @@ private function reInitModel()
->method('getRpToken')
->willReturn('newStringToken');

$date = date('Y-m-d', strtotime('-1 year'));
$pastDateTime = '2016-10-25 00:00:00';

$this->customerSecure
->expects($this->any())
->method('getRpTokenCreatedAt')
->willReturn($date);
->willReturn($pastDateTime);

$this->customer = $this->getMockBuilder(\Magento\Customer\Model\Customer::class)
->disableOriginalConstructor()
->setMethods(['getResetPasswordLinkExpirationPeriod'])
->getMock();

$this->prepareDateTimeFactory();

$this->objectManagerHelper = new ObjectManagerHelper($this);
$this->accountManagement = $this->objectManagerHelper->getObject(
\Magento\Customer\Model\AccountManagement::class,
Expand All @@ -1277,6 +1296,7 @@ private function reInitModel()
'customerRegistry' => $this->customerRegistry,
'customerRepository' => $this->customerRepository,
'customerModel' => $this->customer,
'dateTimeFactory' => $this->dateTimeFactory,
]
);
$reflection = new \ReflectionClass(get_class($this->accountManagement));
Expand Down Expand Up @@ -1320,7 +1340,7 @@ public function testChangePassword()
->with(null);
$customerSecure->expects($this->once())
->method('setRpTokenCreatedAt')
->with(null);
->willReturnSelf();
$customerSecure->expects($this->any())
->method('getPasswordHash')
->willReturn($passwordHash);
Expand Down Expand Up @@ -1586,6 +1606,8 @@ public function testCreateAccountWithPasswordHashWithCustomerAddresses()
$storeId = 1;
$hash = '4nj54lkj5jfi03j49f8bgujfgsd';

$this->prepareDateTimeFactory();

//Handle store
$store = $this->getMockBuilder(\Magento\Store\Model\Store::class)->disableOriginalConstructor()->getMock();
$store->expects($this->any())
Expand Down Expand Up @@ -1630,7 +1652,7 @@ public function testCreateAccountWithPasswordHashWithCustomerAddresses()
->expects($this->any())
->method("getId")
->willReturn($customerId);
//Return Customer from customer repositoryå
//Return Customer from customer repository
$this->customerRepository
->expects($this->atLeastOnce())
->method('save')
Expand Down Expand Up @@ -1673,4 +1695,30 @@ public function testCreateAccountWithPasswordHashWithCustomerAddresses()

$this->assertSame($customer, $this->accountManagement->createAccountWithPasswordHash($customer, $hash));
}

/**
* @return string
*/
private function prepareDateTimeFactory()
{
$dateTime = '2017-10-25 18:57:08';
$timestamp = '1508983028';
$dateTimeMock = $this->createMock(\DateTime::class);
$dateTimeMock->expects($this->any())
->method('format')
->with(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT)
->willReturn($dateTime);

$dateTimeMock
->expects($this->any())
->method('getTimestamp')
->willReturn($timestamp);

$this->dateTimeFactory
->expects($this->any())
->method('create')
->willReturn($dateTimeMock);

return $dateTime;
}
}