GroupRepositoryTest.php 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  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\Customer\Api\Data\GroupInterface;
  8. use Magento\Customer\Model\Data\Group as CustomerGroup;
  9. use Magento\Customer\Model\GroupRegistry;
  10. use Magento\Customer\Model\ResourceModel\GroupRepository;
  11. use Magento\Framework\Api\FilterBuilder;
  12. use Magento\Framework\Api\SearchCriteriaBuilder;
  13. use Magento\Framework\Api\SortOrder;
  14. use Magento\Framework\Api\SortOrderBuilder;
  15. use Magento\Framework\Exception\NoSuchEntityException;
  16. use Magento\TestFramework\Helper\Bootstrap;
  17. use Magento\TestFramework\TestCase\WebapiAbstract;
  18. /**
  19. * Class GroupRepositoryTest
  20. *
  21. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  22. */
  23. class GroupRepositoryTest extends WebapiAbstract
  24. {
  25. const SERVICE_NAME = "customerGroupRepositoryV1";
  26. const SERVICE_VERSION = "V1";
  27. const RESOURCE_PATH = "/V1/customerGroups";
  28. /**
  29. * @var GroupRegistry
  30. */
  31. private $groupRegistry;
  32. /**
  33. * @var GroupRepository
  34. */
  35. private $groupRepository;
  36. /**
  37. * @var \Magento\Customer\Api\Data\groupInterfaceFactory
  38. */
  39. private $customerGroupFactory;
  40. /**
  41. * Execute per test initialization.
  42. */
  43. public function setUp()
  44. {
  45. $objectManager = Bootstrap::getObjectManager();
  46. $this->groupRegistry = $objectManager->get(\Magento\Customer\Model\GroupRegistry::class);
  47. $this->groupRepository = $objectManager->get(\Magento\Customer\Model\ResourceModel\GroupRepository::class);
  48. $this->customerGroupFactory = $objectManager->create(\Magento\Customer\Api\Data\GroupInterfaceFactory::class);
  49. }
  50. /**
  51. * Execute per test cleanup.
  52. */
  53. public function tearDown()
  54. {
  55. parent::tearDown();
  56. }
  57. /**
  58. * Cleaning up the extra groups that might have been created as part of the testing.
  59. */
  60. public static function tearDownAfterClass()
  61. {
  62. parent::tearDownAfterClass();
  63. }
  64. /**
  65. * Verify the retrieval of a customer group by Id.
  66. *
  67. * @param array $testGroup The group data for the group being retrieved.
  68. *
  69. * @dataProvider getGroupDataProvider
  70. */
  71. public function testGetGroupById($testGroup)
  72. {
  73. $groupId = $testGroup[CustomerGroup::ID];
  74. $serviceInfo = [
  75. 'rest' => [
  76. 'resourcePath' => self::RESOURCE_PATH . "/$groupId",
  77. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  78. ],
  79. 'soap' => [
  80. 'service' => self::SERVICE_NAME,
  81. 'serviceVersion' => self::SERVICE_VERSION,
  82. 'operation' => 'customerGroupRepositoryV1GetById',
  83. ],
  84. ];
  85. $requestData = [CustomerGroup::ID => $groupId];
  86. $groupData = $this->_webApiCall($serviceInfo, $requestData);
  87. $this->assertEquals($testGroup, $groupData, "The group data does not match.");
  88. }
  89. /**
  90. * The testGetGroup data provider.
  91. *
  92. * @return array
  93. */
  94. public function getGroupDataProvider()
  95. {
  96. return [
  97. 'NOT LOGGED IN' => [
  98. [
  99. CustomerGroup::ID => 0,
  100. CustomerGroup::CODE => 'NOT LOGGED IN',
  101. CustomerGroup::TAX_CLASS_ID => 3,
  102. CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
  103. ],
  104. ],
  105. 'General' => [
  106. [
  107. CustomerGroup::ID => 1,
  108. CustomerGroup::CODE => 'General',
  109. CustomerGroup::TAX_CLASS_ID => 3,
  110. CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
  111. ],
  112. ],
  113. 'Wholesale' => [
  114. [
  115. CustomerGroup::ID => 2,
  116. CustomerGroup::CODE => 'Wholesale',
  117. CustomerGroup::TAX_CLASS_ID => 3,
  118. CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
  119. ],
  120. ],
  121. 'Retailer' => [
  122. [
  123. CustomerGroup::ID => 3,
  124. CustomerGroup::CODE => 'Retailer',
  125. CustomerGroup::TAX_CLASS_ID => 3,
  126. CustomerGroup::TAX_CLASS_NAME => 'Retail Customer',
  127. ],
  128. ],
  129. ];
  130. }
  131. /**
  132. * Verify that creating a new group works via REST.
  133. */
  134. public function testCreateGroupRest()
  135. {
  136. $this->_markTestAsRestOnly();
  137. $serviceInfo = [
  138. 'rest' => [
  139. 'resourcePath' => self::RESOURCE_PATH,
  140. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  141. ],
  142. ];
  143. $groupData = [
  144. CustomerGroup::ID => null,
  145. CustomerGroup::CODE => 'Create Group REST',
  146. CustomerGroup::TAX_CLASS_ID => 3,
  147. ];
  148. $requestData = ['group' => $groupData];
  149. $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
  150. $this->assertNotNull($groupId);
  151. $newGroup = $this->groupRepository->getById($groupId);
  152. $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
  153. $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), 'The group code does not match.');
  154. $this->assertEquals(
  155. $groupData[CustomerGroup::TAX_CLASS_ID],
  156. $newGroup->getTaxClassId(),
  157. 'The group tax class id does not match.'
  158. );
  159. }
  160. /**
  161. * Verify that creating a new group with a duplicate group name fails with an error via REST.
  162. */
  163. public function testCreateGroupDuplicateGroupRest()
  164. {
  165. $this->_markTestAsRestOnly();
  166. $duplicateGroupCode = 'Duplicate Group Code REST';
  167. $group = $this->customerGroupFactory->create();
  168. $group->setId(null);
  169. $group->setCode($duplicateGroupCode);
  170. $group->setTaxClassId(3);
  171. $this->createGroup($group);
  172. $serviceInfo = [
  173. 'rest' => [
  174. 'resourcePath' => self::RESOURCE_PATH,
  175. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  176. ],
  177. ];
  178. $groupData = [
  179. CustomerGroup::ID => null,
  180. CustomerGroup::CODE => $duplicateGroupCode,
  181. CustomerGroup::TAX_CLASS_ID => 3,
  182. ];
  183. $requestData = ['group' => $groupData];
  184. try {
  185. $this->_webApiCall($serviceInfo, $requestData);
  186. $this->fail("Expected exception");
  187. } catch (\Exception $e) {
  188. $errorData = json_decode($e->getMessage(), true);
  189. $this->assertEquals(
  190. 'Customer Group already exists.',
  191. $errorData['message']
  192. );
  193. $this->assertEquals(400, $e->getCode(), 'Invalid HTTP code');
  194. }
  195. }
  196. /**
  197. * Verify that creating a new group works via REST if tax class id is empty, defaults 3.
  198. */
  199. public function testCreateGroupDefaultTaxClassIdRest()
  200. {
  201. $this->_markTestAsRestOnly();
  202. $serviceInfo = [
  203. 'rest' => [
  204. 'resourcePath' => self::RESOURCE_PATH,
  205. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  206. ],
  207. ];
  208. $groupData = [
  209. CustomerGroup::ID => null,
  210. CustomerGroup::CODE => 'Default Class Tax ID REST',
  211. CustomerGroup::TAX_CLASS_ID => null,
  212. ];
  213. $requestData = ['group' => $groupData];
  214. $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
  215. $this->assertNotNull($groupId);
  216. $newGroup = $this->groupRepository->getById($groupId);
  217. $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
  218. $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), 'The group code does not match.');
  219. $this->assertEquals(
  220. GroupRepository::DEFAULT_TAX_CLASS_ID,
  221. $newGroup->getTaxClassId(),
  222. 'The group tax class id does not match.'
  223. );
  224. }
  225. /**
  226. * Verify that creating a new group without a code fails with an error.
  227. */
  228. public function testCreateGroupNoCodeExpectExceptionRest()
  229. {
  230. $this->_markTestAsRestOnly();
  231. $serviceInfo = [
  232. 'rest' => [
  233. 'resourcePath' => self::RESOURCE_PATH,
  234. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  235. ],
  236. ];
  237. $groupData = [
  238. CustomerGroup::ID => null,
  239. CustomerGroup::CODE => null,
  240. CustomerGroup::TAX_CLASS_ID => null,
  241. ];
  242. $requestData = ['group' => $groupData];
  243. try {
  244. $this->_webApiCall($serviceInfo, $requestData);
  245. $this->fail("Expected exception");
  246. } catch (\Exception $e) {
  247. // @codingStandardsIgnoreStart
  248. $this->assertContains(
  249. '\"%fieldName\" is required. Enter and try again.","parameters":{"fieldName":"code"}',
  250. $e->getMessage(),
  251. "Exception does not contain expected message."
  252. );
  253. // @codingStandardsIgnoreEnd
  254. }
  255. }
  256. /**
  257. * Verify that creating a new group with an invalid tax class id fails with an error.
  258. */
  259. public function testCreateGroupInvalidTaxClassIdRest()
  260. {
  261. $this->_markTestAsRestOnly();
  262. $invalidTaxClassId = 9999;
  263. $serviceInfo = [
  264. 'rest' => [
  265. 'resourcePath' => self::RESOURCE_PATH,
  266. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  267. ],
  268. ];
  269. $groupData = [
  270. CustomerGroup::ID => null,
  271. CustomerGroup::CODE => 'Invalid Tax Class Id Code',
  272. CustomerGroup::TAX_CLASS_ID => $invalidTaxClassId,
  273. ];
  274. $requestData = ['group' => $groupData];
  275. try {
  276. $this->_webApiCall($serviceInfo, $requestData);
  277. $this->fail("Expected exception");
  278. } catch (\Exception $e) {
  279. // @codingStandardsIgnoreStart
  280. $this->assertContains(
  281. '{"message":"Invalid value of \"%value\" provided for the %fieldName field.","parameters":{"fieldName":"taxClassId","value":9999}',
  282. $e->getMessage(),
  283. "Exception does not contain expected message."
  284. );
  285. // codingStandardsIgnoreEnd
  286. }
  287. }
  288. /**
  289. * Verify that an attempt to update via POST is not allowed.
  290. */
  291. public function testCreateGroupWithIdRest()
  292. {
  293. $this->_markTestAsRestOnly();
  294. $serviceInfo = [
  295. 'rest' => [
  296. 'resourcePath' => self::RESOURCE_PATH,
  297. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_POST,
  298. ],
  299. ];
  300. $groupData = [
  301. CustomerGroup::ID => 88,
  302. CustomerGroup::CODE => 'Create Group With Id REST',
  303. CustomerGroup::TAX_CLASS_ID => 3,
  304. ];
  305. $requestData = ['group' => $groupData];
  306. try {
  307. $this->_webApiCall($serviceInfo, $requestData);
  308. $this->fail('Expected exception');
  309. } catch (\Exception $e) {
  310. $this->assertContains(
  311. '{"message":"No such entity with %fieldName = %fieldValue","parameters":{"fieldName":"id","fieldValue":88}',
  312. $e->getMessage(),
  313. "Exception does not contain expected message."
  314. );
  315. }
  316. }
  317. /**
  318. * Verify that creating a new group fails via SOAP if there is an Id specified.
  319. */
  320. public function testCreateGroupWithIdSoap()
  321. {
  322. $this->_markTestAsSoapOnly();
  323. $serviceInfo = [
  324. 'soap' => [
  325. 'service' => self::SERVICE_NAME,
  326. 'serviceVersion' => self::SERVICE_VERSION,
  327. 'operation' => 'customerGroupRepositoryV1Save',
  328. ],
  329. ];
  330. $groupData = [
  331. CustomerGroup::ID => 88,
  332. CustomerGroup::CODE => 'Create Group with Id SOAP',
  333. CustomerGroup::TAX_CLASS_ID => 3,
  334. ];
  335. $requestData = ['group' => $groupData];
  336. try {
  337. $this->_webApiCall($serviceInfo, $requestData);
  338. $this->fail("Expected exception");
  339. } catch (\SoapFault $e) {
  340. $this->assertContains(
  341. 'No such entity with %fieldName = %fieldValue',
  342. $e->getMessage(),
  343. "SoapFault does not contain expected message."
  344. );
  345. }
  346. }
  347. /**
  348. * Verify that updating an existing group works via REST.
  349. */
  350. public function testUpdateGroupRest()
  351. {
  352. $this->_markTestAsRestOnly();
  353. $group = $this->customerGroupFactory->create();
  354. $group->setId(null);
  355. $group->setCode('New Group REST');
  356. $group->setTaxClassId(3);
  357. $groupId = $this->createGroup($group);
  358. $serviceInfo = [
  359. 'rest' => [
  360. 'resourcePath' => self::RESOURCE_PATH . "/$groupId",
  361. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
  362. ],
  363. ];
  364. $groupData = [
  365. CustomerGroup::ID => $groupId,
  366. CustomerGroup::CODE => 'Updated Group REST',
  367. CustomerGroup::TAX_CLASS_ID => 3,
  368. ];
  369. $requestData = ['group' => $groupData];
  370. $this->assertEquals($groupId, $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID]);
  371. $group = $this->groupRepository->getById($groupId);
  372. $this->assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
  373. $this->assertEquals(
  374. $groupData[CustomerGroup::TAX_CLASS_ID],
  375. $group->getTaxClassId(),
  376. 'The group tax class id did not change'
  377. );
  378. }
  379. /**
  380. * Verify that updating a non-existing group throws an exception.
  381. */
  382. public function testUpdateGroupNotExistingGroupRest()
  383. {
  384. $this->_markTestAsRestOnly();
  385. $nonExistentGroupId = '9999';
  386. $serviceInfo = [
  387. 'rest' => [
  388. 'resourcePath' => self::RESOURCE_PATH . "/$nonExistentGroupId",
  389. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_PUT,
  390. ],
  391. ];
  392. $groupData = [
  393. CustomerGroup::ID => $nonExistentGroupId,
  394. CustomerGroup::CODE => 'Updated Group REST Does Not Exist',
  395. CustomerGroup::TAX_CLASS_ID => 3,
  396. ];
  397. $requestData = ['group' => $groupData];
  398. try {
  399. $this->_webApiCall($serviceInfo, $requestData);
  400. $this->fail('Expected exception');
  401. } catch (\Exception $e) {
  402. $expectedMessage = '{"message":"No such entity with %fieldName = %fieldValue",'
  403. . '"parameters":{"fieldName":"id","fieldValue":9999}';
  404. $this->assertContains(
  405. $expectedMessage,
  406. $e->getMessage(),
  407. "Exception does not contain expected message."
  408. );
  409. }
  410. }
  411. /**
  412. * Verify that creating a new group works via SOAP.
  413. */
  414. public function testCreateGroupSoap()
  415. {
  416. $this->_markTestAsSoapOnly();
  417. $serviceInfo = [
  418. 'soap' => [
  419. 'service' => self::SERVICE_NAME,
  420. 'serviceVersion' => self::SERVICE_VERSION,
  421. 'operation' => 'customerGroupRepositoryV1Save',
  422. ],
  423. ];
  424. $groupData = [
  425. CustomerGroup::ID => null,
  426. CustomerGroup::CODE => 'Create Group SOAP',
  427. 'taxClassId' => 3,
  428. ];
  429. $requestData = ['group' => $groupData];
  430. $groupId = $this->_webApiCall($serviceInfo, $requestData)[CustomerGroup::ID];
  431. $this->assertNotNull($groupId);
  432. $newGroup = $this->groupRepository->getById($groupId);
  433. $this->assertEquals($groupId, $newGroup->getId(), "The group id does not match.");
  434. $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), "The group code does not match.");
  435. $this->assertEquals(
  436. $groupData['taxClassId'],
  437. $newGroup->getTaxClassId(),
  438. "The group tax class id does not match."
  439. );
  440. }
  441. /**
  442. * Verify that creating a new group with a duplicate code fails with an error via SOAP.
  443. */
  444. public function testCreateGroupDuplicateGroupSoap()
  445. {
  446. $this->_markTestAsSoapOnly();
  447. $group = $this->customerGroupFactory->create();
  448. $duplicateGroupCode = 'Duplicate Group Code SOAP';
  449. $group->setId(null);
  450. $group->setCode($duplicateGroupCode);
  451. $group->setTaxClassId(3);
  452. $this->createGroup($group);
  453. $serviceInfo = [
  454. 'soap' => [
  455. 'service' => self::SERVICE_NAME,
  456. 'serviceVersion' => self::SERVICE_VERSION,
  457. 'operation' => 'customerGroupRepositoryV1Save',
  458. ],
  459. ];
  460. $groupData = [
  461. CustomerGroup::ID => null,
  462. CustomerGroup::CODE => $duplicateGroupCode,
  463. 'taxClassId' => 3,
  464. ];
  465. $requestData = ['group' => $groupData];
  466. $expectedMessage = 'Customer Group already exists.';
  467. try {
  468. $this->_webApiCall($serviceInfo, $requestData);
  469. $this->fail("Expected exception");
  470. } catch (\SoapFault $e) {
  471. $this->assertContains(
  472. $expectedMessage,
  473. $e->getMessage(),
  474. "Exception does not contain expected message."
  475. );
  476. }
  477. }
  478. /**
  479. * Verify that creating a new group works via SOAP if tax class id is empty, defaults 3.
  480. */
  481. public function testCreateGroupDefaultTaxClassIdSoap()
  482. {
  483. $this->_markTestAsSoapOnly();
  484. $serviceInfo = [
  485. 'soap' => [
  486. 'service' => self::SERVICE_NAME,
  487. 'serviceVersion' => self::SERVICE_VERSION,
  488. 'operation' => 'customerGroupRepositoryV1Save',
  489. ],
  490. ];
  491. $groupData = [
  492. CustomerGroup::ID => null,
  493. CustomerGroup::CODE => 'Default Class Tax ID SOAP',
  494. 'taxClassId' => null,
  495. 'taxClassName' => null,
  496. ];
  497. $requestData = ['group' => $groupData];
  498. $groupResponseData = $this->_webApiCall($serviceInfo, $requestData);
  499. $groupId = $groupResponseData[CustomerGroup::ID];
  500. $this->assertNotNull($groupId);
  501. $newGroup = $this->groupRepository->getById($groupId);
  502. $this->assertEquals($groupId, $newGroup->getId(), "The group id does not match.");
  503. $this->assertEquals($groupData[CustomerGroup::CODE], $newGroup->getCode(), "The group code does not match.");
  504. $this->assertEquals(
  505. GroupRepository::DEFAULT_TAX_CLASS_ID,
  506. $newGroup->getTaxClassId(),
  507. "The group tax class id does not match."
  508. );
  509. }
  510. /**
  511. * Verify that creating a new group without a code fails with an error.
  512. */
  513. public function testCreateGroupNoCodeExpectExceptionSoap()
  514. {
  515. $this->_markTestAsSoapOnly();
  516. $serviceInfo = [
  517. 'soap' => [
  518. 'service' => self::SERVICE_NAME,
  519. 'serviceVersion' => self::SERVICE_VERSION,
  520. 'operation' => 'customerGroupRepositoryV1Save',
  521. ],
  522. ];
  523. $groupData = [
  524. CustomerGroup::ID => null,
  525. CustomerGroup::CODE => null,
  526. 'taxClassId' => null,
  527. ];
  528. $requestData = ['group' => $groupData];
  529. try {
  530. $this->_webApiCall($serviceInfo, $requestData);
  531. $this->fail("Expected exception");
  532. } catch (\SoapFault $e) {
  533. $this->assertContains(
  534. '"%fieldName" is required. Enter and try again.',
  535. $e->getMessage(),
  536. "SoapFault does not contain expected message."
  537. );
  538. }
  539. }
  540. /**
  541. * Verify that creating a new group fails via SOAP if tax class id is invalid.
  542. */
  543. public function testCreateGroupInvalidTaxClassIdSoap()
  544. {
  545. $this->_markTestAsSoapOnly();
  546. $invalidTaxClassId = 9999;
  547. $serviceInfo = [
  548. 'soap' => [
  549. 'service' => self::SERVICE_NAME,
  550. 'serviceVersion' => self::SERVICE_VERSION,
  551. 'operation' => 'customerGroupRepositoryV1Save',
  552. ],
  553. ];
  554. $groupData = [
  555. CustomerGroup::ID => null,
  556. CustomerGroup::CODE => 'Invalid Class Tax ID SOAP',
  557. 'taxClassId' => $invalidTaxClassId,
  558. ];
  559. $requestData = ['group' => $groupData];
  560. $expectedMessage = 'Invalid value of "%value" provided for the %fieldName field.';
  561. try {
  562. $this->_webApiCall($serviceInfo, $requestData);
  563. $this->fail("Expected exception");
  564. } catch (\SoapFault $e) {
  565. $this->assertContains(
  566. $expectedMessage,
  567. $e->getMessage(),
  568. "SoapFault does not contain expected message."
  569. );
  570. }
  571. }
  572. /**
  573. * Verify that updating an existing group works via SOAP.
  574. */
  575. public function testUpdateGroupSoap()
  576. {
  577. $this->_markTestAsSoapOnly();
  578. $group = $this->customerGroupFactory->create();
  579. $group->setId(null);
  580. $group->setCode('New Group SOAP');
  581. $group->setTaxClassId(3);
  582. $groupId = $this->createGroup($group);
  583. $serviceInfo = [
  584. 'soap' => [
  585. 'service' => self::SERVICE_NAME,
  586. 'serviceVersion' => self::SERVICE_VERSION,
  587. 'operation' => 'customerGroupRepositoryV1Save',
  588. ],
  589. ];
  590. $groupData = [
  591. CustomerGroup::ID => $groupId,
  592. CustomerGroup::CODE => 'Updated Group SOAP',
  593. 'taxClassId' => 3,
  594. ];
  595. $this->_webApiCall($serviceInfo, ['group' => $groupData]);
  596. $group = $this->groupRepository->getById($groupId);
  597. $this->assertEquals($groupData[CustomerGroup::CODE], $group->getCode(), 'The group code did not change.');
  598. $this->assertEquals(
  599. $groupData['taxClassId'],
  600. $group->getTaxClassId(),
  601. 'The group tax class id did not change'
  602. );
  603. }
  604. /**
  605. * Verify that updating a non-existing group throws an exception via SOAP.
  606. */
  607. public function testUpdateGroupNotExistingGroupSoap()
  608. {
  609. $this->_markTestAsSoapOnly();
  610. $nonExistentGroupId = '9999';
  611. $serviceInfo = [
  612. 'soap' => [
  613. 'service' => self::SERVICE_NAME,
  614. 'serviceVersion' => self::SERVICE_VERSION,
  615. 'operation' => 'customerGroupRepositoryV1Save',
  616. ],
  617. ];
  618. $groupData = [
  619. CustomerGroup::ID => $nonExistentGroupId,
  620. CustomerGroup::CODE => 'Updated Non-Existent Group SOAP',
  621. 'taxClassId' => 3,
  622. ];
  623. $requestData = ['group' => $groupData];
  624. try {
  625. $this->_webApiCall($serviceInfo, $requestData);
  626. } catch (\Exception $e) {
  627. $expectedMessage = 'No such entity with %fieldName = %fieldValue';
  628. $this->assertContains(
  629. $expectedMessage,
  630. $e->getMessage(),
  631. "Exception does not contain expected message."
  632. );
  633. }
  634. }
  635. /**
  636. * Verify that deleting an existing group works.
  637. */
  638. public function testDeleteGroupExists()
  639. {
  640. $group = $this->customerGroupFactory->create();
  641. $group->setId(null);
  642. $group->setCode('Delete Group');
  643. $group->setTaxClassId(3);
  644. $groupId = $this->createGroup($group);
  645. $serviceInfo = [
  646. 'rest' => [
  647. 'resourcePath' => self::RESOURCE_PATH . "/$groupId",
  648. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE,
  649. ],
  650. 'soap' => [
  651. 'service' => self::SERVICE_NAME,
  652. 'serviceVersion' => self::SERVICE_VERSION,
  653. 'operation' => 'customerGroupRepositoryV1DeleteById',
  654. ],
  655. ];
  656. $requestData = [CustomerGroup::ID => $groupId];
  657. $response = $this->_webApiCall($serviceInfo, $requestData);
  658. $this->assertTrue($response, 'Expected response should be true.');
  659. try {
  660. $this->groupRepository->getById($groupId);
  661. $this->fail('An expected NoSuchEntityException was not thrown.');
  662. } catch (NoSuchEntityException $e) {
  663. $exception = NoSuchEntityException::singleField(CustomerGroup::ID, $groupId);
  664. $this->assertEquals(
  665. $exception->getMessage(),
  666. $e->getMessage(),
  667. 'Exception message does not match expected message.'
  668. );
  669. }
  670. }
  671. /**
  672. * Verify that deleting an non-existing group works.
  673. */
  674. public function testDeleteGroupNotExists()
  675. {
  676. $groupId = 4200;
  677. $serviceInfo = [
  678. 'rest' => [
  679. 'resourcePath' => self::RESOURCE_PATH . "/$groupId",
  680. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE,
  681. ],
  682. 'soap' => [
  683. 'service' => self::SERVICE_NAME,
  684. 'serviceVersion' => self::SERVICE_VERSION,
  685. 'operation' => 'customerGroupRepositoryV1DeleteById',
  686. ],
  687. ];
  688. $requestData = [CustomerGroup::ID => $groupId];
  689. $expectedMessage = 'No such entity with %fieldName = %fieldValue';
  690. $expectedParameters = ['fieldName' => CustomerGroup::ID, 'fieldValue' => $groupId];
  691. try {
  692. $this->_webApiCall($serviceInfo, $requestData);
  693. } catch (\SoapFault $e) {
  694. $this->assertContains($expectedMessage, $e->getMessage(), "SoapFault does not contain expected message.");
  695. } catch (\Exception $e) {
  696. $errorObj = $this->processRestExceptionResult($e);
  697. $this->assertEquals($expectedMessage, $errorObj['message']);
  698. $this->assertEquals($expectedParameters, $errorObj['parameters']);
  699. }
  700. }
  701. /**
  702. * Verify that the group with the specified Id cannot be deleted because it is the default group and a proper
  703. * fault is returned.
  704. */
  705. public function testDeleteGroupCannotDelete()
  706. {
  707. $groupIdAssignedDefault = 1;
  708. $serviceInfo = [
  709. 'rest' => [
  710. 'resourcePath' => self::RESOURCE_PATH . "/$groupIdAssignedDefault",
  711. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_DELETE,
  712. ],
  713. 'soap' => [
  714. 'service' => self::SERVICE_NAME,
  715. 'serviceVersion' => self::SERVICE_VERSION,
  716. 'operation' => 'customerGroupRepositoryV1DeleteById',
  717. ],
  718. ];
  719. $requestData = [CustomerGroup::ID => $groupIdAssignedDefault];
  720. $expectedMessage = "Cannot delete group.";
  721. try {
  722. $this->_webApiCall($serviceInfo, $requestData);
  723. $this->fail("Expected exception");
  724. } catch (\SoapFault $e) {
  725. $this->assertContains(
  726. $expectedMessage,
  727. $e->getMessage(),
  728. "SoapFault does not contain expected message."
  729. );
  730. } catch (\Exception $e) {
  731. $this->assertContains(
  732. $expectedMessage,
  733. $e->getMessage(),
  734. "Exception does not contain expected message."
  735. );
  736. }
  737. $this->assertNotNull($this->groupRepository->getById($groupIdAssignedDefault));
  738. }
  739. /**
  740. * Create a test group.
  741. *
  742. * @param CustomerGroup $group The group to create and save.
  743. * @return int The group Id of the group that was created.
  744. */
  745. private function createGroup($group)
  746. {
  747. $groupId = $this->groupRepository->save($group)->getId();
  748. $this->assertNotNull($groupId);
  749. $newGroup = $this->groupRepository->getById($groupId);
  750. $this->assertEquals($groupId, $newGroup->getId(), 'The group id does not match.');
  751. $this->assertEquals($group->getCode(), $newGroup->getCode(), 'The group code does not match.');
  752. $this->assertEquals(
  753. $group->getTaxClassId(),
  754. $newGroup->getTaxClassId(),
  755. 'The group tax class id does not match.'
  756. );
  757. $this->groupRegistry->remove($groupId);
  758. return $groupId;
  759. }
  760. /**
  761. * Data provider for testSearchGroups
  762. */
  763. public function testSearchGroupsDataProvider()
  764. {
  765. return [
  766. ['tax_class_id', 3, []],
  767. ['tax_class_id', 0, null],
  768. ['code', md5(mt_rand(0, 10000000000) . time()), null],
  769. [
  770. 'id',
  771. 0,
  772. [
  773. 'id' => 0,
  774. 'code' => 'NOT LOGGED IN',
  775. 'tax_class_id' => 3,
  776. 'tax_class_name' => 'Retail Customer'
  777. ]
  778. ],
  779. [
  780. 'code',
  781. 'General',
  782. [
  783. 'id' => 1,
  784. 'code' => 'General',
  785. 'tax_class_id' => 3,
  786. 'tax_class_name' => 'Retail Customer'
  787. ]
  788. ],
  789. [
  790. 'id',
  791. 2,
  792. [
  793. 'id' => 2,
  794. 'code' => 'Wholesale',
  795. 'tax_class_id' => 3,
  796. 'tax_class_name' => 'Retail Customer'
  797. ]
  798. ],
  799. [
  800. 'code',
  801. 'Retailer',
  802. [
  803. 'id' => 3,
  804. 'code' => 'Retailer',
  805. 'tax_class_id' => 3,
  806. 'tax_class_name' => 'Retail Customer'
  807. ]
  808. ]
  809. ];
  810. }
  811. /**
  812. * Test search customer group
  813. *
  814. * @param string $filterField Customer Group field to filter by
  815. * @param string $filterValue Value of the field to be filtered by
  816. * @param array $expectedResult Expected search result
  817. *
  818. * @dataProvider testSearchGroupsDataProvider
  819. */
  820. public function testSearchGroups($filterField, $filterValue, $expectedResult)
  821. {
  822. $filterBuilder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class);
  823. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  824. $searchCriteriaBuilder = Bootstrap::getObjectManager()
  825. ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class);
  826. $filter = $filterBuilder
  827. ->setField($filterField)
  828. ->setValue($filterValue)
  829. ->create();
  830. $searchCriteriaBuilder->addFilters([$filter]);
  831. $searchData = $searchCriteriaBuilder->create()->__toArray();
  832. $requestData = ['searchCriteria' => $searchData];
  833. $serviceInfo = [
  834. 'rest' => [
  835. 'resourcePath' => self::RESOURCE_PATH . "/search" . '?' . http_build_query($requestData),
  836. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  837. ],
  838. 'soap' => [
  839. 'service' => self::SERVICE_NAME,
  840. 'serviceVersion' => self::SERVICE_VERSION,
  841. 'operation' => 'customerGroupRepositoryV1GetList',
  842. ],
  843. ];
  844. $searchResult = $this->_webApiCall($serviceInfo, $requestData);
  845. if (is_null($expectedResult)) {
  846. $this->assertEquals(0, $searchResult['total_count']);
  847. } elseif (is_array($expectedResult)) {
  848. $this->assertGreaterThan(0, $searchResult['total_count']);
  849. if (!empty($expectedResult)) {
  850. $this->assertEquals($expectedResult, $searchResult['items'][0]);
  851. }
  852. }
  853. }
  854. public function testSearchGroupsWithMultipleFilterGroupsAndSorting()
  855. {
  856. /** @var FilterBuilder $filterBuilder */
  857. $filterBuilder = Bootstrap::getObjectManager()->create(FilterBuilder::class);
  858. $filter1 = $filterBuilder->setField(GroupInterface::CODE)
  859. ->setValue('General')
  860. ->create();
  861. $filter2 = $filterBuilder->setField(GroupInterface::CODE)
  862. ->setValue('Retailer')
  863. ->create();
  864. $filter3 = $filterBuilder->setField(GroupInterface::CODE)
  865. ->setValue('Wholesale')
  866. ->create();
  867. $filter4 = $filterBuilder->setField(GroupInterface::ID)
  868. ->setValue(1)
  869. ->setConditionType('gt')
  870. ->create();
  871. /**@var SortOrderBuilder $sortOrderBuilder */
  872. $sortOrderBuilder = Bootstrap::getObjectManager()->create(SortOrderBuilder::class);
  873. /** @var SortOrder $sortOrder */
  874. $sortOrder = $sortOrderBuilder->setField(GroupInterface::CODE)->setDirection(SortOrder::SORT_ASC)->create();
  875. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  876. $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class);
  877. $searchCriteriaBuilder->addFilters([$filter1, $filter2, $filter3]);
  878. $searchCriteriaBuilder->addFilters([$filter4]);
  879. $searchCriteriaBuilder->setSortOrders([$sortOrder]);
  880. $searchData = $searchCriteriaBuilder->create()->__toArray();
  881. $requestData = ['searchCriteria' => $searchData];
  882. $serviceInfo = [
  883. 'rest' => [
  884. 'resourcePath' => self::RESOURCE_PATH . "/search" . '?' . http_build_query($requestData),
  885. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  886. ],
  887. 'soap' => [
  888. 'service' => self::SERVICE_NAME,
  889. 'serviceVersion' => self::SERVICE_VERSION,
  890. 'operation' => 'customerGroupRepositoryV1GetList',
  891. ],
  892. ];
  893. $searchResult = $this->_webApiCall($serviceInfo, $requestData);
  894. $this->assertEquals(2, $searchResult['total_count']);
  895. $this->assertEquals(3, $searchResult['items'][0][GroupInterface::ID]);
  896. $this->assertEquals(2, $searchResult['items'][1][GroupInterface::ID]);
  897. }
  898. /**
  899. * Test search customer group using GET
  900. *
  901. * @param string $filterField Customer Group field to filter by
  902. * @param string $filterValue Value of the field to be filtered by
  903. * @param array $expectedResult Expected search result
  904. *
  905. * @dataProvider testSearchGroupsDataProvider
  906. */
  907. public function testSearchGroupsWithGET($filterField, $filterValue, $expectedResult)
  908. {
  909. $this->_markTestAsRestOnly('SOAP is covered in ');
  910. $filterBuilder = Bootstrap::getObjectManager()->create(\Magento\Framework\Api\FilterBuilder::class);
  911. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  912. $searchCriteriaBuilder = Bootstrap::getObjectManager()
  913. ->create(\Magento\Framework\Api\SearchCriteriaBuilder::class);
  914. $filter = $filterBuilder
  915. ->setField($filterField)
  916. ->setValue($filterValue)
  917. ->create();
  918. $searchCriteriaBuilder->addFilters([$filter]);
  919. $searchData = $searchCriteriaBuilder->create()->__toArray();
  920. $requestData = ['searchCriteria' => $searchData];
  921. $searchQueryString = http_build_query($requestData);
  922. $serviceInfo = [
  923. 'rest' => [
  924. 'resourcePath' => self::RESOURCE_PATH . '/search?' . $searchQueryString,
  925. 'httpMethod' => \Magento\Framework\Webapi\Rest\Request::HTTP_METHOD_GET,
  926. ],
  927. ];
  928. $searchResult = $this->_webApiCall($serviceInfo);
  929. if (is_null($expectedResult)) {
  930. $this->assertEquals(0, $searchResult['total_count']);
  931. } elseif (is_array($expectedResult)) {
  932. $this->assertGreaterThan(0, $searchResult['total_count']);
  933. if (!empty($expectedResult)) {
  934. $this->assertEquals($expectedResult, $searchResult['items'][0]);
  935. }
  936. }
  937. }
  938. }