From d6d087295353de695cd8f6bc77a0b53c1a60277d Mon Sep 17 00:00:00 2001 From: Yaroslav Rogoza Date: Sat, 30 Jun 2018 16:40:31 +0300 Subject: [PATCH 001/189] Added URL rewrites data to the product interface --- .../Magento/CatalogGraphQl/etc/module.xml | 1 + .../CatalogGraphQl/etc/schema.graphqls | 1 + .../Model/Resolver/EntityUrl.php | 161 ++++++++++++++++++ .../Model/Resolver/UrlRewrite.php | 146 +++++----------- .../UrlRewriteGraphQl/etc/schema.graphqls | 12 +- 5 files changed, 219 insertions(+), 102 deletions(-) create mode 100644 app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php diff --git a/app/code/Magento/CatalogGraphQl/etc/module.xml b/app/code/Magento/CatalogGraphQl/etc/module.xml index 87696c129a7..2551664cc5f 100644 --- a/app/code/Magento/CatalogGraphQl/etc/module.xml +++ b/app/code/Magento/CatalogGraphQl/etc/module.xml @@ -15,6 +15,7 @@ + diff --git a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls index 762861de94e..b7a5f7ac1c6 100644 --- a/app/code/Magento/CatalogGraphQl/etc/schema.graphqls +++ b/app/code/Magento/CatalogGraphQl/etc/schema.graphqls @@ -280,6 +280,7 @@ interface ProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\ manufacturer: Int @doc(description: "A number representing the product's manufacturer") categories: [CategoryInterface] @doc(description: "The categories assigned to a product") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Categories") canonical_url: String @doc(description: "Canonical URL") @resolver(class: "Magento\\CatalogGraphQl\\Model\\Resolver\\Product\\CanonicalUrl") + url_rewrites: [UrlRewrite] @doc(description: "URL rewrites list") @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") } interface PhysicalProductInterface @typeResolver(class: "Magento\\CatalogGraphQl\\Model\\ProductInterfaceTypeResolverComposite") @doc(description: "PhysicalProductInterface contains attributes specific to tangible products") { diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php new file mode 100644 index 00000000000..9790339dd10 --- /dev/null +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/EntityUrl.php @@ -0,0 +1,161 @@ +urlFinder = $urlFinder; + $this->storeManager = $storeManager; + $this->valueFactory = $valueFactory; + $this->customUrlLocator = $customUrlLocator; + } + + /** + * {@inheritdoc} + */ + public function resolve( + Field $field, + $context, + ResolveInfo $info, + array $value = null, + array $args = null + ) : Value { + $result = function () { + return null; + }; + + if (isset($args['url'])) { + $url = $args['url']; + if (substr($url, 0, 1) === '/' && $url !== '/') { + $url = ltrim($url, '/'); + } + $customUrl = $this->customUrlLocator->locateUrl($url); + $url = $customUrl ?: $url; + $urlRewrite = $this->findCanonicalUrl($url); + if ($urlRewrite) { + $urlRewriteReturnArray = [ + 'id' => $urlRewrite->getEntityId(), + 'canonical_url' => $urlRewrite->getTargetPath(), + 'type' => $this->sanitizeType($urlRewrite->getEntityType()) + ]; + $result = function () use ($urlRewriteReturnArray) { + return $urlRewriteReturnArray; + }; + } + } + return $this->valueFactory->create($result); + } + + /** + * Find the canonical url passing through all redirects if any + * + * @param string $requestPath + * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null + */ + private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite + { + $urlRewrite = $this->findUrlFromRequestPath($requestPath); + if ($urlRewrite && $urlRewrite->getRedirectType() > 0) { + while ($urlRewrite && $urlRewrite->getRedirectType() > 0) { + $urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath()); + } + } + if (!$urlRewrite) { + $urlRewrite = $this->findUrlFromTargetPath($requestPath); + } + + return $urlRewrite; + } + + /** + * Find a url from a request url on the current store + * + * @param string $requestPath + * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null + */ + private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite + { + return $this->urlFinder->findOneByData( + [ + 'request_path' => $requestPath, + 'store_id' => $this->storeManager->getStore()->getId() + ] + ); + } + + /** + * Find a url from a target url on the current store + * + * @param string $targetPath + * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null + */ + private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite + { + return $this->urlFinder->findOneByData( + [ + 'target_path' => $targetPath, + 'store_id' => $this->storeManager->getStore()->getId() + ] + ); + } + + /** + * Sanitize the type to fit schema specifications + * + * @param string $type + * @return string + */ + private function sanitizeType(string $type) : string + { + return strtoupper(str_replace('-', '_', $type)); + } +} diff --git a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php index 3f07edc6019..e64912d171a 100644 --- a/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php +++ b/app/code/Magento/UrlRewriteGraphQl/Model/Resolver/UrlRewrite.php @@ -12,51 +12,31 @@ use Magento\Framework\GraphQl\Query\Resolver\Value; use Magento\Framework\GraphQl\Query\Resolver\ValueFactory; use Magento\Framework\GraphQl\Query\ResolverInterface; -use Magento\Store\Model\StoreManagerInterface; +use Magento\Framework\Model\AbstractModel; use Magento\UrlRewrite\Model\UrlFinderInterface; -use Magento\UrlRewriteGraphQl\Model\Resolver\UrlRewrite\CustomUrlLocatorInterface; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite as UrlRewriteDTO; /** * UrlRewrite field resolver, used for GraphQL request processing. */ class UrlRewrite implements ResolverInterface { - /** - * @var UrlFinderInterface - */ private $urlFinder; - - /** - * @var StoreManagerInterface - */ - private $storeManager; - /** * @var ValueFactory */ private $valueFactory; - - /** - * @var CustomUrlLocatorInterface - */ - private $customUrlLocator; /** - * @param UrlFinderInterface $urlFinder - * @param StoreManagerInterface $storeManager * @param ValueFactory $valueFactory - * @param CustomUrlLocatorInterface $customUrlLocator + * @param UrlFinderInterface $urlFinder */ public function __construct( - UrlFinderInterface $urlFinder, - StoreManagerInterface $storeManager, ValueFactory $valueFactory, - CustomUrlLocatorInterface $customUrlLocator + UrlFinderInterface $urlFinder ) { - $this->urlFinder = $urlFinder; - $this->storeManager = $storeManager; $this->valueFactory = $valueFactory; - $this->customUrlLocator = $customUrlLocator; + $this->urlFinder = $urlFinder; } /** @@ -68,94 +48,58 @@ public function resolve( ResolveInfo $info, array $value = null, array $args = null - ) : Value { - $result = function () { - return null; - }; - - if (isset($args['url'])) { - $url = $args['url']; - if (substr($url, 0, 1) === '/' && $url !== '/') { - $url = ltrim($url, '/'); - } - $customUrl = $this->customUrlLocator->locateUrl($url); - $url = $customUrl ?: $url; - $urlRewrite = $this->findCanonicalUrl($url); - if ($urlRewrite) { - $urlRewriteReturnArray = [ - 'id' => $urlRewrite->getEntityId(), - 'canonical_url' => $urlRewrite->getTargetPath(), - 'type' => $this->sanitizeType($urlRewrite->getEntityType()) - ]; - $result = function () use ($urlRewriteReturnArray) { - return $urlRewriteReturnArray; - }; - } + ): Value { + if (!isset($value['model'])) { + $result = function () { + return null; + }; + return $this->valueFactory->create($result); } - return $this->valueFactory->create($result); - } - /** - * Find the canonical url passing through all redirects if any - * - * @param string $requestPath - * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null - */ - private function findCanonicalUrl(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite - { - $urlRewrite = $this->findUrlFromRequestPath($requestPath); - if ($urlRewrite && $urlRewrite->getRedirectType() > 0) { - while ($urlRewrite && $urlRewrite->getRedirectType() > 0) { - $urlRewrite = $this->findUrlFromRequestPath($urlRewrite->getTargetPath()); + /** @var AbstractModel $entity */ + $entity = $value['model']; + $entityId = $entity->getEntityId(); + + $urlRewritesCollection = $this->urlFinder->findAllByData([UrlRewriteDTO::ENTITY_ID => $entityId]); + $urlRewrites = []; + + /** @var UrlRewriteDTO $urlRewrite */ + foreach ($urlRewritesCollection as $urlRewrite) { + if ($urlRewrite->getRedirectType() !== 0) { + continue; } + + $urlRewrites[] = [ + 'url' => $urlRewrite->getRequestPath(), + 'parameters' => $this->getUrlParameters($urlRewrite->getTargetPath()) + ]; } - if (!$urlRewrite) { - $urlRewrite = $this->findUrlFromTargetPath($requestPath); - } - - return $urlRewrite; - } - /** - * Find a url from a request url on the current store - * - * @param string $requestPath - * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null - */ - private function findUrlFromRequestPath(string $requestPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite - { - return $this->urlFinder->findOneByData( - [ - 'request_path' => $requestPath, - 'store_id' => $this->storeManager->getStore()->getId() - ] - ); + $result = function () use ($urlRewrites) { + return $urlRewrites; + }; + + return $this->valueFactory->create($result); } /** - * Find a url from a target url on the current store + * Parses target path and extracts parameters * * @param string $targetPath - * @return \Magento\UrlRewrite\Service\V1\Data\UrlRewrite|null + * @return array */ - private function findUrlFromTargetPath(string $targetPath) : ?\Magento\UrlRewrite\Service\V1\Data\UrlRewrite + private function getUrlParameters(string $targetPath): array { - return $this->urlFinder->findOneByData( - [ - 'target_path' => $targetPath, - 'store_id' => $this->storeManager->getStore()->getId() - ] - ); - } + $urlParameters = []; + $targetPathParts = explode('/', trim($targetPath, '/')); - /** - * Sanitize the type to fit schema specifications - * - * @param string $type - * @return string - */ - private function sanitizeType(string $type) : string - { - return strtoupper(str_replace('-', '_', $type)); + for ($i = 3; ($i < sizeof($targetPathParts) - 1); $i += 2) { + $urlParameters[] = [ + 'name' => $targetPathParts[$i], + 'value' => $targetPathParts[$i + 1] + ]; + } + + return $urlParameters; } } diff --git a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls index 38f1d9c6563..a0d7a27ffa3 100644 --- a/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls +++ b/app/code/Magento/UrlRewriteGraphQl/etc/schema.graphqls @@ -8,8 +8,18 @@ type EntityUrl @doc(description: "EntityUrl is an output object containing the ` } type Query { - urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\UrlRewrite") @doc(description: "The urlResolver query returns the canonical URL for a specified product, category or CMS page") + urlResolver(url: String!): EntityUrl @resolver(class: "Magento\\UrlRewriteGraphQl\\Model\\Resolver\\EntityUrl") @doc(description: "The urlResolver query returns the canonical URL for a specified product, category or CMS page") } enum UrlRewriteEntityTypeEnum { } + +type UrlRewrite @doc(description: "The object contains URL rewrite details") { + url: String @doc(description: "Request URL") + parameters: [HttpQueryParameter] @doc(description: "Request parameters") +} + +type HttpQueryParameter @doc(description: "The object details of target path parameters") { + name: String @doc(description: "Parameter name") + value: String @doc(description: "Parameter value") +} From 158d1ee422db46ea4794dfb72cb91cf0ca05a474 Mon Sep 17 00:00:00 2001 From: Oleksandr Gorkun Date: Thu, 5 Jul 2018 15:32:13 +0300 Subject: [PATCH 002/189] MAGETWO-92720: E-mail admin users when a new administrator is created. --- .../Adminhtml/Auth/Forgotpassword.php | 15 +- .../User/Controller/Adminhtml/User/Save.php | 7 +- app/code/Magento/User/Model/Notificator.php | 192 +++++ .../User/Model/NotificatorException.php | 20 + .../User/Model/Spi/NotificationException.php | 17 + .../User/Model/Spi/NotificatorInterface.php | 48 ++ app/code/Magento/User/Model/User.php | 87 +-- .../Magento/User/Test/Unit/Model/UserTest.php | 733 +----------------- app/code/Magento/User/etc/adminhtml/di.xml | 1 + app/code/Magento/User/etc/config.xml | 1 + app/code/Magento/User/etc/email_templates.xml | 6 + .../email/new_user_notification.html | 18 + 12 files changed, 382 insertions(+), 763 deletions(-) create mode 100644 app/code/Magento/User/Model/Notificator.php create mode 100644 app/code/Magento/User/Model/NotificatorException.php create mode 100644 app/code/Magento/User/Model/Spi/NotificationException.php create mode 100644 app/code/Magento/User/Model/Spi/NotificatorInterface.php create mode 100644 app/code/Magento/User/view/adminhtml/email/new_user_notification.html diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php index cd4c3d69506..4bd016c1da7 100644 --- a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php +++ b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php @@ -6,7 +6,9 @@ */ namespace Magento\User\Controller\Adminhtml\Auth; +use Magento\Framework\App\ObjectManager; use Magento\Security\Model\SecurityManager; +use Magento\User\Model\Spi\NotificatorInterface; class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth { @@ -15,18 +17,27 @@ class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth */ protected $securityManager; + /** + * @var NotificatorInterface + */ + private $notificator; + /** * @param \Magento\Backend\App\Action\Context $context * @param \Magento\User\Model\UserFactory $userFactory * @param \Magento\Security\Model\SecurityManager $securityManager + * @param NotificatorInterface|null $notificator */ public function __construct( \Magento\Backend\App\Action\Context $context, \Magento\User\Model\UserFactory $userFactory, - \Magento\Security\Model\SecurityManager $securityManager + \Magento\Security\Model\SecurityManager $securityManager, + ?NotificatorInterface $notificator = null ) { parent::__construct($context, $userFactory); $this->securityManager = $securityManager; + $this->notificator = $notificator + ?? ObjectManager::getInstance()->get(NotificatorInterface::class); } /** @@ -70,7 +81,7 @@ public function execute() )->generateResetPasswordLinkToken(); $user->changeResetPasswordLinkToken($newPassResetToken); $user->save(); - $user->sendPasswordResetConfirmationEmail(); + $this->notificator->sendForgotPassword($user); } break; } diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php index 4b984b761c1..e47555e31a7 100644 --- a/app/code/Magento/User/Controller/Adminhtml/User/Save.php +++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php @@ -9,6 +9,7 @@ use Magento\Framework\Exception\AuthenticationException; use Magento\Framework\Exception\State\UserLockedException; use Magento\Security\Model\SecurityCookie; +use Magento\User\Model\Spi\NotificationException; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -87,17 +88,19 @@ public function execute() $currentUser->performIdentityCheck($data[$currentUserPasswordField]); $model->save(); - $model->sendNotificationEmailsIfRequired(); - $this->messageManager->addSuccess(__('You saved the user.')); $this->_getSession()->setUserData(false); $this->_redirect('adminhtml/*/'); + + $model->sendNotificationEmailsIfRequired(); } catch (UserLockedException $e) { $this->_auth->logout(); $this->getSecurityCookie()->setLogoutReasonCookie( \Magento\Security\Model\AdminSessionsManager::LOGOUT_REASON_USER_LOCKED ); $this->_redirect('adminhtml/*/'); + } catch (NotificationException $exception) { + $this->messageManager->addErrorMessage($exception->getMessage()); } catch (\Magento\Framework\Exception\AuthenticationException $e) { $this->messageManager->addError( __('The password entered for the current user is invalid. Verify the password and try again.') diff --git a/app/code/Magento/User/Model/Notificator.php b/app/code/Magento/User/Model/Notificator.php new file mode 100644 index 00000000000..67a0bb030fe --- /dev/null +++ b/app/code/Magento/User/Model/Notificator.php @@ -0,0 +1,192 @@ +transportBuilder = $transportBuilder; + $this->config = $config; + $this->deployConfig = $deployConfig; + $this->storeManager = $storeManager; + } + + /** + * Send a notification. + * + * @param string $templateConfigId + * @param array $templateVars + * @param string $toEmail + * @param string $toName + * @throws MailException + * + * @return void + */ + private function sendNotification( + string $templateConfigId, + array $templateVars, + string $toEmail, + string $toName + ): void { + $transport = $this->transportBuilder + ->setTemplateIdentifier($this->config->getValue($templateConfigId)) + ->setTemplateModel(\Magento\Email\Model\BackendTemplate::class) + ->setTemplateOptions([ + 'area' => FrontNameResolver::AREA_CODE, + 'store' => Store::DEFAULT_STORE_ID + ]) + ->setTemplateVars($templateVars) + ->setFrom( + $this->config->getValue('admin/emails/forgot_email_identity') + ) + ->addTo($toEmail, $toName) + ->getTransport(); + $transport->sendMessage(); + } + + /** + * @inheritDoc + */ + public function sendForgotPassword(UserInterface $user): void + { + try { + $this->sendNotification( + 'admin/emails/forgot_email_template', + [ + 'user' => $user, + 'store' => $this->storeManager->getStore( + Store::DEFAULT_STORE_ID + ) + ], + $user->getEmail(), + $user->getFirstName().' '.$user->getLastName() + ); + } catch (LocalizedException $exception) { + throw new NotificatorException( + __($exception->getMessage()), + $exception + ); + } + } + + /** + * @inheritDoc + */ + public function sendCreated(UserInterface $user): void + { + $toEmails = []; + $generalEmail = $this->config->getValue( + 'trans_email/ident_general/email' + ); + if ($generalEmail) { + $toEmails[] = $generalEmail; + } + if ($adminEmail = $this->deployConfig->get('user_admin_email')) { + $toEmails[] = $adminEmail; + } + + try { + foreach ($toEmails as $toEmail) { + $this->sendNotification( + 'admin/emails/new_user_notification_template', + [ + 'user' => $user, + 'store' => $this->storeManager->getStore( + Store::DEFAULT_STORE_ID + ) + ], + $toEmail, + __('Administrator')->getText() + ); + } + } catch (LocalizedException $exception) { + throw new NotificatorException( + __($exception->getMessage()), + $exception + ); + } + } + + /** + * @inheritDoc + */ + public function sendUpdated(UserInterface $user, array $changed): void + { + $email = $user->getEmail(); + if ($user instanceof User) { + $email = $user->getOrigData('email'); + } + + try { + $this->sendNotification( + 'admin/emails/user_notification_template', + [ + 'user' => $user, + 'store' => $this->storeManager->getStore( + Store::DEFAULT_STORE_ID + ), + 'changes' => implode(', ', $changed) + ], + $email, + $user->getFirstName().' '.$user->getLastName() + ); + } catch (LocalizedException $exception) { + throw new NotificatorException( + __($exception->getMessage()), + $exception + ); + } + } + +} diff --git a/app/code/Magento/User/Model/NotificatorException.php b/app/code/Magento/User/Model/NotificatorException.php new file mode 100644 index 00000000000..10aa28bb206 --- /dev/null +++ b/app/code/Magento/User/Model/NotificatorException.php @@ -0,0 +1,20 @@ +_encryptor = $encryptor; parent::__construct($context, $registry, $resource, $resourceCollection, $data); @@ -166,7 +182,10 @@ public function __construct( $this->_transportBuilder = $transportBuilder; $this->_storeManager = $storeManager; $this->validationRules = $validationRules; - $this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class); + $this->serializer = $serializer + ?: ObjectManager::getInstance()->get(Json::class); + $this->notificator = $notificator + ?: ObjectManager::getInstance()->get(NotificatorInterface::class); } /** @@ -399,22 +418,16 @@ public function roleUserExists() } /** - * Send email with reset password confirmation link + * Send email with reset password confirmation link. + * @deprecated + * @see NotificatorInterface::sendForgotPassword() * * @return $this */ public function sendPasswordResetConfirmationEmail() { - $templateId = $this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_TEMPLATE); - $transport = $this->_transportBuilder->setTemplateIdentifier($templateId) - ->setTemplateModel(\Magento\Email\Model\BackendTemplate::class) - ->setTemplateOptions(['area' => FrontNameResolver::AREA_CODE, 'store' => Store::DEFAULT_STORE_ID]) - ->setTemplateVars(['user' => $this, 'store' => $this->_storeManager->getStore(Store::DEFAULT_STORE_ID)]) - ->setFrom($this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_IDENTITY)) - ->addTo($this->getEmail(), $this->getName()) - ->getTransport(); + $this->notificator->sendForgotPassword($this); - $transport->sendMessage(); return $this; } @@ -431,19 +444,19 @@ public function sendPasswordResetNotificationEmail() } /** - * Check changes and send notification emails + * Check changes and send notification emails. * + * @throws NotificationException * @return $this * @since 100.1.0 */ public function sendNotificationEmailsIfRequired() { - $changes = $this->createChangesDescriptionString(); - - if ($changes) { - if ($this->getEmail() != $this->getOrigData('email') && $this->getOrigData('email')) { - $this->sendUserNotificationEmail($changes, $this->getOrigData('email')); - } + if ($this->isObjectNew()) { + //Notification about a new user. + $this->notificator->sendCreated($this); + } elseif ($changes = $this->createChangesDescriptionString()) { + //User changed. $this->sendUserNotificationEmail($changes); } @@ -478,35 +491,21 @@ protected function createChangesDescriptionString() } /** - * Send user notification email + * Send user notification email. * * @param string $changes * @param string $email + * @throws NotificationException * @return $this * @since 100.1.0 + * @deprecated + * @see NotificatorInterface::sendUpdated() + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ protected function sendUserNotificationEmail($changes, $email = null) { - if ($email === null) { - $email = $this->getEmail(); - } + $this->notificator->sendUpdated($this, explode(', ', $changes)); - $transport = $this->_transportBuilder - ->setTemplateIdentifier($this->_config->getValue(self::XML_PATH_USER_NOTIFICATION_TEMPLATE)) - ->setTemplateModel(\Magento\Email\Model\BackendTemplate::class) - ->setTemplateOptions(['area' => FrontNameResolver::AREA_CODE, 'store' => Store::DEFAULT_STORE_ID]) - ->setTemplateVars( - [ - 'user' => $this, - 'store' => $this->_storeManager->getStore(Store::DEFAULT_STORE_ID), - 'changes' => $changes - ] - ) - ->setFrom($this->_config->getValue(self::XML_PATH_FORGOT_EMAIL_IDENTITY)) - ->addTo($email, $this->getName()) - ->getTransport(); - - $transport->sendMessage(); return $this; } diff --git a/app/code/Magento/User/Test/Unit/Model/UserTest.php b/app/code/Magento/User/Test/Unit/Model/UserTest.php index 4bc5db138c7..aabfe4b1160 100644 --- a/app/code/Magento/User/Test/Unit/Model/UserTest.php +++ b/app/code/Magento/User/Test/Unit/Model/UserTest.php @@ -6,7 +6,9 @@ namespace Magento\User\Test\Unit\Model; -use Magento\Framework\Serialize\Serializer\Json; +use Magento\User\Helper\Data as UserHelper; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\User\Model\User; /** * Test class for \Magento\User\Model\User testing @@ -16,55 +18,11 @@ */ class UserTest extends \PHPUnit\Framework\TestCase { - /** @var \Magento\User\Model\User */ - protected $model; + /** @var User */ + private $model; - /** @var \Magento\User\Helper\Data|\PHPUnit_Framework_MockObject_MockObject */ - protected $userDataMock; - - /** @var \Magento\Framework\Mail\Template\TransportBuilder|\PHPUnit_Framework_MockObject_MockObject */ - protected $transportBuilderMock; - - /** @var \Magento\Framework\Model\Context|\PHPUnit_Framework_MockObject_MockObject */ - protected $contextMock; - - /** @var \Magento\User\Model\ResourceModel\User|\PHPUnit_Framework_MockObject_MockObject */ - protected $resourceMock; - - /** @var \Magento\Framework\Data\Collection\AbstractDb|\PHPUnit_Framework_MockObject_MockObject */ - protected $collectionMock; - - /** @var \Magento\Framework\Mail\TransportInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $transportMock; - - /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $storeManagerMock; - - /** @var \Magento\Store\Model\Store|\PHPUnit_Framework_MockObject_MockObject */ - protected $storeMock; - - /** @var \Magento\Backend\App\ConfigInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $configMock; - - /** @var \Magento\Framework\Encryption\EncryptorInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $encryptorMock; - - /** @var \Magento\Framework\Event\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject */ - protected $eventManagerMock; - - /** @var \Magento\Framework\Validator\DataObjectFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $validatorObjectFactoryMock; - - /** @var \Magento\User\Model\UserValidationRules|\PHPUnit_Framework_MockObject_MockObject */ - protected $validationRulesMock; - - /** @var \Magento\Authorization\Model\RoleFactory|\PHPUnit_Framework_MockObject_MockObject */ - protected $roleFactoryMock; - - /** - * @var Json|\PHPUnit_Framework_MockObject_MockObject - */ - private $serializer; + /** @var UserHelper|\PHPUnit_Framework_MockObject_MockObject */ + private $userDataMock; /** * Set required values @@ -72,307 +30,20 @@ class UserTest extends \PHPUnit\Framework\TestCase */ protected function setUp() { - $this->userDataMock = $this->getMockBuilder(\Magento\User\Helper\Data::class) + $this->userDataMock = $this->getMockBuilder(UserHelper::class) ->disableOriginalConstructor() ->setMethods([]) ->getMock(); - $this->contextMock = $this->getMockBuilder(\Magento\Framework\Model\Context::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->resourceMock = $this->getMockBuilder(\Magento\User\Model\ResourceModel\User::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->collectionMock = $this->getMockBuilder(\Magento\Framework\Data\Collection\AbstractDb::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMockForAbstractClass(); - $coreRegistry = $this->getMockBuilder(\Magento\Framework\Registry::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->eventManagerMock = $this->getMockBuilder(\Magento\Framework\Event\ManagerInterface::class) - ->disableOriginalConstructor() - ->setMethods(['dispatch']) - ->getMockForAbstractClass(); - $this->validatorObjectFactoryMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObjectFactory::class) - ->disableOriginalConstructor()->setMethods(['create']) - ->getMock(); - $this->roleFactoryMock = $this->getMockBuilder(\Magento\Authorization\Model\RoleFactory::class) - ->disableOriginalConstructor() - ->setMethods(['create']) - ->getMock(); - $this->transportMock = $this->getMockBuilder(\Magento\Framework\Mail\TransportInterface::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->transportBuilderMock = $this->getMockBuilder(\Magento\Framework\Mail\Template\TransportBuilder::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->storeMock = $this->getMockBuilder(\Magento\Store\Model\Store::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->storeManagerMock = $this->getMockBuilder(\Magento\Store\Model\StoreManagerInterface::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->configMock = $this->getMockBuilder(\Magento\Backend\App\ConfigInterface::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->validationRulesMock = $this->getMockBuilder(\Magento\User\Model\UserValidationRules::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - - $this->encryptorMock = $this->getMockBuilder(\Magento\Framework\Encryption\EncryptorInterface::class) - ->setMethods(['validateHash']) - ->getMockForAbstractClass(); - - $this->serializer = $this->createPartialMock(Json::class, ['serialize', 'unserialize']); - $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); + $objectManagerHelper = new ObjectManager($this); $this->model = $objectManagerHelper->getObject( - \Magento\User\Model\User::class, + User::class, [ - 'eventManager' => $this->eventManagerMock, 'userData' => $this->userDataMock, - 'registry' => $coreRegistry, - 'resource' => $this->resourceMock, - 'resourceCollection' => $this->collectionMock, - 'validatorObjectFactory' => $this->validatorObjectFactoryMock, - 'roleFactory' => $this->roleFactoryMock, - 'transportBuilder' => $this->transportBuilderMock, - 'storeManager' => $this->storeManagerMock, - 'validationRules' => $this->validationRulesMock, - 'config' => $this->configMock, - 'encryptor' => $this->encryptorMock, - 'serializer' => $this->serializer ] ); } - /** - * @return void - */ - public function testSendNotificationEmailsIfRequired() - { - $storeId = 0; - $email = 'test1@example.com'; - $origEmail = 'test2@example.com'; - - $password = '1234567'; - $origPassword = '123456789'; - - $username = 'admin1'; - $origUsername = 'admin2'; - - $firstName = 'Foo'; - $lastName = 'Bar'; - - $changes = __('email') . ', ' . __('password') . ', ' . __('username'); - - $this->model->setEmail($email); - $this->model->setOrigData('email', $origEmail); - - $this->model->setPassword($password); - $this->model->setOrigData('password', $origPassword); - - $this->model->setUserName($username); - $this->model->setOrigData('username', $origUsername); - - $this->model->setFirstName($firstName); - $this->model->setLastName($lastName); - - $this->configMock->expects($this->exactly(4)) - ->method('getValue') - ->withConsecutive( - [\Magento\User\Model\User::XML_PATH_USER_NOTIFICATION_TEMPLATE], - [\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY], - [\Magento\User\Model\User::XML_PATH_USER_NOTIFICATION_TEMPLATE], - [\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY] - )->willReturnOnConsecutiveCalls( - 'templateId', - 'sender', - 'templateId', - 'sender' - ); - - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('setTemplateModel') - ->with($this->equalTo(\Magento\Email\Model\BackendTemplate::class)) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('setTemplateOptions') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('setTemplateVars') - ->with(['user' => $this->model, 'store' => $this->storeMock, 'changes' => $changes]) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('addTo') - ->withConsecutive( - $this->equalTo($email), - $this->equalTo($firstName . ' ' . $lastName), - $this->equalTo($origEmail), - $this->equalTo($firstName . ' ' . $lastName) - ) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('setFrom') - ->with('sender') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('setTemplateIdentifier') - ->with('templateId') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->exactly(2)) - ->method('getTransport') - ->willReturn($this->transportMock); - $this->transportMock->expects($this->exactly(2))->method('sendMessage'); - - $this->storeManagerMock->expects($this->exactly(2)) - ->method('getStore') - ->with($storeId) - ->willReturn($this->storeMock); - - $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->sendNotificationEmailsIfRequired()); - } - - /** - * @return void - */ - public function testSendPasswordResetConfirmationEmail() - { - $storeId = 0; - $email = 'test@example.com'; - $firstName = 'Foo'; - $lastName = 'Bar'; - - $this->model->setEmail($email); - $this->model->setFirstName($firstName); - $this->model->setLastName($lastName); - - $this->configMock->expects($this->at(0)) - ->method('getValue') - ->with(\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_TEMPLATE) - ->willReturn('templateId'); - $this->configMock->expects($this->at(1)) - ->method('getValue') - ->with(\Magento\User\Model\User::XML_PATH_FORGOT_EMAIL_IDENTITY) - ->willReturn('sender'); - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateModel') - ->with($this->equalTo(\Magento\Email\Model\BackendTemplate::class)) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateOptions') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateVars') - ->with(['user' => $this->model, 'store' => $this->storeMock]) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('addTo') - ->with($this->equalTo($email), $this->equalTo($firstName . ' ' . $lastName)) - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('setFrom') - ->with('sender') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('setTemplateIdentifier') - ->with('templateId') - ->willReturnSelf(); - $this->transportBuilderMock->expects($this->once()) - ->method('getTransport') - ->willReturn($this->transportMock); - $this->transportMock->expects($this->once())->method('sendMessage'); - - $this->storeManagerMock->expects($this->once()) - ->method('getStore') - ->with($storeId) - ->willReturn($this->storeMock); - - $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->sendPasswordResetConfirmationEmail()); - } - - /** - * @return void - */ - public function testVerifyIdentity() - { - $password = 'password'; - $this->encryptorMock - ->expects($this->once()) - ->method('validateHash') - ->with($password, $this->model->getPassword()) - ->willReturn(true); - $this->model->setIsActive(true); - $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->willReturn(true); - $this->assertTrue( - $this->model->verifyIdentity($password), - 'Identity verification failed while should have passed.' - ); - } - - /** - * @return void - */ - public function testVerifyIdentityFailure() - { - $password = 'password'; - $this->encryptorMock - ->expects($this->once()) - ->method('validateHash') - ->with($password, $this->model->getPassword()) - ->willReturn(false); - $this->assertFalse( - $this->model->verifyIdentity($password), - 'Identity verification passed while should have failed.' - ); - } - - /** - * @return void - */ - public function testVerifyIdentityInactiveRecord() - { - $password = 'password'; - $this->encryptorMock - ->expects($this->once()) - ->method('validateHash') - ->with($password, $this->model->getPassword()) - ->willReturn(true); - $this->model->setIsActive(false); - $this->expectException(\Magento\Framework\Exception\AuthenticationException::class); - $this->expectExceptionMessage('The account sign-in was incorrect or your account is disabled temporarily. ' - . 'Please wait and try again later.'); - $this->model->verifyIdentity($password); - } - - /** - * @return void - */ - public function testVerifyIdentityNoAssignedRoles() - { - $password = 'password'; - $this->encryptorMock - ->expects($this->once()) - ->method('validateHash') - ->with($password, $this->model->getPassword()) - ->willReturn(true); - $this->model->setIsActive(true); - $this->resourceMock->expects($this->once())->method('hasAssigned2Role')->willReturn(false); - $this->expectException(\Magento\Framework\Exception\AuthenticationException::class); - $this->expectExceptionMessage('More permissions are needed to access this.'); - $this->model->verifyIdentity($password); - } /** * @return void @@ -399,225 +70,21 @@ public function testSleep() $this->assertEmpty($expectedResult); } - /** - * @return void - */ - public function testBeforeSave() - { - $this->eventManagerMock->expects($this->any())->method('dispatch'); - $this->model->setIsActive(1); - $actualData = $this->model->beforeSave()->getData(); - $this->assertArrayHasKey('extra', $actualData); - $this->assertArrayHasKey('password', $actualData); - $this->assertArrayHasKey('is_active', $actualData); - } - - /** - * @return void - */ - public function testValidateOk() - { - /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ - $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); - $this->validationRulesMock->expects($this->once()) - ->method('addUserInfoRules') - ->with($validatorMock); - $validatorMock->expects($this->once())->method('isValid')->willReturn(true); - $this->assertTrue($this->model->validate()); - } - - /** - * @return void - */ - public function testValidateInvalid() - { - $messages = ['Invalid username']; - /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ - $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); - $this->validationRulesMock->expects($this->once()) - ->method('addUserInfoRules') - ->with($validatorMock); - $validatorMock->expects($this->once())->method('isValid')->willReturn(false); - $validatorMock->expects($this->once())->method('getMessages')->willReturn($messages); - $this->assertEquals($messages, $this->model->validate()); - } - - /** - * @return void - */ - public function testSaveExtra() - { - $data = [1, 2, 3]; - $this->resourceMock->expects($this->once()) - ->method('saveExtra') - ->with($this->model, json_encode($data)); - - $this->serializer->expects($this->once()) - ->method('serialize') - ->with($data) - ->will($this->returnValue(json_encode($data))); - - $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->saveExtra($data)); - } - - /** - * @return void - */ - public function testGetRoles() - { - $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn([]); - $this->assertInternalType('array', $this->model->getRoles()); - } - - /** - * @return void - */ - public function testGetRole() - { - $roles = ['role']; - $roleMock = $this->getMockBuilder(\Magento\Authorization\Model\Role::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock); - $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles); - $roleMock->expects($this->once())->method('load')->with($roles[0]); - $this->assertInstanceOf(\Magento\Authorization\Model\Role::class, $this->model->getRole()); - } - - /** - * @return void - */ - public function testDeleteFromRole() - { - $this->resourceMock->expects($this->once())->method('deleteFromRole')->with($this->model); - $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->deleteFromRole()); - } - - /** - * @return void - */ - public function testRoleUserExistsTrue() - { - $result = ['role']; - $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result); - $this->assertTrue($this->model->roleUserExists()); - } - - /** - * @return void - */ - public function testRoleUserExistsFalse() - { - $result = []; - $this->resourceMock->expects($this->once())->method('roleUserExists')->with($this->model)->willReturn($result); - $this->assertFalse($this->model->roleUserExists()); - } - - /** - * @return void - */ - public function testGetAclRole() - { - $roles = ['role']; - $result = 1; - $roleMock = $this->getMockBuilder(\Magento\Authorization\Model\Role::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->roleFactoryMock->expects($this->once())->method('create')->willReturn($roleMock); - $this->resourceMock->expects($this->once())->method('getRoles')->with($this->model)->willReturn($roles); - $roleMock->expects($this->once())->method('load')->with($roles[0]); - $roleMock->expects($this->once())->method('getId')->willReturn($result); - $this->assertEquals($result, $this->model->getAclRole()); - } - - /** - * @dataProvider authenticateDataProvider - * @param string $usernameIn - * @param string $usernameOut - * @param bool $expectedResult - * @return void - */ - public function testAuthenticate($usernameIn, $usernameOut, $expectedResult) - { - $password = 'password'; - $config = 'config'; - - $data = ['id' => 1, 'is_active' => 1, 'username' => $usernameOut]; - - $this->configMock->expects($this->once()) - ->method('isSetFlag') - ->with('admin/security/use_case_sensitive_login') - ->willReturn($config); - $this->eventManagerMock->expects($this->any())->method('dispatch'); - - $this->resourceMock->expects($this->any())->method('loadByUsername')->willReturn($data); - $this->model->setIdFieldName('id'); - - $this->encryptorMock->expects($this->any())->method('validateHash')->willReturn(true); - $this->resourceMock->expects($this->any())->method('hasAssigned2Role')->willReturn(true); - $this->assertEquals($expectedResult, $this->model->authenticate($usernameIn, $password)); - } - - /** - * @return array - */ - public function authenticateDataProvider() - { - return [ - 'success' => [ - 'usernameIn' => 'username', - 'usernameOut' => 'username', - 'expectedResult' => true - ], - 'failedUsername' => [ - 'usernameIn' => 'username1', - 'usernameOut' => 'username2', - 'expectedResult' => false - ] - ]; - } - - /** - * @expectedException \Magento\Framework\Exception\LocalizedException - * @return void - */ - public function testAuthenticateException() - { - $username = 'username'; - $password = 'password'; - $config = 'config'; - - $this->configMock->expects($this->once()) - ->method('isSetFlag') - ->with('admin/security/use_case_sensitive_login') - ->willReturn($config); - - $this->eventManagerMock->expects($this->any())->method('dispatch'); - $this->resourceMock->expects($this->once()) - ->method('loadByUsername') - ->willThrowException(new \Magento\Framework\Exception\LocalizedException(__())); - $this->model->authenticate($username, $password); - } - /** * @return void */ public function testChangeResetPasswordLinkToken() { $token = '1'; - $this->assertInstanceOf(\Magento\User\Model\User::class, $this->model->changeResetPasswordLinkToken($token)); + $this->assertInstanceOf( + User::class, + $this->model->changeResetPasswordLinkToken($token) + ); $this->assertEquals($token, $this->model->getRpToken()); - $this->assertInternalType('string', $this->model->getRpTokenCreatedAt()); + $this->assertInternalType( + 'string', + $this->model->getRpTokenCreatedAt() + ); } /** @@ -640,168 +107,4 @@ public function testIsResetPasswordLinkTokenExpiredIsExpiredToken() $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(0); $this->assertTrue($this->model->isResetPasswordLinkTokenExpired()); } - - /** - * @return void - */ - public function testIsResetPasswordLinkTokenExpiredIsNotExpiredToken() - { - $this->model->setRpToken('1'); - $this->model->setRpTokenCreatedAt( - (new \DateTime())->format(\Magento\Framework\Stdlib\DateTime::DATETIME_PHP_FORMAT) - ); - $this->userDataMock->expects($this->once())->method('getResetPasswordLinkExpirationPeriod')->willReturn(1); - $this->assertFalse($this->model->isResetPasswordLinkTokenExpired()); - } - - public function testCheckPasswordChangeEqualToCurrent() - { - /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ - $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); - $this->validationRulesMock->expects($this->once()) - ->method('addUserInfoRules') - ->with($validatorMock); - $validatorMock->expects($this->once())->method('isValid')->willReturn(true); - - $newPassword = "NEWmYn3wpassw0rd"; - $oldPassword = "OLDmYn3wpassw0rd"; - $this->model->setPassword($newPassword) - ->setId(1) - ->setOrigData('password', $oldPassword); - $this->encryptorMock->expects($this->once()) - ->method('isValidHash') - ->with($newPassword, $oldPassword) - ->willReturn(true); - $result = $this->model->validate(); - $this->assertInternalType('array', $result); - $this->assertCount(1, $result); - $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]); - } - - public function testCheckPasswordChangeEqualToPrevious() - { - /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ - $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); - $this->validationRulesMock->expects($this->once()) - ->method('addUserInfoRules') - ->with($validatorMock); - $validatorMock->expects($this->once())->method('isValid')->willReturn(true); - - $newPassword = "NEWmYn3wpassw0rd"; - $newPasswordHash = "new password hash"; - $oldPassword = "OLDmYn3wpassw0rd"; - $this->model->setPassword($newPassword) - ->setId(1) - ->setOrigData('password', $oldPassword); - $this->encryptorMock->expects($this->atLeastOnce()) - ->method('isValidHash') - ->will($this->onConsecutiveCalls(false, true)); - - $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', $newPasswordHash]); - - $result = $this->model->validate(); - $this->assertInternalType('array', $result); - $this->assertCount(1, $result); - $this->assertContains("Sorry, but this password has already been used.", (string)$result[0]); - } - - public function testCheckPasswordChangeValid() - { - /** @var $validatorMock \Magento\Framework\Validator\DataObject|\PHPUnit_Framework_MockObject_MockObject */ - $validatorMock = $this->getMockBuilder(\Magento\Framework\Validator\DataObject::class) - ->disableOriginalConstructor() - ->setMethods([]) - ->getMock(); - $this->validatorObjectFactoryMock->expects($this->once())->method('create')->willReturn($validatorMock); - $this->validationRulesMock->expects($this->once()) - ->method('addUserInfoRules') - ->with($validatorMock); - $validatorMock->expects($this->once())->method('isValid')->willReturn(true); - - $newPassword = "NEWmYn3wpassw0rd"; - $oldPassword = "OLDmYn3wpassw0rd"; - $this->model->setPassword($newPassword) - ->setId(1) - ->setOrigData('password', $oldPassword); - $this->encryptorMock->expects($this->atLeastOnce()) - ->method('isValidHash') - ->will($this->onConsecutiveCalls(false, false, false)); - - $this->resourceMock->expects($this->once())->method('getOldPasswords')->willReturn(['hash1', 'hash2']); - - $result = $this->model->validate(); - $this->assertTrue($result); - } - - /** - * Test for performIdentityCheck method - * - * @param bool $verifyIdentityResult - * @param bool $lockExpires - * @dataProvider dataProviderPerformIdentityCheck - */ - public function testPerformIdentityCheck($verifyIdentityResult, $lockExpires) - { - $password = 'qwerty1'; - $userName = 'John Doe'; - - $this->encryptorMock - ->expects($this->once()) - ->method('validateHash') - ->with($password, $this->model->getPassword()) - ->willReturn($verifyIdentityResult); - $this->model->setIsActive(true); - $this->resourceMock->expects($this->any())->method('hasAssigned2Role')->willReturn(true); - - $this->model->setUserName($userName); - $this->model->setLockExpires($lockExpires); - - $this->eventManagerMock->expects($this->any()) - ->method('dispatch') - ->with( - 'admin_user_authenticate_after', - [ - 'username' => $userName, - 'password' => $password, - 'user' => $this->model, - 'result' => $verifyIdentityResult - ] - ) - ->willReturnSelf(); - - if ($lockExpires) { - $this->expectException(\Magento\Framework\Exception\State\UserLockedException::class); - $this->expectExceptionMessage((string)__('Your account is temporarily disabled. Please try again later.')); - } - - if (!$lockExpires && !$verifyIdentityResult) { - $this->expectException(\Magento\Framework\Exception\AuthenticationException::class); - $this->expectExceptionMessage( - (string)__('The password entered for the current user is invalid. Verify the password and try again.') - ); - } - - $this->model->performIdentityCheck($password); - } - - /** - * @return array - */ - public function dataProviderPerformIdentityCheck() - { - return [ - ['verifyIdentityResult' => true, 'lockExpires' => false], - ['verifyIdentityResult' => false, 'lockExpires' => false], - ['verifyIdentityResult' => true, 'lockExpires' => true], - ['verifyIdentityResult' => false, 'lockExpires' => true] - ]; - } } diff --git a/app/code/Magento/User/etc/adminhtml/di.xml b/app/code/Magento/User/etc/adminhtml/di.xml index 58c34552f8c..daa03975db8 100755 --- a/app/code/Magento/User/etc/adminhtml/di.xml +++ b/app/code/Magento/User/etc/adminhtml/di.xml @@ -12,4 +12,5 @@ Magento\Framework\Authorization + diff --git a/app/code/Magento/User/etc/config.xml b/app/code/Magento/User/etc/config.xml index f6a3924b5a2..c1f51bcbece 100644 --- a/app/code/Magento/User/etc/config.xml +++ b/app/code/Magento/User/etc/config.xml @@ -10,6 +10,7 @@ admin_emails_forgot_email_template + admin_emails_new_user_notification_template general admin_emails_user_notification_template diff --git a/app/code/Magento/User/etc/email_templates.xml b/app/code/Magento/User/etc/email_templates.xml index b998f304c24..637c2b799f3 100644 --- a/app/code/Magento/User/etc/email_templates.xml +++ b/app/code/Magento/User/etc/email_templates.xml @@ -8,4 +8,10 @@