AccountManagementTest.php 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Model;
  7. use Magento\Customer\Api\AccountManagementInterface;
  8. use Magento\Customer\Api\AddressRepositoryInterface;
  9. use Magento\Customer\Api\CustomerRepositoryInterface;
  10. use Magento\Customer\Api\Data\AddressInterface;
  11. use Magento\Framework\Exception\InputException;
  12. use Magento\Framework\Exception\NoSuchEntityException;
  13. use Magento\Framework\Exception\State\ExpiredException;
  14. use Magento\Framework\Reflection\DataObjectProcessor;
  15. use Magento\TestFramework\Helper\Bootstrap;
  16. /**
  17. * Integration test for service layer \Magento\Customer\Model\AccountManagementTest
  18. *
  19. * @SuppressWarnings(PHPMD.TooManyMethods)
  20. * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  21. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  22. * @magentoAppArea frontend
  23. */
  24. class AccountManagementTest extends \PHPUnit\Framework\TestCase
  25. {
  26. /** @var AccountManagementInterface */
  27. private $accountManagement;
  28. /** @var CustomerRepositoryInterface */
  29. private $customerRepository;
  30. /** @var AddressRepositoryInterface needed to setup tests */
  31. private $addressRepository;
  32. /** @var \Magento\Framework\ObjectManagerInterface */
  33. private $objectManager;
  34. /** @var AddressInterface[] */
  35. private $_expectedAddresses;
  36. /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */
  37. private $addressFactory;
  38. /** @var \Magento\Customer\Api\Data\CustomerInterfaceFactory */
  39. private $customerFactory;
  40. /** @var DataObjectProcessor */
  41. private $dataProcessor;
  42. /** @var \Magento\Framework\Api\ExtensibleDataObjectConverter */
  43. private $extensibleDataObjectConverter;
  44. /** @var \Magento\Framework\Api\DataObjectHelper */
  45. protected $dataObjectHelper;
  46. protected function setUp()
  47. {
  48. $this->objectManager = Bootstrap::getObjectManager();
  49. $this->accountManagement = $this->objectManager
  50. ->create(\Magento\Customer\Api\AccountManagementInterface::class);
  51. $this->customerRepository = $this->objectManager
  52. ->create(\Magento\Customer\Api\CustomerRepositoryInterface::class);
  53. $this->addressRepository =
  54. $this->objectManager->create(\Magento\Customer\Api\AddressRepositoryInterface::class);
  55. $this->addressFactory = $this->objectManager->create(\Magento\Customer\Api\Data\AddressInterfaceFactory::class);
  56. $this->customerFactory = $this->objectManager->create(
  57. \Magento\Customer\Api\Data\CustomerInterfaceFactory::class
  58. );
  59. $this->dataObjectHelper = $this->objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
  60. $regionFactory = $this->objectManager->create(\Magento\Customer\Api\Data\RegionInterfaceFactory::class);
  61. $address = $this->addressFactory->create();
  62. $address->setId('1')
  63. ->setCountryId('US')
  64. ->setCustomerId('1')
  65. ->setPostcode('75477')
  66. ->setRegion(
  67. $regionFactory->create()->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)
  68. )
  69. ->setRegionId(1)
  70. ->setCompany('CompanyName')
  71. ->setStreet(['Green str, 67'])
  72. ->setTelephone('3468676')
  73. ->setCity('CityM')
  74. ->setFirstname('John')
  75. ->setLastname('Smith')
  76. ->setIsDefaultShipping(true)
  77. ->setIsDefaultBilling(true);
  78. $address2 = $this->addressFactory->create();
  79. $address2->setId('2')
  80. ->setCountryId('US')
  81. ->setCustomerId('1')
  82. ->setPostcode('47676')
  83. ->setRegion(
  84. $regionFactory->create()->setRegionCode('AL')->setRegion('Alabama')->setRegionId(1)
  85. )
  86. ->setRegionId(1)
  87. ->setCompany('Company')
  88. ->setStreet(['Black str, 48'])
  89. ->setCity('CityX')
  90. ->setTelephone('3234676')
  91. ->setFirstname('John')
  92. ->setLastname('Smith');
  93. $this->_expectedAddresses = [$address, $address2];
  94. $this->dataProcessor = $this->objectManager
  95. ->create(\Magento\Framework\Reflection\DataObjectProcessor::class);
  96. $this->extensibleDataObjectConverter = $this->objectManager
  97. ->create(\Magento\Framework\Api\ExtensibleDataObjectConverter::class);
  98. }
  99. /**
  100. * Clean up shared dependencies
  101. */
  102. protected function tearDown()
  103. {
  104. /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */
  105. $customerRegistry = $this->objectManager->get(\Magento\Customer\Model\CustomerRegistry::class);
  106. /** @var \Magento\Customer\Model\CustomerRegistry $addressRegistry */
  107. $addressRegistry = $this->objectManager->get(\Magento\Customer\Model\AddressRegistry::class);
  108. //Cleanup customer from registry
  109. $customerRegistry->remove(1);
  110. $addressRegistry->remove(1);
  111. $addressRegistry->remove(2);
  112. }
  113. /**
  114. * @magentoAppArea frontend
  115. * @magentoDataFixture Magento/Customer/_files/customer.php
  116. */
  117. public function testLogin()
  118. {
  119. // Customer email and password are pulled from the fixture customer.php
  120. $customer = $this->accountManagement->authenticate('customer@example.com', 'password');
  121. $this->assertSame('customer@example.com', $customer->getEmail());
  122. }
  123. /**
  124. * @magentoDataFixture Magento/Customer/_files/customer.php
  125. *
  126. * @expectedException \Magento\Framework\Exception\InvalidEmailOrPasswordException
  127. */
  128. public function testLoginWrongPassword()
  129. {
  130. // Customer email and password are pulled from the fixture customer.php
  131. $this->accountManagement->authenticate('customer@example.com', 'wrongPassword');
  132. }
  133. /**
  134. * @expectedException \Magento\Framework\Exception\InvalidEmailOrPasswordException
  135. * @expectedExceptionMessage Invalid login or password.
  136. */
  137. public function testLoginWrongUsername()
  138. {
  139. // Customer email and password are pulled from the fixture customer.php
  140. $this->accountManagement->authenticate('non_existing_user', '_Password123');
  141. }
  142. /**
  143. * @magentoAppArea frontend
  144. * @magentoDataFixture Magento/Customer/_files/customer.php
  145. */
  146. public function testChangePassword()
  147. {
  148. $this->accountManagement->changePassword('customer@example.com', 'password', 'new_Password123');
  149. $this->accountManagement->authenticate('customer@example.com', 'new_Password123');
  150. }
  151. /**
  152. * @magentoDataFixture Magento/Customer/_files/customer.php
  153. *
  154. * @expectedException \Magento\Framework\Exception\InvalidEmailOrPasswordException
  155. * @expectedExceptionMessage The password doesn't match this account. Verify the password and try again.
  156. */
  157. public function testChangePasswordWrongPassword()
  158. {
  159. $this->accountManagement->changePassword('customer@example.com', 'wrongPassword', 'new_Password123');
  160. }
  161. /**
  162. * @expectedException \Magento\Framework\Exception\InvalidEmailOrPasswordException
  163. * @expectedExceptionMessage Invalid login or password.
  164. */
  165. public function testChangePasswordWrongUser()
  166. {
  167. $this->accountManagement->changePassword('wrong.email@example.com', '_Password123', 'new_Password123');
  168. }
  169. /**
  170. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  171. * @magentoAppArea frontend
  172. */
  173. public function testActivateAccount()
  174. {
  175. /** @var \Magento\Customer\Model\Customer $customerModel */
  176. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  177. $customerModel->load(1);
  178. // Assert in just one test that the fixture is working
  179. $this->assertNotNull($customerModel->getConfirmation(), 'New customer needs to be confirmed');
  180. $this->accountManagement->activate($customerModel->getEmail(), $customerModel->getConfirmation());
  181. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  182. $customerModel->load(1);
  183. $this->assertNull($customerModel->getConfirmation(), 'Customer should be considered confirmed now');
  184. }
  185. /**
  186. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  187. * @expectedException \Magento\Framework\Exception\State\InputMismatchException
  188. */
  189. public function testActivateCustomerConfirmationKeyWrongKey()
  190. {
  191. /** @var \Magento\Customer\Model\Customer $customerModel */
  192. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  193. $customerModel->load(1);
  194. $key = $customerModel->getConfirmation();
  195. try {
  196. $this->accountManagement->activate($customerModel->getEmail(), $key . $key);
  197. $this->fail('Expected exception was not thrown');
  198. } catch (InputException $ie) {
  199. $this->assertEquals('', $ie->getMessage());
  200. }
  201. }
  202. /**
  203. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  204. */
  205. public function testActivateCustomerWrongAccount()
  206. {
  207. /** @var \Magento\Customer\Model\Customer $customerModel */
  208. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  209. $customerModel->load(1);
  210. $key = $customerModel->getConfirmation();
  211. try {
  212. $this->accountManagement->activate('1234' . $customerModel->getEmail(), $key);
  213. $this->fail('Expected exception not thrown.');
  214. } catch (NoSuchEntityException $nsee) {
  215. $this->assertEquals(
  216. 'No such entity with email = 1234customer@needAconfirmation.com, websiteId = 1',
  217. $nsee->getMessage()
  218. );
  219. }
  220. }
  221. /**
  222. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  223. * @magentoAppArea frontend
  224. * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
  225. */
  226. public function testActivateCustomerAlreadyActive()
  227. {
  228. /** @var \Magento\Customer\Model\Customer $customerModel */
  229. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  230. $customerModel->load(1);
  231. $key = $customerModel->getConfirmation();
  232. $this->accountManagement->activate($customerModel->getEmail(), $key);
  233. // activate it one more time to produce an exception
  234. $this->accountManagement->activate($customerModel->getEmail(), $key);
  235. }
  236. /**
  237. * @magentoDataFixture Magento/Customer/_files/customer.php
  238. */
  239. public function testValidateResetPasswordLinkToken()
  240. {
  241. $this->setResetPasswordData('token', 'Y-m-d H:i:s');
  242. $this->accountManagement->validateResetPasswordLinkToken(1, 'token');
  243. }
  244. /**
  245. * @magentoDataFixture Magento/Customer/_files/customer.php
  246. * @expectedException \Magento\Framework\Exception\State\ExpiredException
  247. */
  248. public function testValidateResetPasswordLinkTokenExpired()
  249. {
  250. $resetToken = 'lsdj579slkj5987slkj595lkj';
  251. $this->setResetPasswordData($resetToken, '1970-01-01');
  252. $this->accountManagement->validateResetPasswordLinkToken(1, $resetToken);
  253. }
  254. /**
  255. * @magentoDataFixture Magento/Customer/_files/customer.php
  256. */
  257. public function testValidateResetPasswordLinkTokenInvalid()
  258. {
  259. $resetToken = 'lsdj579slkj5987slkj595lkj';
  260. $invalidToken = 0;
  261. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  262. try {
  263. $this->accountManagement->validateResetPasswordLinkToken(1, $invalidToken);
  264. $this->fail('Expected exception not thrown.');
  265. } catch (InputException $ie) {
  266. $this->assertEquals('"%fieldName" is required. Enter and try again.', $ie->getRawMessage());
  267. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getMessage());
  268. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getLogMessage());
  269. $this->assertEmpty($ie->getErrors());
  270. }
  271. }
  272. /**
  273. * @magentoDataFixture Magento/Customer/_files/customer.php
  274. *
  275. */
  276. public function testValidateResetPasswordLinkTokenWrongUser()
  277. {
  278. $resetToken = 'lsdj579slkj5987slkj595lkj';
  279. try {
  280. $this->accountManagement->validateResetPasswordLinkToken(4200, $resetToken);
  281. $this->fail('Expected exception not thrown.');
  282. } catch (NoSuchEntityException $nsee) {
  283. $this->assertEquals('No such entity with customerId = 4200', $nsee->getMessage());
  284. }
  285. }
  286. /**
  287. * Test for resetPassword() method when reset for the second time
  288. *
  289. * @magentoDataFixture Magento/Customer/_files/customer.php
  290. * @expectedException \Magento\Framework\Exception\State\InputMismatchException
  291. */
  292. public function testResetPasswordTokenSecondTime()
  293. {
  294. $resetToken = 'lsdj579slkj5987slkj595lkj';
  295. $password = 'new_Password123';
  296. $email = 'customer@example.com';
  297. $this->setResetPasswordData($resetToken, 'Y-m-d H:i');
  298. $this->assertTrue($this->accountManagement->resetPassword($email, $resetToken, $password));
  299. $this->accountManagement->resetPassword($email, $resetToken, $password);
  300. }
  301. /**
  302. * @magentoDataFixture Magento/Customer/_files/customer.php
  303. *
  304. */
  305. public function testValidateResetPasswordLinkTokenNull()
  306. {
  307. try {
  308. $this->accountManagement->validateResetPasswordLinkToken(1, null);
  309. $this->fail('Expected exception not thrown.');
  310. } catch (InputException $ie) {
  311. $this->assertEquals('"%fieldName" is required. Enter and try again.', $ie->getRawMessage());
  312. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getMessage());
  313. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getLogMessage());
  314. $this->assertEmpty($ie->getErrors());
  315. }
  316. }
  317. /**
  318. * @magentoDataFixture Magento/Customer/_files/customer.php
  319. */
  320. public function testValidateResetPasswordLinkTokenWithoutId()
  321. {
  322. $token = 'randomStr123';
  323. $this->setResetPasswordData($token, 'Y-m-d H:i:s');
  324. $this->assertTrue(
  325. $this->accountManagement->validateResetPasswordLinkToken(null, $token)
  326. );
  327. }
  328. /**
  329. * @magentoDataFixture Magento/Customer/_files/two_customers.php
  330. * @expectedException \Magento\Framework\Exception\State\ExpiredException
  331. */
  332. public function testValidateResetPasswordLinkTokenAmbiguous()
  333. {
  334. $token = 'randomStr123';
  335. $this->setResetPasswordData($token, 'Y-m-d H:i:s', 1);
  336. $this->setResetPasswordData($token, 'Y-m-d H:i:s', 2);
  337. $this->accountManagement->validateResetPasswordLinkToken(null, $token);
  338. }
  339. /**
  340. * @magentoAppArea frontend
  341. * @magentoDataFixture Magento/Customer/_files/customer.php
  342. */
  343. public function testSendPasswordResetLink()
  344. {
  345. $email = 'customer@example.com';
  346. $this->accountManagement->initiatePasswordReset($email, AccountManagement::EMAIL_RESET, 1);
  347. }
  348. /**
  349. * @magentoAppArea frontend
  350. * @magentoDataFixture Magento/Customer/_files/customer.php
  351. */
  352. public function testSendPasswordResetLinkDefaultWebsite()
  353. {
  354. $email = 'customer@example.com';
  355. $this->accountManagement->initiatePasswordReset($email, AccountManagement::EMAIL_RESET);
  356. }
  357. /**
  358. * @magentoDataFixture Magento/Customer/_files/customer.php
  359. *
  360. */
  361. public function testSendPasswordResetLinkBadEmailOrWebsite()
  362. {
  363. $email = 'foo@example.com';
  364. try {
  365. $this->accountManagement->initiatePasswordReset(
  366. $email,
  367. AccountManagement::EMAIL_RESET,
  368. 0
  369. );
  370. $this->fail('Expected exception not thrown.');
  371. } catch (NoSuchEntityException $e) {
  372. $expectedParams = [
  373. 'fieldName' => 'email',
  374. 'fieldValue' => $email,
  375. 'field2Name' => 'websiteId',
  376. 'field2Value' => 0,
  377. ];
  378. $this->assertEquals($expectedParams, $e->getParameters());
  379. }
  380. }
  381. /**
  382. * @magentoDataFixture Magento/Customer/_files/customer.php
  383. */
  384. public function testSendPasswordResetLinkBadEmailDefaultWebsite()
  385. {
  386. $email = 'foo@example.com';
  387. try {
  388. $this->accountManagement->initiatePasswordReset(
  389. $email,
  390. AccountManagement::EMAIL_RESET
  391. );
  392. $this->fail('Expected exception not thrown.');
  393. } catch (NoSuchEntityException $nsee) {
  394. // App area is frontend, so we expect websiteId of 1.
  395. $this->assertEquals('No such entity with email = foo@example.com, websiteId = 1', $nsee->getMessage());
  396. }
  397. }
  398. /**
  399. * @magentoDataFixture Magento/Customer/_files/customer.php
  400. */
  401. public function testResetPassword()
  402. {
  403. $resetToken = 'lsdj579slkj5987slkj595lkj';
  404. $password = 'new_Password123';
  405. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  406. $this->assertTrue($this->accountManagement->resetPassword('customer@example.com', $resetToken, $password));
  407. }
  408. /**
  409. * @magentoDataFixture Magento/Customer/_files/customer.php
  410. */
  411. public function testResetPasswordTokenExpired()
  412. {
  413. $resetToken = 'lsdj579slkj5987slkj595lkj';
  414. $password = 'new_Password123';
  415. $this->setResetPasswordData($resetToken, '1970-01-01');
  416. try {
  417. $this->accountManagement->resetPassword('customer@example.com', $resetToken, $password);
  418. $this->fail('Expected exception not thrown.');
  419. } catch (ExpiredException $e) {
  420. $this->assertEquals('The password token is expired. Reset and try again.', $e->getMessage());
  421. }
  422. }
  423. /**
  424. * @magentoDataFixture Magento/Customer/_files/customer.php
  425. *
  426. */
  427. public function testResetPasswordTokenInvalid()
  428. {
  429. $resetToken = 'lsdj579slkj5987slkj595lkj';
  430. $invalidToken = 0;
  431. $password = 'new_Password123';
  432. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  433. try {
  434. $this->accountManagement->resetPassword('customer@example.com', $invalidToken, $password);
  435. $this->fail('Expected exception not thrown.');
  436. } catch (InputException $ie) {
  437. $this->assertEquals('"%fieldName" is required. Enter and try again.', $ie->getRawMessage());
  438. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getMessage());
  439. $this->assertEquals('"resetPasswordLinkToken" is required. Enter and try again.', $ie->getLogMessage());
  440. $this->assertEmpty($ie->getErrors());
  441. }
  442. }
  443. /**
  444. * @magentoDataFixture Magento/Customer/_files/customer.php
  445. */
  446. public function testResetPasswordTokenWrongUser()
  447. {
  448. $resetToken = 'lsdj579slkj5987slkj595lkj';
  449. $password = 'new_Password123';
  450. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  451. try {
  452. $this->accountManagement->resetPassword('invalid-customer@example.com', $resetToken, $password);
  453. $this->fail('Expected exception not thrown.');
  454. } catch (NoSuchEntityException $nsee) {
  455. $this->assertEquals(
  456. 'No such entity with email = invalid-customer@example.com, websiteId = 1',
  457. $nsee->getMessage()
  458. );
  459. }
  460. }
  461. /**
  462. * @magentoDataFixture Magento/Customer/_files/customer.php
  463. */
  464. public function testResetPasswordTokenInvalidUserEmail()
  465. {
  466. $resetToken = 'lsdj579slkj5987slkj595lkj';
  467. $password = 'new_Password123';
  468. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  469. try {
  470. $this->accountManagement->resetPassword('invalid', $resetToken, $password);
  471. $this->fail('Expected exception not thrown.');
  472. } catch (NoSuchEntityException $e) {
  473. $this->assertEquals('No such entity with email = invalid, websiteId = 1', $e->getMessage());
  474. }
  475. }
  476. /**
  477. * @magentoDataFixture Magento/Customer/_files/customer.php
  478. */
  479. public function testResetPasswordWithoutEmail()
  480. {
  481. $resetToken = 'lsdj579slkj5987slkj595lkj';
  482. $password = 'new_Password123';
  483. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s');
  484. $this->assertTrue(
  485. $this->accountManagement->resetPassword(null, $resetToken, $password)
  486. );
  487. }
  488. /**
  489. * @magentoDataFixture Magento/Customer/_files/two_customers.php
  490. * @expectedException \Magento\Framework\Exception\State\ExpiredException
  491. */
  492. public function testResetPasswordAmbiguousToken()
  493. {
  494. $resetToken = 'lsdj579slkj5987slkj595lkj';
  495. $password = 'new_Password123';
  496. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s', 1);
  497. $this->setResetPasswordData($resetToken, 'Y-m-d H:i:s', 2);
  498. $this->accountManagement->resetPassword(null, $resetToken, $password);
  499. }
  500. /**
  501. * @magentoAppArea frontend
  502. * @magentoAppIsolation enabled
  503. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  504. */
  505. public function testResendConfirmation()
  506. {
  507. $this->accountManagement->resendConfirmation('customer@needAconfirmation.com', 1);
  508. //TODO assert
  509. }
  510. /**
  511. * @magentoAppArea frontend
  512. * @magentoAppIsolation enabled
  513. * @magentoDataFixture Magento/Customer/_files/inactive_customer.php
  514. */
  515. public function testResendConfirmationBadWebsiteId()
  516. {
  517. try {
  518. $this->accountManagement->resendConfirmation('customer@needAconfirmation.com', 'notAWebsiteId');
  519. } catch (NoSuchEntityException $nsee) {
  520. $this->assertEquals(
  521. 'No such entity with email = customer@needAconfirmation.com, websiteId = notAWebsiteId',
  522. $nsee->getMessage()
  523. );
  524. }
  525. }
  526. /**
  527. * @magentoDataFixture Magento/Customer/_files/customer.php
  528. */
  529. public function testResendConfirmationNoEmail()
  530. {
  531. try {
  532. $this->accountManagement->resendConfirmation('wrongemail@example.com', 1);
  533. $this->fail('Expected exception not thrown.');
  534. } catch (NoSuchEntityException $nsee) {
  535. $this->assertEquals(
  536. 'No such entity with email = wrongemail@example.com, websiteId = 1',
  537. $nsee->getMessage()
  538. );
  539. }
  540. }
  541. /**
  542. * @magentoDataFixture Magento/Customer/_files/customer.php
  543. * @expectedException \Magento\Framework\Exception\State\InvalidTransitionException
  544. */
  545. public function testResendConfirmationNotNeeded()
  546. {
  547. $this->accountManagement->resendConfirmation('customer@example.com', 1);
  548. }
  549. /**
  550. * @magentoDbIsolation enabled
  551. */
  552. public function testCreateCustomerException()
  553. {
  554. $customerEntity = $this->customerFactory->create();
  555. try {
  556. $this->accountManagement->createAccount($customerEntity);
  557. $this->fail('Expected exception not thrown');
  558. } catch (InputException $ie) {
  559. $this->assertEquals('The customer email is missing. Enter and try again.', $ie->getMessage());
  560. }
  561. }
  562. /**
  563. * @magentoAppArea frontend
  564. * @magentoDataFixture Magento/Customer/_files/customer.php
  565. * @magentoDbIsolation enabled
  566. */
  567. public function testCreateNonexistingCustomer()
  568. {
  569. $existingCustId = 1;
  570. $existingCustomer = $this->customerRepository->getById($existingCustId);
  571. $email = 'savecustomer@example.com';
  572. $firstName = 'Firstsave';
  573. $lastName = 'Lastsave';
  574. $customerData = array_merge(
  575. $existingCustomer->__toArray(),
  576. [
  577. 'email' => $email,
  578. 'firstname' => $firstName,
  579. 'lastname' => $lastName,
  580. 'id' => null
  581. ]
  582. );
  583. $customerEntity = $this->customerFactory->create();
  584. $this->dataObjectHelper->populateWithArray(
  585. $customerEntity,
  586. $customerData,
  587. \Magento\Customer\Api\Data\CustomerInterface::class
  588. );
  589. $customerAfter = $this->accountManagement->createAccount($customerEntity, '_aPassword1');
  590. $this->assertGreaterThan(0, $customerAfter->getId());
  591. $this->assertEquals($email, $customerAfter->getEmail());
  592. $this->assertEquals($firstName, $customerAfter->getFirstname());
  593. $this->assertEquals($lastName, $customerAfter->getLastname());
  594. $this->accountManagement->authenticate(
  595. $customerAfter->getEmail(),
  596. '_aPassword1'
  597. );
  598. $attributesBefore = $this->extensibleDataObjectConverter->toFlatArray(
  599. $existingCustomer,
  600. [],
  601. \Magento\Customer\Api\Data\CustomerInterface::class
  602. );
  603. $attributesAfter = $this->extensibleDataObjectConverter->toFlatArray(
  604. $customerAfter,
  605. [],
  606. \Magento\Customer\Api\Data\CustomerInterface::class
  607. );
  608. // ignore 'updated_at'
  609. unset($attributesBefore['updated_at']);
  610. unset($attributesAfter['updated_at']);
  611. $inBeforeOnly = array_diff_assoc($attributesBefore, $attributesAfter);
  612. $inAfterOnly = array_diff_assoc($attributesAfter, $attributesBefore);
  613. $expectedInBefore = [
  614. 'email',
  615. 'firstname',
  616. 'id',
  617. 'lastname',
  618. ];
  619. sort($expectedInBefore);
  620. $actualInBeforeOnly = array_keys($inBeforeOnly);
  621. sort($actualInBeforeOnly);
  622. $this->assertEquals($expectedInBefore, $actualInBeforeOnly);
  623. $expectedInAfter = [
  624. 'created_in',
  625. 'email',
  626. 'firstname',
  627. 'id',
  628. 'lastname',
  629. ];
  630. $actualInAfterOnly = array_keys($inAfterOnly);
  631. foreach ($expectedInAfter as $item) {
  632. $this->assertContains($item, $actualInAfterOnly);
  633. }
  634. }
  635. /**
  636. * @magentoDbIsolation enabled
  637. */
  638. public function testCreateCustomerInServiceVsInModel()
  639. {
  640. $email = 'email@example.com';
  641. $email2 = 'email2@example.com';
  642. $firstname = 'Tester';
  643. $lastname = 'McTest';
  644. $groupId = 1;
  645. $password = '_aPassword1';
  646. /** @var \Magento\Customer\Model\Customer $customerModel */
  647. $customerModel = $this->objectManager->create(\Magento\Customer\Model\CustomerFactory::class)->create();
  648. $customerModel->setEmail($email)
  649. ->setFirstname($firstname)
  650. ->setLastname($lastname)
  651. ->setGroupId($groupId)
  652. ->setPassword($password);
  653. $customerModel->save();
  654. /** @var \Magento\Customer\Model\Customer $customerModel */
  655. $savedModel = $this->objectManager
  656. ->create(\Magento\Customer\Model\CustomerFactory::class)
  657. ->create()
  658. ->load($customerModel->getId());
  659. $dataInModel = $savedModel->getData();
  660. $newCustomerEntity = $this->customerFactory->create()
  661. ->setEmail($email2)
  662. ->setFirstname($firstname)
  663. ->setLastname($lastname)
  664. ->setGroupId($groupId);
  665. $customerData = $this->accountManagement->createAccount($newCustomerEntity, $password);
  666. $this->assertNotNull($customerData->getId());
  667. $savedCustomer = $this->customerRepository->getById($customerData->getId());
  668. /** @var \Magento\Framework\Api\SimpleDataObjectConverter $simpleDataObjectConverter */
  669. $simpleDataObjectConverter = Bootstrap::getObjectManager()
  670. ->get(\Magento\Framework\Api\SimpleDataObjectConverter::class);
  671. $dataInService = $simpleDataObjectConverter->toFlatArray(
  672. $savedCustomer,
  673. \Magento\Customer\Api\Data\CustomerInterface::class
  674. );
  675. $expectedDifferences = [
  676. 'created_at',
  677. 'updated_at',
  678. 'email',
  679. 'is_active',
  680. 'entity_id',
  681. 'entity_type_id',
  682. 'password_hash',
  683. 'attribute_set_id',
  684. 'disable_auto_group_change',
  685. 'confirmation',
  686. 'reward_update_notification',
  687. 'reward_warning_notification',
  688. ];
  689. foreach ($dataInModel as $key => $value) {
  690. if (!in_array($key, $expectedDifferences)) {
  691. if ($value === null) {
  692. $this->assertArrayNotHasKey($key, $dataInService);
  693. } else {
  694. if (isset($dataInService[$key])) {
  695. $this->assertEquals($value, $dataInService[$key], 'Failed asserting value for ' . $key);
  696. }
  697. }
  698. }
  699. }
  700. $this->assertEquals($email2, $dataInService['email']);
  701. $this->assertArrayNotHasKey('is_active', $dataInService);
  702. $this->assertArrayNotHasKey('password_hash', $dataInService);
  703. }
  704. /**
  705. * @magentoDbIsolation enabled
  706. */
  707. public function testCreateNewCustomer()
  708. {
  709. $email = 'email@example.com';
  710. $storeId = 1;
  711. $firstname = 'Tester';
  712. $lastname = 'McTest';
  713. $groupId = 1;
  714. $newCustomerEntity = $this->customerFactory->create()
  715. ->setStoreId($storeId)
  716. ->setEmail($email)
  717. ->setFirstname($firstname)
  718. ->setLastname($lastname)
  719. ->setGroupId($groupId);
  720. $savedCustomer = $this->accountManagement->createAccount($newCustomerEntity, '_aPassword1');
  721. $this->assertNotNull($savedCustomer->getId());
  722. $this->assertEquals($email, $savedCustomer->getEmail());
  723. $this->assertEquals($storeId, $savedCustomer->getStoreId());
  724. $this->assertEquals($firstname, $savedCustomer->getFirstname());
  725. $this->assertEquals($lastname, $savedCustomer->getLastname());
  726. $this->assertEquals($groupId, $savedCustomer->getGroupId());
  727. $this->assertTrue(!$savedCustomer->getSuffix());
  728. }
  729. /**
  730. * @magentoDbIsolation enabled
  731. */
  732. public function testCreateNewCustomerWithPasswordHash()
  733. {
  734. $email = 'email@example.com';
  735. $storeId = 1;
  736. $firstname = 'Tester';
  737. $lastname = 'McTest';
  738. $groupId = 1;
  739. $newCustomerEntity = $this->customerFactory->create()
  740. ->setStoreId($storeId)
  741. ->setEmail($email)
  742. ->setFirstname($firstname)
  743. ->setLastname($lastname)
  744. ->setGroupId($groupId);
  745. /** @var \Magento\Framework\Math\Random $mathRandom */
  746. $password = $this->objectManager->get(\Magento\Framework\Math\Random::class)->getRandomString(8);
  747. /** @var \Magento\Framework\Encryption\EncryptorInterface $encryptor */
  748. $encryptor = $this->objectManager->get(\Magento\Framework\Encryption\EncryptorInterface::class);
  749. $passwordHash = $encryptor->getHash($password, true);
  750. $savedCustomer = $this->accountManagement->createAccountWithPasswordHash(
  751. $newCustomerEntity,
  752. $passwordHash
  753. );
  754. $this->assertNotNull($savedCustomer->getId());
  755. $this->assertEquals($email, $savedCustomer->getEmail());
  756. $this->assertEquals($storeId, $savedCustomer->getStoreId());
  757. $this->assertEquals($firstname, $savedCustomer->getFirstname());
  758. $this->assertEquals($lastname, $savedCustomer->getLastname());
  759. $this->assertEquals($groupId, $savedCustomer->getGroupId());
  760. $this->assertTrue(!$savedCustomer->getSuffix());
  761. $this->assertEquals(
  762. $savedCustomer->getId(),
  763. $this->accountManagement->authenticate($email, $password)->getId()
  764. );
  765. }
  766. /**
  767. * @magentoAppArea frontend
  768. * @magentoDataFixture Magento/Customer/_files/customer.php
  769. */
  770. public function testCreateNewCustomerFromClone()
  771. {
  772. $email = 'savecustomer@example.com';
  773. $firstName = 'Firstsave';
  774. $lastname = 'Lastsave';
  775. $existingCustId = 1;
  776. $existingCustomer = $this->customerRepository->getById($existingCustId);
  777. $customerEntity = $this->customerFactory->create();
  778. $this->dataObjectHelper->mergeDataObjects(
  779. \Magento\Customer\Api\Data\CustomerInterface::class,
  780. $customerEntity,
  781. $existingCustomer
  782. );
  783. $customerEntity->setEmail($email)
  784. ->setFirstname($firstName)
  785. ->setLastname($lastname)
  786. ->setId(null);
  787. $customer = $this->accountManagement->createAccount($customerEntity, '_aPassword1');
  788. $this->assertNotEmpty($customer->getId());
  789. $this->assertEquals($email, $customer->getEmail());
  790. $this->assertEquals($firstName, $customer->getFirstname());
  791. $this->assertEquals($lastname, $customer->getLastname());
  792. $this->accountManagement->authenticate(
  793. $customer->getEmail(),
  794. '_aPassword1',
  795. true
  796. );
  797. }
  798. /**
  799. * @magentoDataFixture Magento/Customer/_files/customer.php
  800. */
  801. public function testIsEmailAvailable()
  802. {
  803. $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com', 1));
  804. }
  805. /**
  806. * @magentoDataFixture Magento/Customer/_files/customer.php
  807. */
  808. public function testIsEmailAvailableNoWebsiteSpecified()
  809. {
  810. $this->assertFalse($this->accountManagement->isEmailAvailable('customer@example.com'));
  811. }
  812. /**
  813. * @magentoDataFixture Magento/Customer/_files/customer.php
  814. */
  815. public function testIsEmailAvailableNoWebsiteSpecifiedNonExistent()
  816. {
  817. $this->assertTrue($this->accountManagement->isEmailAvailable('nonexistent@example.com'));
  818. }
  819. public function testIsEmailAvailableNonExistentEmail()
  820. {
  821. $this->assertTrue($this->accountManagement->isEmailAvailable('nonexistent@example.com', 1));
  822. }
  823. /**
  824. * @magentoDataFixture Magento/Customer/_files/customer.php
  825. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  826. * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
  827. */
  828. public function testGetDefaultBillingAddress()
  829. {
  830. $customerId = 1;
  831. $address = $this->accountManagement->getDefaultBillingAddress($customerId);
  832. $expected = $this->dataProcessor->buildOutputDataArray(
  833. $this->_expectedAddresses[0],
  834. \Magento\Customer\Api\Data\AddressInterface::class
  835. );
  836. $result = $this->dataProcessor->buildOutputDataArray(
  837. $address,
  838. \Magento\Customer\Api\Data\AddressInterface::class
  839. );
  840. /*
  841. * TODO : Data builder / populateWithArray currently does not detect
  842. * array type and returns street as string instead of array. Need to fix this.
  843. */
  844. unset($expected[AddressInterface::STREET]);
  845. unset($result[AddressInterface::STREET]);
  846. $this->assertEquals($expected, $result);
  847. }
  848. /**
  849. * @magentoDataFixture Magento/Customer/_files/customer.php
  850. */
  851. public function testSaveNewAddressDefaults()
  852. {
  853. $customerId = 1;
  854. /** @var $addressShipping \Magento\Customer\Api\Data\AddressInterface */
  855. $addressShipping = $this->_expectedAddresses[0]->setId(null);
  856. $addressShipping->setIsDefaultShipping(true)->setIsDefaultBilling(false)->setCustomerId($customerId);
  857. //TODO : Will be fixed as part of fixing populate. For now Region is set as Data Object instead of array
  858. $addressShipping->setRegion($this->_expectedAddresses[0]->getRegion());
  859. /** @var $addressBilling \Magento\Customer\Api\Data\AddressInterface */
  860. $addressBilling = $this->_expectedAddresses[1]->setId(null);
  861. $addressBilling->setIsDefaultBilling(true)->setIsDefaultShipping(false)->setCustomerId($customerId);
  862. //TODO : Will be fixed as part of fixing populate
  863. $addressBilling->setRegion($this->_expectedAddresses[1]->getRegion());
  864. $addressShippingExpected = $this->addressRepository->save($addressShipping);
  865. $addressBillingExpected = $this->addressRepository->save($addressBilling);
  866. /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */
  867. $customerRegistry = $this->objectManager->get(\Magento\Customer\Model\CustomerRegistry::class);
  868. $customerRegistry->remove(1);
  869. // Call api under test
  870. $shippingResponse = $this->accountManagement->getDefaultShippingAddress($customerId);
  871. $billingResponse = $this->accountManagement->getDefaultBillingAddress($customerId);
  872. // Verify if the new Shipping address created is same as returned by the api under test :
  873. // \Magento\Customer\Api\AccountManagementInterface::getDefaultShippingAddress
  874. $addressShippingExpected = $this->dataProcessor->buildOutputDataArray(
  875. $addressShippingExpected,
  876. \Magento\Customer\Api\Data\AddressInterface::class
  877. );
  878. $shippingResponse = $this->dataProcessor->buildOutputDataArray(
  879. $shippingResponse,
  880. \Magento\Customer\Api\Data\AddressInterface::class
  881. );
  882. // Response should have this set since we save as default shipping
  883. $addressShippingExpected[AddressInterface::DEFAULT_SHIPPING] = true;
  884. $this->assertEquals($addressShippingExpected, $shippingResponse);
  885. // Verify if the new Billing address created is same as returned by the api under test :
  886. // \Magento\Customer\Api\AccountManagementInterface::getDefaultShippingAddress
  887. $addressBillingExpected = $this->dataProcessor->buildOutputDataArray(
  888. $addressBillingExpected,
  889. \Magento\Customer\Api\Data\AddressInterface::class
  890. );
  891. $billingResponse = $this->dataProcessor->buildOutputDataArray(
  892. $billingResponse,
  893. \Magento\Customer\Api\Data\AddressInterface::class
  894. );
  895. // Response should have this set since we save as default billing
  896. $addressBillingExpected[AddressInterface::DEFAULT_BILLING] = true;
  897. $this->assertEquals($addressBillingExpected, $billingResponse);
  898. }
  899. /**
  900. * @magentoDataFixture Magento/Customer/_files/customer.php
  901. */
  902. public function testGetDefaultAddressesForNonExistentAddress()
  903. {
  904. $customerId = 1;
  905. $this->assertNull($this->accountManagement->getDefaultBillingAddress($customerId));
  906. $this->assertNull($this->accountManagement->getDefaultShippingAddress($customerId));
  907. }
  908. /**
  909. * Set Rp data to Customer in fixture
  910. *
  911. * @param $resetToken
  912. * @param $date
  913. * @param int $customerIdFromFixture Which customer to use.
  914. * @throws \Exception
  915. */
  916. protected function setResetPasswordData(
  917. $resetToken,
  918. $date,
  919. int $customerIdFromFixture = 1
  920. ) {
  921. /** @var \Magento\Customer\Model\Customer $customerModel */
  922. $customerModel = $this->objectManager->create(\Magento\Customer\Model\Customer::class);
  923. $customerModel->load($customerIdFromFixture);
  924. $customerModel->setRpToken($resetToken);
  925. $customerModel->setRpTokenCreatedAt(date($date));
  926. $customerModel->save();
  927. }
  928. }