Skip to content

Commit 383a93e

Browse files
author
Sergii Kovalenko
committed
MAGETWO-53674: Impossible to create subscribed customer using WebAPI
1 parent a5fa3af commit 383a93e

File tree

5 files changed

+251
-28
lines changed

5 files changed

+251
-28
lines changed

app/code/Magento/Newsletter/Model/Plugin/CustomerPlugin.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,35 @@ public function afterSave(CustomerRepository $subject, CustomerInterface $custom
4242
return $customer;
4343
}
4444

45+
/**
46+
* Plugin around customer repository save. If we have extension attribute (is_subscribed) we need to subscribe that customer
47+
*
48+
* @param CustomerRepository $subject
49+
* @param \Closure $proceed
50+
* @param CustomerInterface $customer
51+
* @param null $passwordHash
52+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
53+
*/
54+
public function aroundSave(
55+
CustomerRepository $subject,
56+
\Closure $proceed,
57+
CustomerInterface $customer,
58+
$passwordHash = null
59+
) {
60+
/** @var CustomerInterface $savedCustomer */
61+
$savedCustomer = $proceed($customer, $passwordHash);
62+
63+
if ($savedCustomer->getId() && $customer->getExtensionAttributes()) {
64+
if ($customer->getExtensionAttributes()->getIsSubscribed() === true) {
65+
$this->subscriberFactory->create()->subscribeCustomerById($savedCustomer->getId());
66+
} elseif ($customer->getExtensionAttributes()->getIsSubscribed() === false) {
67+
$this->subscriberFactory->create()->unsubscribeCustomerById($savedCustomer->getId());
68+
}
69+
}
70+
71+
return $savedCustomer;
72+
}
73+
4574
/**
4675
* Plugin around delete customer that updates any newsletter subscription that may have existed.
4776
*

app/code/Magento/Newsletter/Test/Unit/Model/Plugin/CustomerPluginTest.php

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
namespace Magento\Newsletter\Test\Unit\Model\Plugin;
77

8+
use Magento\Customer\Api\Data\CustomerInterface;
9+
use Magento\Customer\Model\ResourceModel\CustomerRepository;
10+
811
class CustomerPluginTest extends \PHPUnit_Framework_TestCase
912
{
1013
/**
@@ -34,7 +37,7 @@ protected function setUp()
3437
->setMethods(['create'])
3538
->getMock();
3639
$this->subscriber = $this->getMockBuilder('\Magento\Newsletter\Model\Subscriber')
37-
->setMethods(['loadByEmail', 'getId', 'delete', 'updateSubscription'])
40+
->setMethods(['loadByEmail', 'getId', 'delete', 'updateSubscription', 'subscribeCustomerById', 'unsubscribeCustomerById'])
3841
->disableOriginalConstructor()
3942
->getMock();
4043
$this->subscriberFactory->expects($this->any())->method('create')->willReturn($this->subscriber);
@@ -60,6 +63,80 @@ public function testAfterSave()
6063
$this->assertEquals($customer, $this->plugin->afterSave($subject, $customer));
6164
}
6265

66+
public function testAroundSaveWithoutIsSubscribed()
67+
{
68+
$passwordHash = null;
69+
$customerId = 1;
70+
/** @var CustomerInterface | \PHPUnit_Framework_MockObject_MockObject $customer */
71+
$customer = $this->getMock('Magento\Customer\Api\Data\CustomerInterface');
72+
$proceed = function(CustomerInterface $customer, $passwordHash = null) use($customer) {
73+
return $customer;
74+
};
75+
/** @var CustomerRepository | \PHPUnit_Framework_MockObject_MockObject $subject */
76+
$subject = $this->getMock('\Magento\Customer\Api\CustomerRepositoryInterface');
77+
78+
$customer->expects($this->atLeastOnce())
79+
->method("getId")
80+
->willReturn($customerId);
81+
82+
$this->assertEquals($customer, $this->plugin->aroundSave($subject, $proceed, $customer, $passwordHash));
83+
}
84+
85+
/**
86+
* @return array
87+
*/
88+
public function provideExtensionAttributeDataForAroundSave() {
89+
return [
90+
[true, true] ,
91+
[false, false]
92+
];
93+
}
94+
95+
/**
96+
* @dataProvider provideExtensionAttributeDataForAroundSave
97+
*/
98+
public function testAroundSaveWithIsSubscribed($isSubscribed, $subscribeIsCreated) {
99+
$passwordHash = null;
100+
$customerId = 1;
101+
/** @var CustomerInterface | \PHPUnit_Framework_MockObject_MockObject $customer */
102+
$customer = $this->getMock('Magento\Customer\Api\Data\CustomerInterface');
103+
$extensionAttributes = $this
104+
->getMockBuilder("Magento\Customer\Api\Data\CustomerExtensionInterface")
105+
->setMethods(["getIsSubscribed", "setIsSubscribed"])
106+
->getMock();
107+
108+
$extensionAttributes
109+
->expects($this->atLeastOnce())
110+
->method("getIsSubscribed")
111+
->willReturn($isSubscribed);
112+
113+
$customer->expects($this->atLeastOnce())
114+
->method("getExtensionAttributes")
115+
->willReturn($extensionAttributes);
116+
117+
if ($subscribeIsCreated) {
118+
$this->subscriber->expects($this->once())
119+
->method("subscribeCustomerById")
120+
->with($customerId);
121+
} else {
122+
$this->subscriber->expects($this->once())
123+
->method("unsubscribeCustomerById")
124+
->with($customerId);
125+
}
126+
127+
$proceed = function(CustomerInterface $customer, $passwordHash = null) use($customer) {
128+
return $customer;
129+
};
130+
/** @var CustomerRepository | \PHPUnit_Framework_MockObject_MockObject $subject */
131+
$subject = $this->getMock('\Magento\Customer\Api\CustomerRepositoryInterface');
132+
133+
$customer->expects($this->atLeastOnce())
134+
->method("getId")
135+
->willReturn($customerId);
136+
137+
$this->assertEquals($customer, $this->plugin->aroundSave($subject, $proceed, $customer, $passwordHash));
138+
}
139+
63140
public function testAroundDelete()
64141
{
65142
$deleteCustomer = function () {
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
/**
4+
* Copyright © 2016 Magento. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
10+
<extension_attributes for="Magento\Customer\Api\Data\CustomerInterface">
11+
<attribute code="is_subscribed" type="boolean" />
12+
</extension_attributes>
13+
</config>

dev/tests/api-functional/framework/Magento/TestFramework/Helper/Customer.php

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Customer extends WebapiAbstract
1515
{
1616
const RESOURCE_PATH = '/V1/customers';
1717
const SERVICE_NAME = 'customerAccountManagementV1';
18+
const CUSTOMER_REPOSITORY_SERVICE_NAME = "customerCustomerRepositoryV1";
1819
const SERVICE_VERSION = 'V1';
1920

2021
const CONFIRMATION = 'a4fg7h893e39d';
@@ -78,7 +79,11 @@ public function __construct($name = null, array $data = [], $dataName = '')
7879
);
7980
}
8081

81-
public function createSampleCustomer()
82+
/**
83+
* @param array $additional
84+
* @return array|bool|float|int|string
85+
*/
86+
public function createSampleCustomer(array $additional = [])
8287
{
8388
$serviceInfo = [
8489
'rest' => [
@@ -91,21 +96,85 @@ public function createSampleCustomer()
9196
'operation' => self::SERVICE_NAME . 'CreateAccount',
9297
],
9398
];
99+
94100
$customerDataArray = $this->dataObjectProcessor->buildOutputDataArray(
95-
$this->createSampleCustomerDataObject(),
101+
$this->createSampleCustomerDataObject($additional),
102+
\Magento\Customer\Api\Data\CustomerInterface::class
103+
);
104+
$requestData = ['customer' => $customerDataArray, 'password' => self::PASSWORD];
105+
$customerData = $this->_webApiCall($serviceInfo, $requestData);
106+
return $customerData;
107+
}
108+
109+
/**
110+
* Update Existing customer
111+
*
112+
* @param array $additional
113+
* @param int $customerId
114+
* @return array|bool|float|int|string
115+
*/
116+
public function updateSampleCustomer(array $additional = [], $customerId) {
117+
$serviceInfo = [
118+
'rest' => [
119+
'resourcePath' => self::RESOURCE_PATH . "/" . $customerId,
120+
'httpMethod' => RestRequest::HTTP_METHOD_PUT,
121+
],
122+
'soap' => [
123+
'service' => self::CUSTOMER_REPOSITORY_SERVICE_NAME,
124+
'serviceVersion' => self::SERVICE_VERSION,
125+
'operation' => self::CUSTOMER_REPOSITORY_SERVICE_NAME . 'save',
126+
],
127+
];
128+
129+
$customerDataArray = $this->dataObjectProcessor->buildOutputDataArray(
130+
$this->createSampleCustomerDataObject($additional),
96131
'\Magento\Customer\Api\Data\CustomerInterface'
97132
);
98133
$requestData = ['customer' => $customerDataArray, 'password' => self::PASSWORD];
99134
$customerData = $this->_webApiCall($serviceInfo, $requestData);
100135
return $customerData;
101136
}
102137

138+
/**
139+
* @param array $additional
140+
* @return array
141+
*/
142+
private function getCustomerSampleData(array $additional = [])
143+
{
144+
$customerData = [
145+
CustomerData::FIRSTNAME => self::FIRSTNAME,
146+
CustomerData::LASTNAME => self::LASTNAME,
147+
CustomerData::EMAIL => 'janedoe' . uniqid() . '@example.com',
148+
CustomerData::CONFIRMATION => self::CONFIRMATION,
149+
CustomerData::CREATED_AT => self::CREATED_AT,
150+
CustomerData::CREATED_IN => self::STORE_NAME,
151+
CustomerData::DOB => self::DOB,
152+
CustomerData::GENDER => self::GENDER,
153+
CustomerData::GROUP_ID => self::GROUP_ID,
154+
CustomerData::MIDDLENAME => self::MIDDLENAME,
155+
CustomerData::PREFIX => self::PREFIX,
156+
CustomerData::STORE_ID => self::STORE_ID,
157+
CustomerData::SUFFIX => self::SUFFIX,
158+
CustomerData::TAXVAT => self::TAXVAT,
159+
CustomerData::WEBSITE_ID => self::WEBSITE_ID,
160+
'custom_attributes' => [
161+
[
162+
'attribute_code' => 'disable_auto_group_change',
163+
'value' => '0',
164+
],
165+
],
166+
];
167+
168+
return array_merge($customerData, $additional);
169+
}
170+
103171
/**
104172
* Create customer using setters.
105173
*
174+
* @param array $additional
106175
* @return CustomerInterface
107176
*/
108-
public function createSampleCustomerDataObject()
177+
public function createSampleCustomerDataObject(array $additional = [])
109178
{
110179
$customerAddress1 = $this->customerAddressFactory->create();
111180
$customerAddress1->setCountryId('US');
@@ -151,30 +220,9 @@ public function createSampleCustomerDataObject()
151220
'Magento\Customer\Api\Data\AddressInterface'
152221
);
153222

154-
$customerData = [
155-
CustomerData::FIRSTNAME => self::FIRSTNAME,
156-
CustomerData::LASTNAME => self::LASTNAME,
157-
CustomerData::EMAIL => 'janedoe' . uniqid() . '@example.com',
158-
CustomerData::CONFIRMATION => self::CONFIRMATION,
159-
CustomerData::CREATED_AT => self::CREATED_AT,
160-
CustomerData::CREATED_IN => self::STORE_NAME,
161-
CustomerData::DOB => self::DOB,
162-
CustomerData::GENDER => self::GENDER,
163-
CustomerData::GROUP_ID => self::GROUP_ID,
164-
CustomerData::MIDDLENAME => self::MIDDLENAME,
165-
CustomerData::PREFIX => self::PREFIX,
166-
CustomerData::STORE_ID => self::STORE_ID,
167-
CustomerData::SUFFIX => self::SUFFIX,
168-
CustomerData::TAXVAT => self::TAXVAT,
169-
CustomerData::WEBSITE_ID => self::WEBSITE_ID,
170-
CustomerData::KEY_ADDRESSES => [$address1, $address2],
171-
'custom_attributes' => [
172-
[
173-
'attribute_code' => 'disable_auto_group_change',
174-
'value' => '0',
175-
],
176-
],
177-
];
223+
$customerData = $this->getCustomerSampleData(
224+
array_merge([CustomerData::KEY_ADDRESSES => [$address1, $address2]], $additional)
225+
);
178226
$customer = $this->customerDataFactory->create();
179227
$this->dataObjectHelper->populateWithArray(
180228
$customer,

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

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
use Magento\TestFramework\TestCase\WebapiAbstract;
1515
use Magento\Framework\Webapi\Exception as HTTPExceptionCodes;
1616
use Magento\Security\Model\Config;
17+
use Magento\Newsletter\Model\Plugin\CustomerPlugin;
18+
use Magento\Framework\Webapi\Rest\Request as RestRequest;
19+
use Magento\Newsletter\Model\Subscriber;
20+
use Magento\Customer\Model\Data\Customer as CustomerData;
1721

1822
/**
1923
* Test class for Magento\Customer\Api\AccountManagementInterface
@@ -62,6 +66,9 @@ class AccountManagementTest extends WebapiAbstract
6266
*/
6367
private $currentCustomerId;
6468

69+
/** @var Subscriber */
70+
private $subscriber;
71+
6572
/**
6673
* @var \Magento\Framework\Reflection\DataObjectProcessor
6774
*/
@@ -102,6 +109,7 @@ public function setUp()
102109
$this->config = Bootstrap::getObjectManager()->create(
103110
'Magento\Config\Model\Config'
104111
);
112+
$this->initSubscriber();
105113

106114
if ($this->config->getConfigDataValue(
107115
Config::XML_PATH_FRONTED_AREA .
@@ -147,6 +155,13 @@ public function tearDown()
147155
);
148156
$this->config->save();
149157
unset($this->accountManagement);
158+
unset($this->subscriber);
159+
}
160+
161+
private function initSubscriber() {
162+
$this->subscriber = Bootstrap::getObjectManager()->create(
163+
'Magento\Newsletter\Model\Subscriber'
164+
);
150165
}
151166

152167
public function testCreateCustomer()
@@ -778,4 +793,45 @@ protected function getFirstFixtureAddressData()
778793
'region_id' => 1,
779794
];
780795
}
796+
797+
public function testCreateCustomerWithSubscription()
798+
{
799+
$customerData = $this->customerHelper->createSampleCustomer(
800+
["extension_attributes" => ["is_subscribed" => true]]
801+
);
802+
803+
$this->assertNotNull($customerData['id']);
804+
805+
$this->subscriber->loadByCustomerId($customerData['id']);
806+
807+
$this->assertNotNull($this->subscriber->getId());
808+
$this->assertEquals($customerData['id'], $this->subscriber->getCustomerId());
809+
}
810+
811+
public function testUnsubscribeCustomer()
812+
{
813+
//Creating customer and subscribe
814+
$customerData = $this->customerHelper->createSampleCustomer(
815+
["extension_attributes" => ["is_subscribed" => true]]
816+
);
817+
$this->assertNotNull($customerData['id']);
818+
819+
$this->subscriber->loadByCustomerId($customerData['id']);
820+
$subscriptionId = $this->subscriber->getId();
821+
822+
$this->assertNotNull($subscriptionId);
823+
$this->assertEquals($customerData['id'], $this->subscriber->getCustomerId());
824+
//Manage customer in order to unsubscribe
825+
$this->customerHelper->updateSampleCustomer(
826+
array_merge(
827+
$customerData,
828+
["extension_attributes" => ["is_subscribed" => false]]
829+
),
830+
$customerData["id"]
831+
);
832+
$this->initSubscriber();
833+
834+
$this->subscriber->loadByCustomerId($customerData['id']);
835+
$this->assertEquals(Subscriber::STATUS_UNSUBSCRIBED, $this->subscriber->getStatus());
836+
}
781837
}

0 commit comments

Comments
 (0)