Skip to content

Commit bc633b6

Browse files
authored
ENGCOM-7785: Create or update customer don't validate customer group id #28903
2 parents 878b1c9 + 924f355 commit bc633b6

File tree

4 files changed

+136
-13
lines changed

4 files changed

+136
-13
lines changed

app/code/Magento/Customer/Model/ResourceModel/CustomerRepository.php

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Magento\Customer\Api\CustomerRepositoryInterface;
1111
use Magento\Customer\Api\Data\CustomerInterface;
1212
use Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory;
13+
use Magento\Customer\Api\GroupRepositoryInterface;
1314
use Magento\Customer\Model\Customer as CustomerModel;
1415
use Magento\Customer\Model\Customer\NotificationStorage;
1516
use Magento\Customer\Model\CustomerFactory;
@@ -27,6 +28,8 @@
2728
use Magento\Framework\Api\SearchCriteriaInterface;
2829
use Magento\Framework\App\ObjectManager;
2930
use Magento\Framework\Event\ManagerInterface;
31+
use Magento\Framework\Exception\LocalizedException;
32+
use Magento\Framework\Exception\NoSuchEntityException;
3033
use Magento\Store\Model\StoreManagerInterface;
3134

3235
/**
@@ -119,6 +122,11 @@ class CustomerRepository implements CustomerRepositoryInterface
119122
*/
120123
private $delegatedStorage;
121124

125+
/**
126+
* @var GroupRepositoryInterface
127+
*/
128+
private $groupRepository;
129+
122130
/**
123131
* @param CustomerFactory $customerFactory
124132
* @param CustomerSecureFactory $customerSecureFactory
@@ -136,6 +144,7 @@ class CustomerRepository implements CustomerRepositoryInterface
136144
* @param CollectionProcessorInterface $collectionProcessor
137145
* @param NotificationStorage $notificationStorage
138146
* @param DelegatedStorage|null $delegatedStorage
147+
* @param GroupRepositoryInterface|null $groupRepository
139148
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
140149
*/
141150
public function __construct(
@@ -154,7 +163,8 @@ public function __construct(
154163
JoinProcessorInterface $extensionAttributesJoinProcessor,
155164
CollectionProcessorInterface $collectionProcessor,
156165
NotificationStorage $notificationStorage,
157-
DelegatedStorage $delegatedStorage = null
166+
DelegatedStorage $delegatedStorage = null,
167+
?GroupRepositoryInterface $groupRepository = null
158168
) {
159169
$this->customerFactory = $customerFactory;
160170
$this->customerSecureFactory = $customerSecureFactory;
@@ -172,6 +182,7 @@ public function __construct(
172182
$this->collectionProcessor = $collectionProcessor;
173183
$this->notificationStorage = $notificationStorage;
174184
$this->delegatedStorage = $delegatedStorage ?? ObjectManager::getInstance()->get(DelegatedStorage::class);
185+
$this->groupRepository = $groupRepository ?: ObjectManager::getInstance()->get(GroupRepositoryInterface::class);
175186
}
176187

177188
/**
@@ -216,6 +227,7 @@ public function save(CustomerInterface $customer, $passwordHash = null)
216227
$prevCustomerData ? $prevCustomerData->getStoreId() : $this->storeManager->getStore()->getId()
217228
);
218229
}
230+
$this->validateGroupId($customer->getGroupId());
219231
$this->setCustomerGroupId($customerModel, $customerArr, $prevCustomerDataArr);
220232
// Need to use attribute set or future updates can cause data loss
221233
if (!$customerModel->getAttributeSetId()) {
@@ -268,10 +280,7 @@ public function save(CustomerInterface $customer, $passwordHash = null)
268280
$savedAddressIds[] = $address->getId();
269281
}
270282
}
271-
$addressIdsToDelete = array_diff($existingAddressIds, $savedAddressIds);
272-
foreach ($addressIdsToDelete as $addressId) {
273-
$this->addressRepository->deleteById($addressId);
274-
}
283+
$this->deleteAddressesByIds(array_diff($existingAddressIds, $savedAddressIds));
275284
}
276285
$this->customerRegistry->remove($customerId);
277286
$savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
@@ -286,6 +295,39 @@ public function save(CustomerInterface $customer, $passwordHash = null)
286295
return $savedCustomer;
287296
}
288297

298+
/**
299+
* Delete addresses by ids
300+
*
301+
* @param array $addressIds
302+
* @return void
303+
*/
304+
private function deleteAddressesByIds(array $addressIds): void
305+
{
306+
foreach ($addressIds as $id) {
307+
$this->addressRepository->deleteById($id);
308+
}
309+
}
310+
311+
/**
312+
* Validate customer group id if exist
313+
*
314+
* @param int|null $groupId
315+
* @return bool
316+
* @throws LocalizedException
317+
*/
318+
private function validateGroupId(?int $groupId): bool
319+
{
320+
if ($groupId) {
321+
try {
322+
$this->groupRepository->getById($groupId);
323+
} catch (NoSuchEntityException $e) {
324+
throw new LocalizedException(__('The specified customer group id does not exist.'));
325+
}
326+
}
327+
328+
return true;
329+
}
330+
289331
/**
290332
* Set secure data to customer model
291333
*

app/code/Magento/Customer/Test/Unit/Model/ResourceModel/CustomerRepositoryTest.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,8 @@ public function testSave()
249249
'getEmail',
250250
'getWebsiteId',
251251
'getAddresses',
252-
'setAddresses'
252+
'setAddresses',
253+
'getGroupId',
253254
]
254255
);
255256
$customerSecureData = $this->getMockBuilder(CustomerSecure::class)
@@ -433,7 +434,8 @@ public function testSaveWithPasswordHash()
433434
'getEmail',
434435
'getWebsiteId',
435436
'getAddresses',
436-
'setAddresses'
437+
'setAddresses',
438+
'getGroupId'
437439
]
438440
);
439441
$customerModel->expects($this->atLeastOnce())

app/code/Magento/Customer/i18n/en_US.csv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,3 +542,4 @@ Addresses,Addresses
542542
"The store view is not in the associated website.","The store view is not in the associated website."
543543
"The Store View selected for sending Welcome email from is not related to the customer's associated website.","The Store View selected for sending Welcome email from is not related to the customer's associated website."
544544
"Add/Update Address","Add/Update Address"
545+
"The specified customer group id does not exist.","The specified customer group id does not exist."

dev/tests/api-functional/testsuite/Magento/Customer/Api/CustomerRepositoryTest.php

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,8 @@ class CustomerRepositoryTest extends WebapiAbstract
3434
const SERVICE_VERSION = 'V1';
3535
const SERVICE_NAME = 'customerCustomerRepositoryV1';
3636
const RESOURCE_PATH = '/V1/customers';
37-
const RESOURCE_PATH_CUSTOMER_TOKEN = "/V1/integration/customer/token";
3837

39-
/**
40-
* Sample values for testing
41-
*/
42-
const ATTRIBUTE_CODE = 'attribute_code';
43-
const ATTRIBUTE_VALUE = 'attribute_value';
38+
private const STUB_INVALID_CUSTOMER_GROUP_ID = 777;
4439

4540
/**
4641
* @var CustomerRepositoryInterface
@@ -412,6 +407,89 @@ public function testUpdateCustomerException(): void
412407
}
413408
}
414409

410+
/**
411+
* Test customer update with invalid customer group id
412+
*
413+
* @magentoApiDataFixture Magento/Customer/_files/customer.php
414+
*
415+
* @return void
416+
*/
417+
public function testUpdateCustomerWithInvalidGroupId(): void
418+
{
419+
$customerId = 1;
420+
$customerData = $this->dataObjectProcessor->buildOutputDataArray(
421+
$this->getCustomerData($customerId),
422+
Customer::class
423+
);
424+
$customerData[Customer::GROUP_ID] = self::STUB_INVALID_CUSTOMER_GROUP_ID;
425+
426+
$serviceInfo = [
427+
'rest' => [
428+
'resourcePath' => self::RESOURCE_PATH . '/' . $customerId,
429+
'httpMethod' => Request::HTTP_METHOD_PUT,
430+
],
431+
'soap' => [
432+
'service' => self::SERVICE_NAME,
433+
'serviceVersion' => self::SERVICE_VERSION,
434+
'operation' => self::SERVICE_NAME . 'Save',
435+
],
436+
];
437+
438+
$requestData['customer'] = $customerData;
439+
$expectedMessage = 'The specified customer group id does not exist.';
440+
441+
try {
442+
$this->_webApiCall($serviceInfo, $requestData);
443+
$this->fail('Expected exception was not raised');
444+
} catch (\SoapFault $e) {
445+
$this->assertStringContainsString($expectedMessage, $e->getMessage());
446+
} catch (\Exception $e) {
447+
$errorObj = $this->processRestExceptionResult($e);
448+
$this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
449+
$this->assertEquals($expectedMessage, $errorObj['message']);
450+
}
451+
}
452+
453+
/**
454+
* Test customer create with invalid customer group id
455+
*
456+
* @return void
457+
*/
458+
public function testCreateCustomerWithInvalidGroupId(): void
459+
{
460+
$customerData = $this->dataObjectProcessor->buildOutputDataArray(
461+
$this->customerHelper->createSampleCustomerDataObject(),
462+
Customer::class
463+
);
464+
$customerData[Customer::GROUP_ID] = self::STUB_INVALID_CUSTOMER_GROUP_ID;
465+
466+
$serviceInfo = [
467+
'rest' => [
468+
'resourcePath' => self::RESOURCE_PATH,
469+
'httpMethod' => Request::HTTP_METHOD_POST,
470+
],
471+
'soap' => [
472+
'service' => self::SERVICE_NAME,
473+
'serviceVersion' => self::SERVICE_VERSION,
474+
'operation' => self::SERVICE_NAME . 'Save',
475+
],
476+
];
477+
478+
$requestData = ['customer' => $customerData];
479+
$expectedMessage = 'The specified customer group id does not exist.';
480+
481+
try {
482+
$this->_webApiCall($serviceInfo, $requestData);
483+
$this->fail('Expected exception was not raised');
484+
} catch (\SoapFault $e) {
485+
$this->assertStringContainsString($expectedMessage, $e->getMessage());
486+
} catch (\Exception $e) {
487+
$errorObj = $this->processRestExceptionResult($e);
488+
$this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
489+
$this->assertEquals($expectedMessage, $errorObj['message']);
490+
}
491+
}
492+
415493
/**
416494
* Test creating a customer with absent required address fields
417495
*

0 commit comments

Comments
 (0)