Skip to content

Commit a5bb1b0

Browse files
author
Viktor Sevch
committed
MC-39886: Improve customer api
1 parent bbedf18 commit a5bb1b0

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Model\Validator;
9+
10+
use Magento\Customer\Model\Customer;
11+
use Magento\Framework\Validator\AbstractValidator;
12+
13+
/**
14+
* Customer name fields validator.
15+
*/
16+
class Name extends AbstractValidator
17+
{
18+
/**
19+
* Validate name fields.
20+
*
21+
* @param Customer $customer
22+
* @return bool
23+
*/
24+
public function isValid($customer)
25+
{
26+
if (!$this->isValidName($customer->getFirstname())) {
27+
$this->_addErrorMessages('firstname', (array)['First Name is not valid!']);
28+
}
29+
30+
if (!$this->isValidName($customer->getLastname())) {
31+
$this->_addErrorMessages('lastname', (array)['Last Name is not valid!']);
32+
}
33+
34+
if (!$this->isValidName($customer->getMiddlename())) {
35+
$this->_addErrorMessages('middlename', (array)['Middle Name is not valid!']);
36+
}
37+
38+
return count($this->_messages) == 0;
39+
}
40+
41+
/**
42+
* Check if name field is valid.
43+
*
44+
* @param string $nameValue
45+
* @return bool
46+
*/
47+
private function isValidName(string $nameValue)
48+
{
49+
if ($nameValue != null) {
50+
$pattern = '/(?:[\p{L}\p{M}\,\-\.\'\s]){1,255}+/u';
51+
if (preg_match($pattern, $nameValue, $matches)) {
52+
return $matches[0] == $nameValue;
53+
}
54+
}
55+
56+
return true;
57+
}
58+
59+
/**
60+
* Add error messages.
61+
*
62+
* @param string $code
63+
* @param array $messages
64+
* @return void
65+
*/
66+
protected function _addErrorMessages($code, array $messages)
67+
{
68+
if (!array_key_exists($code, $this->_messages)) {
69+
$this->_messages[$code] = $messages;
70+
} else {
71+
$this->_messages[$code] = array_merge($this->_messages[$code], $messages);
72+
}
73+
}
74+
}

app/code/Magento/Customer/etc/validation.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818
<constraint alias="metadata_data_validator" class="Magento\Customer\Model\Metadata\Validator" />
1919
</entity_constraints>
2020
</rule>
21+
<rule name="check_name">
22+
<entity_constraints>
23+
<constraint alias="name_validator" class="Magento\Customer\Model\Validator\Name" />
24+
</entity_constraints>
25+
</rule>
2126
</rules>
2227
<groups>
2328
<group name="save">
2429
<uses>
2530
<use rule="check_eav"/>
31+
<use rule="check_name"/>
2632
</uses>
2733
</group>
2834
<group name="form">

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

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,4 +933,131 @@ protected function _createCustomer()
933933
$this->currentCustomerId[] = $customerData['id'];
934934
return $customerData;
935935
}
936+
937+
/**
938+
* Test customer create with invalid name's.
939+
*
940+
* @param string $fieldName
941+
* @param string $fieldValue
942+
* @param string $expectedMessage
943+
* @return void
944+
*
945+
* @dataProvider customerDataProvider
946+
*/
947+
public function testCreateCustomerWithInvalidCustomerFirstName(
948+
string $fieldName,
949+
string $fieldValue,
950+
string $expectedMessage
951+
): void {
952+
$customerData = $this->dataObjectProcessor->buildOutputDataArray(
953+
$this->customerHelper->createSampleCustomerDataObject(),
954+
Customer::class
955+
);
956+
$customerData[$fieldName] = $fieldValue;
957+
958+
$serviceInfo = [
959+
'rest' => [
960+
'resourcePath' => self::RESOURCE_PATH,
961+
'httpMethod' => Request::HTTP_METHOD_POST,
962+
],
963+
'soap' => [
964+
'service' => self::SERVICE_NAME,
965+
'serviceVersion' => self::SERVICE_VERSION,
966+
'operation' => self::SERVICE_NAME . 'Save',
967+
],
968+
];
969+
970+
$requestData = ['customer' => $customerData];
971+
972+
try {
973+
$this->_webApiCall($serviceInfo, $requestData);
974+
$this->fail('Expected exception was not raised');
975+
} catch (\SoapFault $e) {
976+
$this->assertEquals($expectedMessage, $e->getMessage());
977+
} catch (\Exception $e) {
978+
$errorObj = $this->processRestExceptionResult($e);
979+
$this->assertEquals(HTTPExceptionCodes::HTTP_BAD_REQUEST, $e->getCode());
980+
$this->assertEquals($expectedMessage, $errorObj['message']);
981+
}
982+
}
983+
984+
/**
985+
* Invalid customer data provider
986+
*
987+
* @return array
988+
*/
989+
public function customerDataProvider(): array
990+
{
991+
return [
992+
['firstname', 'Jane ☺ ', 'First Name is not valid!'],
993+
['lastname', '☏ - Doe', 'Last Name is not valid!'],
994+
['middlename', '⚐ $(date)', 'Middle Name is not valid!'],
995+
[
996+
'firstname',
997+
str_repeat('खाना अच्छा है', 20),
998+
'First Name is not valid!',
999+
],
1000+
[
1001+
'lastname',
1002+
str_repeat('المغلوطة حول استنكار النشوة وتمجيد الألمالمغلوطة حول', 5),
1003+
'Last Name is not valid!',
1004+
],
1005+
];
1006+
}
1007+
1008+
/**
1009+
* Test customer create with ultibyte chanracters in name's.
1010+
*
1011+
* @param string $fieldName
1012+
* @param string $fieldValue
1013+
* @return void
1014+
*
1015+
* @dataProvider customerWithMultiByteDataProvider
1016+
*/
1017+
public function testCreateCustomerWithMultibyteCharacters(string $fieldName, string $fieldValue): void
1018+
{
1019+
$customerData = $this->dataObjectProcessor->buildOutputDataArray(
1020+
$this->customerHelper->createSampleCustomerDataObject(),
1021+
Customer::class
1022+
);
1023+
$customerData[$fieldName] = $fieldValue;
1024+
1025+
$serviceInfo = [
1026+
'rest' => [
1027+
'resourcePath' => self::RESOURCE_PATH,
1028+
'httpMethod' => Request::HTTP_METHOD_POST,
1029+
],
1030+
'soap' => [
1031+
'service' => self::SERVICE_NAME,
1032+
'serviceVersion' => self::SERVICE_VERSION,
1033+
'operation' => self::SERVICE_NAME . 'Save',
1034+
],
1035+
];
1036+
1037+
$requestData = ['customer' => $customerData];
1038+
1039+
$response = $this->_webApiCall($serviceInfo, $requestData);
1040+
1041+
$this->assertNotNull($response);
1042+
$this->assertEquals($fieldValue, $response[$fieldName]);
1043+
}
1044+
1045+
/**
1046+
* Customer with multibyte characters data provider.
1047+
*
1048+
* @return array
1049+
*/
1050+
public function customerWithMultiByteDataProvider(): array
1051+
{
1052+
return [
1053+
[
1054+
'firstname',
1055+
str_repeat('हैखान', 51),
1056+
],
1057+
[
1058+
'lastname',
1059+
str_repeat('مغلوطة حول استنكار النشوة وتمجيد الألمالمغلوطة حول', 5),
1060+
],
1061+
];
1062+
}
9361063
}

0 commit comments

Comments
 (0)