Skip to content

Commit 0cee64b

Browse files
committed
MAGETWO-61907: [Backport] - Updating customer via REST API without address unsets default billing and default shipping address - for 2.1
1 parent 75a7b9b commit 0cee64b

File tree

3 files changed

+163
-72
lines changed

3 files changed

+163
-72
lines changed

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

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
/**
1616
* Customer repository.
1717
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
18+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
1819
*/
1920
class CustomerRepository implements \Magento\Customer\Api\CustomerRepositoryInterface
2021
{
@@ -137,9 +138,15 @@ public function __construct(
137138
public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null)
138139
{
139140
$prevCustomerData = null;
141+
$prevCustomerDataArr = null;
142+
140143
if ($customer->getId()) {
141144
$prevCustomerData = $this->getById($customer->getId());
145+
$prevCustomerDataArr = $prevCustomerData->__toArray();
142146
}
147+
148+
/** @var $customer \Magento\Customer\Model\Data\Customer */
149+
$customerArr = $customer->__toArray();
143150
$customer = $this->imageProcessor->save(
144151
$customer,
145152
CustomerMetadataInterface::ENTITY_TYPE_CUSTOMER,
@@ -151,15 +158,17 @@ public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $pa
151158
$customerData = $this->extensibleDataObjectConverter->toNestedArray(
152159
$customer,
153160
[],
154-
'\Magento\Customer\Api\Data\CustomerInterface'
161+
\Magento\Customer\Api\Data\CustomerInterface::class
155162
);
156163

157164
$customer->setAddresses($origAddresses);
158165
$customerModel = $this->customerFactory->create(['data' => $customerData]);
159166
$storeId = $customerModel->getStoreId();
167+
160168
if ($storeId === null) {
161169
$customerModel->setStoreId($this->storeManager->getStore()->getId());
162170
}
171+
163172
$customerModel->setId($customer->getId());
164173

165174
// Need to use attribute set or future updates can cause data loss
@@ -190,6 +199,21 @@ public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $pa
190199
$customerModel->setRpToken(null);
191200
$customerModel->setRpTokenCreatedAt(null);
192201
}
202+
203+
if (!array_key_exists('default_billing', $customerArr) &&
204+
null !== $prevCustomerDataArr &&
205+
array_key_exists('default_billing', $prevCustomerDataArr)
206+
) {
207+
$customerModel->setDefaultBilling($prevCustomerDataArr['default_billing']);
208+
}
209+
210+
if (!array_key_exists('default_shipping', $customerArr) &&
211+
null !== $prevCustomerDataArr &&
212+
array_key_exists('default_shipping', $prevCustomerDataArr)
213+
) {
214+
$customerModel->setDefaultShipping($prevCustomerDataArr['default_shipping']);
215+
}
216+
193217
$customerModel->save();
194218
$this->customerRegistry->push($customerModel);
195219
$customerId = $customerModel->getId();
@@ -256,7 +280,10 @@ public function getList(SearchCriteriaInterface $searchCriteria)
256280
$searchResults->setSearchCriteria($searchCriteria);
257281
/** @var \Magento\Customer\Model\ResourceModel\Customer\Collection $collection */
258282
$collection = $this->customerFactory->create()->getCollection();
259-
$this->extensionAttributesJoinProcessor->process($collection, 'Magento\Customer\Api\Data\CustomerInterface');
283+
$this->extensionAttributesJoinProcessor->process(
284+
$collection,
285+
\Magento\Customer\Api\Data\CustomerInterface::class
286+
);
260287
// This is needed to make sure all the attributes are properly loaded
261288
foreach ($this->customerMetadata->getAllAttributesMetadata() as $metadata) {
262289
$collection->addAttributeToSelect($metadata->getAttributeCode());

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

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -91,77 +91,78 @@ class CustomerRepositoryTest extends \PHPUnit_Framework_TestCase
9191
protected function setUp()
9292
{
9393
$this->customerResourceModel =
94-
$this->getMock('Magento\Customer\Model\ResourceModel\Customer', [], [], '', false);
95-
$this->customerRegistry = $this->getMock('Magento\Customer\Model\CustomerRegistry', [], [], '', false);
96-
$this->dataObjectHelper = $this->getMock('Magento\Framework\Api\DataObjectHelper', [], [], '', false);
97-
$this->customerFactory = $this->getMock('Magento\Customer\Model\CustomerFactory', ['create'], [], '', false);
94+
$this->getMock(\Magento\Customer\Model\ResourceModel\Customer::class, [], [], '', false);
95+
$this->customerRegistry = $this->getMock(\Magento\Customer\Model\CustomerRegistry::class, [], [], '', false);
96+
$this->dataObjectHelper = $this->getMock(\Magento\Framework\Api\DataObjectHelper::class, [], [], '', false);
97+
$this->customerFactory = $this->getMock(
98+
\Magento\Customer\Model\CustomerFactory::class,
99+
['create'],
100+
[],
101+
'',
102+
false
103+
);
98104
$this->customerSecureFactory = $this->getMock(
99-
'Magento\Customer\Model\Data\CustomerSecureFactory',
105+
\Magento\Customer\Model\Data\CustomerSecureFactory::class,
100106
['create'],
101107
[],
102108
'',
103109
false
104110
);
105-
106111
$this->addressRepository = $this->getMock(
107-
'Magento\Customer\Model\ResourceModel\AddressRepository',
112+
\Magento\Customer\Model\ResourceModel\AddressRepository::class,
108113
[],
109114
[],
110115
'',
111116
false
112117
);
113-
114118
$this->customerMetadata = $this->getMockForAbstractClass(
115-
'Magento\Customer\Api\CustomerMetadataInterface',
119+
\Magento\Customer\Api\CustomerMetadataInterface::class,
116120
[],
117121
'',
118122
false
119123
);
120124
$this->searchResultsFactory = $this->getMock(
121-
'Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory',
125+
\Magento\Customer\Api\Data\CustomerSearchResultsInterfaceFactory::class,
122126
['create'],
123127
[],
124128
'',
125129
false
126130
);
127131
$this->eventManager = $this->getMockForAbstractClass(
128-
'Magento\Framework\Event\ManagerInterface',
132+
\Magento\Framework\Event\ManagerInterface::class,
129133
[],
130134
'',
131135
false
132136
);
133137
$this->storeManager = $this->getMockForAbstractClass(
134-
'Magento\Store\Model\StoreManagerInterface',
138+
\Magento\Store\Model\StoreManagerInterface::class,
135139
[],
136140
'',
137141
false
138142
);
139143
$this->extensibleDataObjectConverter = $this->getMock(
140-
'Magento\Framework\Api\ExtensibleDataObjectConverter',
144+
\Magento\Framework\Api\ExtensibleDataObjectConverter::class,
141145
[],
142146
[],
143147
'',
144148
false
145149
);
146150
$this->imageProcessor = $this->getMockForAbstractClass(
147-
'Magento\Framework\Api\ImageProcessorInterface',
151+
\Magento\Framework\Api\ImageProcessorInterface::class,
148152
[],
149153
'',
150154
false
151155
);
152156
$this->extensionAttributesJoinProcessor = $this->getMockForAbstractClass(
153-
'Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface',
154-
[],
155-
'',
156-
false
157-
);
158-
$this->customer = $this->getMockForAbstractClass(
159-
'Magento\Customer\Api\Data\CustomerInterface',
157+
\Magento\Framework\Api\ExtensionAttribute\JoinProcessorInterface::class,
160158
[],
161159
'',
162160
false
163161
);
164-
162+
$this->customer = $this->getMockBuilder(\Magento\Customer\Api\Data\CustomerInterface::class)
163+
->setMethods(['__toArray'])
164+
->disableOriginalConstructor()
165+
->getMockForAbstractClass();
165166
$this->model = new \Magento\Customer\Model\ResourceModel\CustomerRepository(
166167
$this->customerFactory,
167168
$this->customerSecureFactory,
@@ -187,9 +188,9 @@ public function testSave()
187188
$customerId = 1;
188189
$storeId = 2;
189190

190-
$region = $this->getMockForAbstractClass('Magento\Customer\Api\Data\RegionInterface', [], '', false);
191+
$region = $this->getMockForAbstractClass(\Magento\Customer\Api\Data\RegionInterface::class, [], '', false);
191192
$address = $this->getMockForAbstractClass(
192-
'Magento\Customer\Api\Data\AddressInterface',
193+
\Magento\Customer\Api\Data\AddressInterface::class,
193194
[],
194195
'',
195196
false,
@@ -203,7 +204,7 @@ public function testSave()
203204
]
204205
);
205206
$address2 = $this->getMockForAbstractClass(
206-
'Magento\Customer\Api\Data\AddressInterface',
207+
\Magento\Customer\Api\Data\AddressInterface::class,
207208
[],
208209
'',
209210
false,
@@ -217,7 +218,7 @@ public function testSave()
217218
]
218219
);
219220
$customerModel = $this->getMock(
220-
'Magento\Customer\Model\Customer',
221+
\Magento\Customer\Model\Customer::class,
221222
[
222223
'getId',
223224
'setId',
@@ -238,8 +239,11 @@ public function testSave()
238239
'',
239240
false
240241
);
242+
$this->customer->expects($this->atLeastOnce())
243+
->method('__toArray')
244+
->willReturn(['default_billing', 'default_shipping']);
241245
$customerAttributesMetaData = $this->getMockForAbstractClass(
242-
'Magento\Framework\Api\CustomAttributesDataInterface',
246+
\Magento\Framework\Api\CustomAttributesDataInterface::class,
243247
[],
244248
'',
245249
false,
@@ -254,7 +258,7 @@ public function testSave()
254258
]
255259
);
256260
$customerSecureData = $this->getMock(
257-
'Magento\Customer\Model\Data\CustomerSecure',
261+
\Magento\Customer\Model\Data\CustomerSecure::class,
258262
[
259263
'getRpToken',
260264
'getRpTokenCreatedAt',
@@ -305,7 +309,7 @@ public function testSave()
305309
->with([$address]);
306310
$this->extensibleDataObjectConverter->expects($this->once())
307311
->method('toNestedArray')
308-
->with($customerAttributesMetaData, [], '\Magento\Customer\Api\Data\CustomerInterface')
312+
->with($customerAttributesMetaData, [], \Magento\Customer\Api\Data\CustomerInterface::class)
309313
->willReturn(['customerData']);
310314
$this->customerFactory->expects($this->once())
311315
->method('create')
@@ -428,9 +432,9 @@ public function testSaveWithPasswordHash()
428432
$storeId = 2;
429433
$passwordHash = 'ukfa4sdfa56s5df02asdf4rt';
430434

431-
$region = $this->getMockForAbstractClass('Magento\Customer\Api\Data\RegionInterface', [], '', false);
435+
$region = $this->getMockForAbstractClass(\Magento\Customer\Api\Data\RegionInterface::class, [], '', false);
432436
$address = $this->getMockForAbstractClass(
433-
'Magento\Customer\Api\Data\AddressInterface',
437+
\Magento\Customer\Api\Data\AddressInterface::class,
434438
[],
435439
'',
436440
false,
@@ -444,7 +448,7 @@ public function testSaveWithPasswordHash()
444448
]
445449
);
446450
$address2 = $this->getMockForAbstractClass(
447-
'Magento\Customer\Api\Data\AddressInterface',
451+
\Magento\Customer\Api\Data\AddressInterface::class,
448452
[],
449453
'',
450454
false,
@@ -457,8 +461,12 @@ public function testSaveWithPasswordHash()
457461
'getId'
458462
]
459463
);
464+
$this->customer->expects($this->atLeastOnce())
465+
->method('__toArray')
466+
->willReturn(['default_billing', 'default_shipping']);
467+
460468
$customerModel = $this->getMock(
461-
'Magento\Customer\Model\Customer',
469+
\Magento\Customer\Model\Customer::class,
462470
[
463471
'getId',
464472
'setId',
@@ -477,7 +485,7 @@ public function testSaveWithPasswordHash()
477485
false
478486
);
479487
$customerAttributesMetaData = $this->getMockForAbstractClass(
480-
'Magento\Framework\Api\CustomAttributesDataInterface',
488+
\Magento\Framework\Api\CustomAttributesDataInterface::class,
481489
[],
482490
'',
483491
false,
@@ -529,7 +537,7 @@ public function testSaveWithPasswordHash()
529537
->with([$address]);
530538
$this->extensibleDataObjectConverter->expects($this->once())
531539
->method('toNestedArray')
532-
->with($customerAttributesMetaData, [], '\Magento\Customer\Api\Data\CustomerInterface')
540+
->with($customerAttributesMetaData, [], \Magento\Customer\Api\Data\CustomerInterface::class)
533541
->willReturn(['customerData']);
534542
$this->customerFactory->expects($this->once())
535543
->method('create')
@@ -600,24 +608,30 @@ public function testSaveWithPasswordHash()
600608
*/
601609
public function testGetList()
602610
{
603-
$sortOrder = $this->getMock('Magento\Framework\Api\SortOrder', [], [], '', false);
604-
$filterGroup = $this->getMock('Magento\Framework\Api\Search\FilterGroup', [], [], '', false);
605-
$filter = $this->getMock('Magento\Framework\Api\Filter', [], [], '', false);
606-
$collection = $this->getMock('Magento\Customer\Model\ResourceModel\Customer\Collection', [], [], '', false);
611+
$sortOrder = $this->getMock(\Magento\Framework\Api\SortOrder::class, [], [], '', false);
612+
$filterGroup = $this->getMock(\Magento\Framework\Api\Search\FilterGroup::class, [], [], '', false);
613+
$filter = $this->getMock(\Magento\Framework\Api\Filter::class, [], [], '', false);
614+
$collection = $this->getMock(
615+
\Magento\Customer\Model\ResourceModel\Customer\Collection::class,
616+
[],
617+
[],
618+
'',
619+
false
620+
);
607621
$searchResults = $this->getMockForAbstractClass(
608-
'Magento\Customer\Api\Data\AddressSearchResultsInterface',
622+
\Magento\Customer\Api\Data\AddressSearchResultsInterface::class,
609623
[],
610624
'',
611625
false
612626
);
613627
$searchCriteria = $this->getMockForAbstractClass(
614-
'Magento\Framework\Api\SearchCriteriaInterface',
628+
\Magento\Framework\Api\SearchCriteriaInterface::class,
615629
[],
616630
'',
617631
false
618632
);
619633
$customerModel = $this->getMock(
620-
'Magento\Customer\Model\Customer',
634+
\Magento\Customer\Model\Customer::class,
621635
[
622636
'getId',
623637
'setId',
@@ -636,7 +650,7 @@ public function testGetList()
636650
false
637651
);
638652
$metadata = $this->getMockForAbstractClass(
639-
'Magento\Customer\Api\Data\AttributeMetadataInterface',
653+
\Magento\Customer\Api\Data\AttributeMetadataInterface::class,
640654
[],
641655
'',
642656
false
@@ -656,7 +670,7 @@ public function testGetList()
656670
->willReturn($collection);
657671
$this->extensionAttributesJoinProcessor->expects($this->once())
658672
->method('process')
659-
->with($collection, 'Magento\Customer\Api\Data\CustomerInterface');
673+
->with($collection, \Magento\Customer\Api\Data\CustomerInterface::class);
660674
$this->customerMetadata->expects($this->once())
661675
->method('getAllAttributesMetadata')
662676
->willReturn([$metadata]);
@@ -757,7 +771,7 @@ public function testDeleteById()
757771
{
758772
$customerId = 14;
759773
$customerModel = $this->getMock(
760-
'Magento\Customer\Model\Customer',
774+
\Magento\Customer\Model\Customer::class,
761775
['delete'],
762776
[],
763777
'',
@@ -781,7 +795,7 @@ public function testDelete()
781795
{
782796
$customerId = 14;
783797
$customerModel = $this->getMock(
784-
'Magento\Customer\Model\Customer',
798+
\Magento\Customer\Model\Customer::class,
785799
['delete'],
786800
[],
787801
'',

0 commit comments

Comments
 (0)