AddressRepositoryTest.php 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Customer\Api;
  7. use Magento\Framework\Exception\InputException;
  8. use Magento\Framework\Exception\NoSuchEntityException;
  9. /**
  10. * Integration test for service layer \Magento\Customer\Model\ResourceModel\AddressRepository
  11. *
  12. * @SuppressWarnings(PHPMD.TooManyMethods)
  13. * @SuppressWarnings(PHPMD.ExcessivePublicCount)
  14. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  15. */
  16. class AddressRepositoryTest extends \PHPUnit\Framework\TestCase
  17. {
  18. /** @var AddressRepositoryInterface */
  19. private $repository;
  20. /** @var \Magento\Framework\ObjectManagerInterface */
  21. private $_objectManager;
  22. /** @var \Magento\Customer\Model\Data\Address[] */
  23. private $_expectedAddresses;
  24. /** @var \Magento\Customer\Api\Data\AddressInterfaceFactory */
  25. private $_addressFactory;
  26. /** @var \Magento\Framework\Api\DataObjectHelper */
  27. protected $dataObjectHelper;
  28. protected function setUp()
  29. {
  30. $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  31. $this->repository = $this->_objectManager->create(\Magento\Customer\Api\AddressRepositoryInterface::class);
  32. $this->_addressFactory = $this->_objectManager->create(
  33. \Magento\Customer\Api\Data\AddressInterfaceFactory::class
  34. );
  35. $this->dataObjectHelper = $this->_objectManager->create(\Magento\Framework\Api\DataObjectHelper::class);
  36. $regionFactory = $this->_objectManager->create(\Magento\Customer\Api\Data\RegionInterfaceFactory::class);
  37. $region = $regionFactory->create();
  38. $region->setRegionCode('AL')
  39. ->setRegion('Alabama')
  40. ->setRegionId(1);
  41. $address = $this->_addressFactory->create()
  42. ->setId('1')
  43. ->setCountryId('US')
  44. ->setCustomerId(1)
  45. ->setPostcode('75477')
  46. ->setRegion($region)
  47. ->setStreet(['Green str, 67'])
  48. ->setTelephone('3468676')
  49. ->setCity('CityM')
  50. ->setFirstname('John')
  51. ->setLastname('Smith')
  52. ->setCompany('CompanyName')
  53. ->setRegionId(1);
  54. /* XXX: would it be better to have a clear method for this? */
  55. $address2 = $this->_addressFactory->create()
  56. ->setId('2')
  57. ->setCountryId('US')
  58. ->setCustomerId(1)
  59. ->setPostcode('47676')
  60. ->setRegion($region)
  61. ->setStreet(['Black str, 48'])
  62. ->setCity('CityX')
  63. ->setTelephone('3234676')
  64. ->setFirstname('John')
  65. ->setLastname('Smith')
  66. ->setRegionId(1);
  67. $this->_expectedAddresses = [$address, $address2];
  68. }
  69. protected function tearDown()
  70. {
  71. $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
  72. /** @var \Magento\Customer\Model\CustomerRegistry $customerRegistry */
  73. $customerRegistry = $objectManager->get(\Magento\Customer\Model\CustomerRegistry::class);
  74. $customerRegistry->remove(1);
  75. }
  76. /**
  77. * @magentoDataFixture Magento/Customer/_files/customer.php
  78. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  79. * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
  80. * @magentoAppIsolation enabled
  81. */
  82. public function testSaveAddressChanges()
  83. {
  84. $address = $this->repository->getById(2);
  85. $address->setRegion($address->getRegion());
  86. // change phone #
  87. $address->setTelephone('555' . $address->getTelephone());
  88. $address = $this->repository->save($address);
  89. $this->assertEquals(2, $address->getId());
  90. $savedAddress = $this->repository->getById(2);
  91. $this->assertNotEquals($this->_expectedAddresses[1]->getTelephone(), $savedAddress->getTelephone());
  92. }
  93. /**
  94. * @magentoDataFixture Magento/Customer/_files/customer.php
  95. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  96. * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
  97. * @magentoAppIsolation enabled
  98. * @expectedException \Magento\Framework\Exception\NoSuchEntityException
  99. * @expectedExceptionMessage No such entity with addressId = 4200
  100. */
  101. public function testSaveAddressesIdSetButNotAlreadyExisting()
  102. {
  103. $proposedAddress = $this->_createSecondAddress()->setId(4200);
  104. $this->repository->save($proposedAddress);
  105. }
  106. /**
  107. * @magentoDataFixture Magento/Customer/_files/customer.php
  108. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  109. * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
  110. * @magentoAppIsolation enabled
  111. */
  112. public function testGetAddressById()
  113. {
  114. $addressId = 2;
  115. $address = $this->repository->getById($addressId);
  116. $this->assertEquals($this->_expectedAddresses[1], $address);
  117. }
  118. /**
  119. * @magentoDataFixture Magento/Customer/_files/customer.php
  120. * @expectedException \Magento\Framework\Exception\NoSuchEntityException
  121. * @expectedExceptionMessage No such entity with addressId = 12345
  122. */
  123. public function testGetAddressByIdBadAddressId()
  124. {
  125. $this->repository->getById(12345);
  126. }
  127. /**
  128. * @magentoDataFixture Magento/Customer/_files/customer.php
  129. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  130. * @magentoAppIsolation enabled
  131. */
  132. public function testSaveNewAddress()
  133. {
  134. $proposedAddress = $this->_createSecondAddress()->setCustomerId(1);
  135. $returnedAddress = $this->repository->save($proposedAddress);
  136. $this->assertNotNull($returnedAddress->getId());
  137. $savedAddress = $this->repository->getById($returnedAddress->getId());
  138. $expectedNewAddress = $this->_expectedAddresses[1];
  139. $expectedNewAddress->setId($savedAddress->getId());
  140. $expectedNewAddress->setRegion($this->_expectedAddresses[1]->getRegion());
  141. $this->assertEquals($expectedNewAddress->getExtensionAttributes(), $savedAddress->getExtensionAttributes());
  142. $this->assertEquals(
  143. $expectedNewAddress->getRegion()->getExtensionAttributes(),
  144. $savedAddress->getRegion()->getExtensionAttributes()
  145. );
  146. $this->assertEquals($expectedNewAddress, $savedAddress);
  147. }
  148. /**
  149. * @magentoDataFixture Magento/Customer/_files/customer.php
  150. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  151. * @magentoAppIsolation enabled
  152. */
  153. public function testSaveNewAddressWithAttributes()
  154. {
  155. $proposedAddress = $this->_createFirstAddress()
  156. ->setCustomAttribute('firstname', 'Jane')
  157. ->setCustomAttribute('id', 4200)
  158. ->setCustomAttribute('weird', 'something_strange_with_hair')
  159. ->setId(null)
  160. ->setCustomerId(1);
  161. $returnedAddress = $this->repository->save($proposedAddress);
  162. $savedAddress = $this->repository->getById($returnedAddress->getId());
  163. $this->assertNotEquals($proposedAddress, $savedAddress);
  164. $this->assertArrayNotHasKey(
  165. 'weird',
  166. $savedAddress->getCustomAttributes(),
  167. 'Only valid attributes should be available.'
  168. );
  169. }
  170. /**
  171. * @magentoDataFixture Magento/Customer/_files/customer.php
  172. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  173. * @magentoAppIsolation enabled
  174. */
  175. public function testSaveNewInvalidAddress()
  176. {
  177. $address = $this->_createFirstAddress()
  178. ->setCustomAttribute('firstname', null)
  179. ->setId(null)
  180. ->setFirstname(null)
  181. ->setLastname(null)
  182. ->setCustomerId(1)
  183. ->setRegionId($invalidRegion = 10354);
  184. try {
  185. $this->repository->save($address);
  186. } catch (InputException $exception) {
  187. $this->assertEquals('One or more input exceptions have occurred.', $exception->getMessage());
  188. $errors = $exception->getErrors();
  189. $this->assertCount(3, $errors);
  190. $this->assertEquals('"firstname" is required. Enter and try again.', $errors[0]->getLogMessage());
  191. $this->assertEquals('"lastname" is required. Enter and try again.', $errors[1]->getLogMessage());
  192. $this->assertEquals(
  193. __(
  194. 'Invalid value of "%value" provided for the %fieldName field.',
  195. ['fieldName' => 'regionId', 'value' => $invalidRegion]
  196. ),
  197. $errors[2]->getLogMessage()
  198. );
  199. }
  200. $address->setCountryId($invalidCountry = 'invalid_id');
  201. try {
  202. $this->repository->save($address);
  203. } catch (InputException $exception) {
  204. $this->assertEquals(
  205. 'One or more input exceptions have occurred.',
  206. $exception->getMessage()
  207. );
  208. $errors = $exception->getErrors();
  209. $this->assertCount(3, $errors);
  210. $this->assertEquals(
  211. '"firstname" is required. Enter and try again.',
  212. $errors[0]->getLogMessage()
  213. );
  214. $this->assertEquals(
  215. '"lastname" is required. Enter and try again.',
  216. $errors[1]->getLogMessage()
  217. );
  218. $this->assertEquals(
  219. __(
  220. 'Invalid value of "%value" provided for the %fieldName field.',
  221. ['fieldName' => 'countryId', 'value' => $invalidCountry]
  222. ),
  223. $errors[2]->getLogMessage()
  224. );
  225. }
  226. }
  227. public function testSaveAddressesCustomerIdNotExist()
  228. {
  229. $proposedAddress = $this->_createSecondAddress()->setCustomerId(4200);
  230. try {
  231. $this->repository->save($proposedAddress);
  232. $this->fail('Expected exception not thrown');
  233. } catch (NoSuchEntityException $nsee) {
  234. $this->assertEquals('No such entity with customerId = 4200', $nsee->getMessage());
  235. }
  236. }
  237. public function testSaveAddressesCustomerIdInvalid()
  238. {
  239. $proposedAddress = $this->_createSecondAddress()->setCustomerId('this_is_not_a_valid_id');
  240. try {
  241. $this->repository->save($proposedAddress);
  242. $this->fail('Expected exception not thrown');
  243. } catch (NoSuchEntityException $nsee) {
  244. $this->assertEquals('No such entity with customerId = this_is_not_a_valid_id', $nsee->getMessage());
  245. }
  246. }
  247. /**
  248. * @magentoDataFixture Magento/Customer/_files/customer.php
  249. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  250. */
  251. public function testDeleteAddress()
  252. {
  253. $addressId = 1;
  254. // See that customer already has an address with expected addressId
  255. $addressDataObject = $this->repository->getById($addressId);
  256. $this->assertEquals($addressDataObject->getId(), $addressId);
  257. // Delete the address from the customer
  258. $this->repository->delete($addressDataObject);
  259. // See that address is deleted
  260. try {
  261. $addressDataObject = $this->repository->getById($addressId);
  262. $this->fail("Expected NoSuchEntityException not caught");
  263. } catch (NoSuchEntityException $exception) {
  264. $this->assertEquals('No such entity with addressId = 1', $exception->getMessage());
  265. }
  266. }
  267. /**
  268. * @magentoDataFixture Magento/Customer/_files/customer.php
  269. * @magentoDataFixture Magento/Customer/_files/customer_address.php
  270. */
  271. public function testDeleteAddressById()
  272. {
  273. $addressId = 1;
  274. // See that customer already has an address with expected addressId
  275. $addressDataObject = $this->repository->getById($addressId);
  276. $this->assertEquals($addressDataObject->getId(), $addressId);
  277. // Delete the address from the customer
  278. $this->repository->deleteById($addressId);
  279. // See that address is deleted
  280. try {
  281. $addressDataObject = $this->repository->getById($addressId);
  282. $this->fail("Expected NoSuchEntityException not caught");
  283. } catch (NoSuchEntityException $exception) {
  284. $this->assertEquals('No such entity with addressId = 1', $exception->getMessage());
  285. }
  286. }
  287. /**
  288. * @magentoDataFixture Magento/Customer/_files/customer.php
  289. */
  290. public function testDeleteAddressFromCustomerBadAddressId()
  291. {
  292. try {
  293. $this->repository->deleteById(12345);
  294. $this->fail("Expected NoSuchEntityException not caught");
  295. } catch (NoSuchEntityException $exception) {
  296. $this->assertEquals('No such entity with addressId = 12345', $exception->getMessage());
  297. }
  298. }
  299. /**
  300. * @param \Magento\Framework\Api\Filter[] $filters
  301. * @param \Magento\Framework\Api\Filter[] $filterGroup
  302. * @param array $expectedResult array of expected results indexed by ID
  303. *
  304. * @dataProvider searchAddressDataProvider
  305. *
  306. * @magentoDataFixture Magento/Customer/_files/customer.php
  307. * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php
  308. * @magentoAppIsolation enabled
  309. */
  310. public function testSearchAddresses($filters, $filterGroup, $expectedResult)
  311. {
  312. /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */
  313. $searchBuilder = $this->_objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class);
  314. foreach ($filters as $filter) {
  315. $searchBuilder->addFilters([$filter]);
  316. }
  317. if ($filterGroup !== null) {
  318. $searchBuilder->addFilters($filterGroup);
  319. }
  320. $searchResults = $this->repository->getList($searchBuilder->create());
  321. $this->assertEquals(count($expectedResult), $searchResults->getTotalCount());
  322. /** @var \Magento\Customer\Api\Data\AddressInterface $item */
  323. foreach ($searchResults->getItems() as $item) {
  324. $this->assertEquals(
  325. $expectedResult[$item->getId()]['city'],
  326. $item->getCity()
  327. );
  328. $this->assertEquals(
  329. $expectedResult[$item->getId()]['postcode'],
  330. $item->getPostcode()
  331. );
  332. $this->assertEquals(
  333. $expectedResult[$item->getId()]['firstname'],
  334. $item->getFirstname()
  335. );
  336. unset($expectedResult[$item->getId()]);
  337. }
  338. }
  339. public function searchAddressDataProvider()
  340. {
  341. /**
  342. * @var \Magento\Framework\Api\FilterBuilder $filterBuilder
  343. */
  344. $filterBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
  345. ->create(\Magento\Framework\Api\FilterBuilder::class);
  346. return [
  347. 'Address with postcode 75477' => [
  348. [$filterBuilder->setField('postcode')->setValue('75477')->create()],
  349. null,
  350. [1 => ['city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John']],
  351. ],
  352. 'Address with city CityM' => [
  353. [$filterBuilder->setField('city')->setValue('CityM')->create()],
  354. null,
  355. [1 => ['city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John']],
  356. ],
  357. 'Addresses with firstname John' => [
  358. [$filterBuilder->setField('firstname')->setValue('John')->create()],
  359. null,
  360. [
  361. 1 => ['city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
  362. 2 => ['city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John']
  363. ],
  364. ],
  365. 'Addresses with postcode of either 75477 or 47676' => [
  366. [],
  367. [
  368. $filterBuilder->setField('postcode')->setValue('75477')->create(),
  369. $filterBuilder->setField('postcode')->setValue('47676')->create()
  370. ],
  371. [
  372. 1 => ['city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
  373. 2 => ['city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John']
  374. ],
  375. ],
  376. 'Addresses with postcode greater than 0' => [
  377. [$filterBuilder->setField('postcode')->setValue('0')->setConditionType('gt')->create()],
  378. null,
  379. [
  380. 1 => ['city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'],
  381. 2 => ['city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John']
  382. ],
  383. ]
  384. ];
  385. }
  386. /**
  387. * Helper function that returns an Address Data Object that matches the data from customer_address fixture
  388. *
  389. * @return \Magento\Customer\Api\Data\AddressInterface
  390. */
  391. private function _createFirstAddress()
  392. {
  393. $address = $this->_addressFactory->create();
  394. $this->dataObjectHelper->mergeDataObjects(
  395. \Magento\Customer\Api\Data\AddressInterface::class,
  396. $address,
  397. $this->_expectedAddresses[0]
  398. );
  399. $address->setId(null);
  400. $address->setRegion($this->_expectedAddresses[0]->getRegion());
  401. return $address;
  402. }
  403. /**
  404. * Helper function that returns an Address Data Object that matches the data from customer_two_address fixture
  405. *
  406. * @return \Magento\Customer\Api\Data\AddressInterface
  407. */
  408. private function _createSecondAddress()
  409. {
  410. $address = $this->_addressFactory->create();
  411. $this->dataObjectHelper->mergeDataObjects(
  412. \Magento\Customer\Api\Data\AddressInterface::class,
  413. $address,
  414. $this->_expectedAddresses[1]
  415. );
  416. $address->setId(null);
  417. $address->setRegion($this->_expectedAddresses[1]->getRegion());
  418. return $address;
  419. }
  420. }