![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-customer/Test/Unit/Model/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\Customer\Test\Unit\Model; use Magento\Backend\App\ConfigInterface; use Magento\Customer\Api\CustomerRepositoryInterface; use Magento\Customer\Api\Data\CustomerInterface; use Magento\Customer\Model\Authentication; use Magento\Customer\Model\Customer; use Magento\Customer\Model\CustomerAuthUpdate; use Magento\Customer\Model\CustomerRegistry; use Magento\Customer\Model\Data\CustomerSecure; use Magento\Framework\Encryption\EncryptorInterface; use Magento\Framework\Exception\InvalidEmailOrPasswordException; use Magento\Framework\Stdlib\DateTime; use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ class AuthenticationTest extends TestCase { /** * @var ConfigInterface|MockObject */ private $backendConfigMock; /** * @var CustomerRegistry|MockObject */ private $customerRegistryMock; /** * @var EncryptorInterface|MockObject */ protected $encryptorMock; /** * @var CustomerRepositoryInterface|MockObject */ private $customerRepositoryMock; /** * @var CustomerSecure|MockObject */ private $customerSecureMock; /** * @var Authentication */ private $authentication; /** * @var DateTime */ private $dateTimeMock; /** * @var CustomerAuthUpdate|MockObject */ protected $customerAuthUpdate; /** * @var ObjectManagerHelper */ protected $objectManager; protected function setUp(): void { $this->objectManager = new ObjectManagerHelper($this); $this->backendConfigMock = $this->getMockBuilder(ConfigInterface::class) ->disableOriginalConstructor() ->setMethods(['getValue']) ->getMockForAbstractClass(); $this->customerRegistryMock = $this->createPartialMock( CustomerRegistry::class, ['retrieveSecureData', 'retrieve'] ); $this->customerRepositoryMock = $this->getMockBuilder(CustomerRepositoryInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->encryptorMock = $this->getMockBuilder(EncryptorInterface::class) ->disableOriginalConstructor() ->getMockForAbstractClass(); $this->dateTimeMock = $this->getMockBuilder(DateTime::class) ->disableOriginalConstructor() ->getMock(); $this->dateTimeMock->expects($this->any()) ->method('formatDate') ->willReturn('formattedDate'); $this->customerSecureMock = $this->getMockBuilder(CustomerSecure::class) ->addMethods( [ 'getId', 'getPasswordHash', 'isCustomerLocked', 'getFailuresNum', 'getFirstFailure', 'getLockExpires', 'setFirstFailure', 'setFailuresNum', 'setLockExpires' ] ) ->disableOriginalConstructor() ->getMock(); $this->customerAuthUpdate = $this->getMockBuilder(CustomerAuthUpdate::class) ->disableOriginalConstructor() ->getMock(); $this->authentication = $this->objectManager->getObject( Authentication::class, [ 'customerRegistry' => $this->customerRegistryMock, 'backendConfig' => $this->backendConfigMock, 'customerRepository' => $this->customerRepositoryMock, 'encryptor' => $this->encryptorMock, 'dateTime' => $this->dateTimeMock, ] ); $this->objectManager->setBackwardCompatibleProperty( $this->authentication, 'customerAuthUpdate', $this->customerAuthUpdate ); } public function testProcessAuthenticationFailureLockingIsDisabled() { $customerId = 1; $this->backendConfigMock->expects($this->exactly(2)) ->method('getValue') ->withConsecutive( [Authentication::LOCKOUT_THRESHOLD_PATH], [Authentication::MAX_FAILURES_PATH] ) ->willReturnOnConsecutiveCalls(0, 0); $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') ->with($customerId) ->willReturn($this->customerSecureMock); $this->authentication->processAuthenticationFailure($customerId); } /** * @param int $failureNum * @param string $firstFailure * @param string $lockExpires * @param int $setFailureNumCallCtr * @param int $setFailureNumValue * @param int $setFirstFailureCallCtr * @param int $setFirstFailureValue * @param int $setLockExpiresCallCtr * @param int $setLockExpiresValue * @dataProvider processAuthenticationFailureDataProvider */ public function testProcessAuthenticationFailureFirstAttempt( $failureNum, $firstFailure, $lockExpires, $setFailureNumCallCtr, $setFailureNumValue, $setFirstFailureCallCtr, $setLockExpiresCallCtr, $setLockExpiresValue ) { $customerId = 1; $this->backendConfigMock->expects($this->exactly(2)) ->method('getValue') ->withConsecutive( [Authentication::LOCKOUT_THRESHOLD_PATH], [Authentication::MAX_FAILURES_PATH] ) ->willReturnOnConsecutiveCalls(10, 5); $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') ->with($customerId) ->willReturn($this->customerSecureMock); $this->customerAuthUpdate->expects($this->once()) ->method('saveAuth') ->with($customerId) ->willReturnSelf(); $this->customerSecureMock->expects($this->once())->method('getFailuresNum')->willReturn($failureNum); $this->customerSecureMock->expects($this->once()) ->method('getFirstFailure') ->willReturn($firstFailure ? (new \DateTime())->modify($firstFailure)->format('Y-m-d H:i:s') : null); $this->customerSecureMock->expects($this->once()) ->method('getLockExpires') ->willReturn($lockExpires ? (new \DateTime())->modify($lockExpires)->format('Y-m-d H:i:s') : null); $this->customerSecureMock->expects($this->exactly($setFirstFailureCallCtr))->method('setFirstFailure'); $this->customerSecureMock->expects($this->exactly($setFailureNumCallCtr)) ->method('setFailuresNum') ->with($setFailureNumValue); $this->customerSecureMock->expects($this->exactly($setLockExpiresCallCtr)) ->method('setLockExpires') ->with($setLockExpiresValue); $this->authentication->processAuthenticationFailure($customerId); } /** * @return array */ public function processAuthenticationFailureDataProvider() { return [ 'first attempt' => [0, null, null, 1, 1, 1, 1, null], 'not locked' => [3, '-400 second', null, 1, 4, 0, 0, null], 'lock expired' => [5, '-400 second', '-100 second', 1, 1, 1, 1, null], 'max attempt' => [4, '-400 second', null, 1, 5, 0, 1, 'formattedDate'], ]; } public function testUnlock() { $customerId = 1; $this->customerRegistryMock->expects($this->once()) ->method('retrieveSecureData') ->with($customerId) ->willReturn($this->customerSecureMock); $this->customerAuthUpdate->expects($this->once()) ->method('saveAuth') ->with($customerId) ->willReturnSelf(); $this->customerSecureMock->expects($this->once())->method('setFailuresNum')->with(0); $this->customerSecureMock->expects($this->once())->method('setFirstFailure')->with(null); $this->customerSecureMock->expects($this->once())->method('setLockExpires')->with(null); $this->authentication->unlock($customerId); } /** * @return array */ public function validatePasswordAndLockStatusDataProvider() { return [[true], [false]]; } /** * @return void */ public function testIsLocked() { $customerId = 7; $customerModelMock = $this->getMockBuilder(Customer::class) ->disableOriginalConstructor() ->getMock(); $customerModelMock->expects($this->once()) ->method('isCustomerLocked'); $this->customerRegistryMock->expects($this->once()) ->method('retrieve') ->with($customerId) ->willReturn($customerModelMock); $this->authentication->isLocked($customerId); } /** * @param bool $result * @dataProvider validateCustomerPassword */ public function testAuthenticate($result) { $customerId = 7; $password = '1234567'; $hash = '1b2af329dd0'; $customerMock = $this->getMockForAbstractClass(CustomerInterface::class); $this->customerRepositoryMock->expects($this->any()) ->method('getById') ->willReturn($customerMock); $this->customerSecureMock->expects($this->any()) ->method('getId') ->willReturn($customerId); $this->customerSecureMock->expects($this->once()) ->method('getPasswordHash') ->willReturn($hash); $this->customerRegistryMock->expects($this->any()) ->method('retrieveSecureData') ->with($customerId) ->willReturn($this->customerSecureMock); $this->encryptorMock->expects($this->once()) ->method('validateHash') ->with($password, $hash) ->willReturn($result); if ($result) { $this->assertTrue($this->authentication->authenticate($customerId, $password)); } else { $this->backendConfigMock->expects($this->exactly(2)) ->method('getValue') ->withConsecutive( [Authentication::LOCKOUT_THRESHOLD_PATH], [Authentication::MAX_FAILURES_PATH] ) ->willReturnOnConsecutiveCalls(1, 1); $this->customerSecureMock->expects($this->once()) ->method('isCustomerLocked') ->willReturn(false); $this->customerRegistryMock->expects($this->once()) ->method('retrieve') ->with($customerId) ->willReturn($this->customerSecureMock); $this->customerAuthUpdate->expects($this->once()) ->method('saveAuth') ->with($customerId) ->willReturnSelf(); $this->expectException(InvalidEmailOrPasswordException::class); $this->authentication->authenticate($customerId, $password); } } /** * @return array */ public function validateCustomerPassword() { return [ [true], [false], ]; } }