Skip to content

Commit e5efbd4

Browse files
MAGETWO-84639: Correctly set payment information when using paypal #12401
2 parents 2cddf69 + b6437bc commit e5efbd4

File tree

6 files changed

+158
-41
lines changed

6 files changed

+158
-41
lines changed

app/code/Magento/Paypal/Model/Express.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -669,14 +669,19 @@ public function getApi()
669669
public function assignData(\Magento\Framework\DataObject $data)
670670
{
671671
parent::assignData($data);
672-
672+
673673
$additionalData = $data->getData(PaymentInterface::KEY_ADDITIONAL_DATA);
674674

675675
if (!is_array($additionalData)) {
676676
return $this;
677677
}
678678

679679
foreach ($additionalData as $key => $value) {
680+
// Skip extension attributes
681+
if ($key === \Magento\Framework\Api\ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY) {
682+
continue;
683+
}
684+
680685
$this->getInfoInstance()->setAdditionalInformation($key, $value);
681686
}
682687
return $this;

app/code/Magento/Paypal/Test/Unit/Model/ExpressTest.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,21 @@ public function testAssignData()
161161
{
162162
$transportValue = 'something';
163163

164+
$extensionAttribute = $this->getMockForAbstractClass(
165+
\Magento\Quote\Api\Data\PaymentExtensionInterface::class,
166+
[],
167+
'',
168+
false,
169+
false
170+
);
171+
164172
$data = new DataObject(
165173
[
166174
PaymentInterface::KEY_ADDITIONAL_DATA => [
167175
Express\Checkout::PAYMENT_INFO_TRANSPORT_BILLING_AGREEMENT => $transportValue,
168176
Express\Checkout::PAYMENT_INFO_TRANSPORT_PAYER_ID => $transportValue,
169-
Express\Checkout::PAYMENT_INFO_TRANSPORT_TOKEN => $transportValue
177+
Express\Checkout::PAYMENT_INFO_TRANSPORT_TOKEN => $transportValue,
178+
\Magento\Framework\Api\ExtensibleDataInterface::EXTENSION_ATTRIBUTES_KEY => $extensionAttribute
170179
]
171180
]
172181
);

app/code/Magento/Paypal/view/frontend/web/js/action/set-payment-method.js

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,12 @@
44
*/
55

66
define([
7-
'jquery',
87
'Magento_Checkout/js/model/quote',
9-
'Magento_Checkout/js/model/url-builder',
10-
'mage/storage',
11-
'Magento_Checkout/js/model/error-processor',
12-
'Magento_Customer/js/model/customer',
13-
'Magento_Checkout/js/model/full-screen-loader'
14-
], function ($, quote, urlBuilder, storage, errorProcessor, customer, fullScreenLoader) {
8+
'Magento_Checkout/js/action/set-payment-information'
9+
], function (quote, setPaymentInformation) {
1510
'use strict';
1611

1712
return function (messageContainer) {
18-
var serviceUrl,
19-
payload,
20-
paymentData = quote.paymentMethod();
21-
22-
/**
23-
* Checkout for guest and registered customer.
24-
*/
25-
if (!customer.isLoggedIn()) {
26-
serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/set-payment-information', {
27-
cartId: quote.getQuoteId()
28-
});
29-
payload = {
30-
cartId: quote.getQuoteId(),
31-
email: quote.guestEmail,
32-
paymentMethod: paymentData
33-
};
34-
} else {
35-
serviceUrl = urlBuilder.createUrl('/carts/mine/set-payment-information', {});
36-
payload = {
37-
cartId: quote.getQuoteId(),
38-
paymentMethod: paymentData
39-
};
40-
}
41-
fullScreenLoader.startLoader();
42-
43-
return storage.post(
44-
serviceUrl, JSON.stringify(payload)
45-
).fail(function (response) {
46-
errorProcessor.process(response, messageContainer);
47-
}).always(function () {
48-
fullScreenLoader.stopLoader();
49-
});
13+
return setPaymentInformation(messageContainer, quote.paymentMethod());
5014
};
5115
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'squire'
8+
], function (Squire) {
9+
'use strict';
10+
11+
var injector = new Squire(),
12+
mocks = {
13+
'Magento_Checkout/js/action/place-order': jasmine.createSpy('placeOrderAction'),
14+
'Magento_CheckoutAgreements/js/model/agreements-assigner': jasmine.createSpy('agreementsAssigner')
15+
},
16+
defaultContext = require.s.contexts._,
17+
mixin,
18+
placeOrderAction;
19+
20+
beforeEach(function (done) {
21+
window.checkoutConfig = {
22+
checkoutAgreements: {
23+
isEnabled: true
24+
}
25+
};
26+
injector.mock(mocks);
27+
injector.require([
28+
'Magento_CheckoutAgreements/js/model/place-order-mixin',
29+
'Magento_Checkout/js/action/place-order'
30+
], function (Mixin, placeOrder) {
31+
mixin = Mixin;
32+
placeOrderAction = placeOrder;
33+
done();
34+
});
35+
});
36+
37+
describe('Magento_CheckoutAgreements/js/model/place-order-mixin', function () {
38+
it('mixin is applied to Magento_Checkout/js/action/place-order', function () {
39+
var placeOrderMixins = defaultContext.config.config.mixins['Magento_Checkout/js/action/place-order'];
40+
41+
expect(placeOrderMixins['Magento_CheckoutAgreements/js/model/place-order-mixin']).toBe(true);
42+
});
43+
44+
it('Magento_CheckoutAgreements/js/model/agreements-assigner is called', function () {
45+
var messageContainer = jasmine.createSpy('messageContainer'),
46+
paymentData = {};
47+
48+
mixin(placeOrderAction)(paymentData, messageContainer);
49+
expect(mocks['Magento_CheckoutAgreements/js/model/agreements-assigner'])
50+
.toHaveBeenCalledWith(paymentData);
51+
expect(mocks['Magento_Checkout/js/action/place-order'])
52+
.toHaveBeenCalledWith(paymentData, messageContainer);
53+
});
54+
});
55+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* Copyright © Magento, Inc. All rights reserved.
3+
* See COPYING.txt for license details.
4+
*/
5+
6+
define([
7+
'squire'
8+
], function (Squire) {
9+
'use strict';
10+
11+
var injector = new Squire(),
12+
mocks = {
13+
'Magento_Checkout/js/action/set-payment-information': jasmine.createSpy('placeOrderAction'),
14+
'Magento_CheckoutAgreements/js/model/agreements-assigner': jasmine.createSpy('agreementsAssigner')
15+
},
16+
defaultContext = require.s.contexts._,
17+
mixin,
18+
placeOrderAction;
19+
20+
beforeEach(function (done) {
21+
window.checkoutConfig = {
22+
checkoutAgreements: {
23+
isEnabled: true
24+
}
25+
};
26+
injector.mock(mocks);
27+
injector.require([
28+
'Magento_CheckoutAgreements/js/model/set-payment-information-mixin',
29+
'Magento_Checkout/js/action/set-payment-information'
30+
], function (Mixin, setPaymentInformation) {
31+
mixin = Mixin;
32+
placeOrderAction = setPaymentInformation;
33+
done();
34+
});
35+
});
36+
37+
describe('Magento_CheckoutAgreements/js/model/set-payment-information-mixin', function () {
38+
it('mixin is applied to Magento_Checkout/js/action/set-payment-information', function () {
39+
var placeOrderMixins = defaultContext
40+
.config.config.mixins['Magento_Checkout/js/action/set-payment-information'];
41+
42+
expect(placeOrderMixins['Magento_CheckoutAgreements/js/model/set-payment-information-mixin']).toBe(true);
43+
});
44+
45+
it('Magento_CheckoutAgreements/js/model/agreements-assigner is called', function () {
46+
var messageContainer = jasmine.createSpy('messageContainer'),
47+
paymentData = {};
48+
49+
mixin(placeOrderAction)(messageContainer, paymentData);
50+
expect(mocks['Magento_CheckoutAgreements/js/model/agreements-assigner'])
51+
.toHaveBeenCalledWith(paymentData);
52+
expect(mocks['Magento_Checkout/js/action/set-payment-information'])
53+
.toHaveBeenCalledWith(messageContainer, paymentData);
54+
});
55+
});
56+
});

dev/tests/js/jasmine/tests/app/code/Magento/Paypal/frontend/js/view/payment/method-renderer/paypal-express-abstract.test.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,24 @@ define([
1616

1717
describe('paypal/js/view/payment/method-renderer/paypal-express-abstract', function () {
1818
var injector = new Squire(),
19+
successPromise = jasmine.createSpyObj('successPromise', ['done']),
20+
setPaymentMock = jasmine.createSpy('set-payment-information', function () {
21+
return successPromise;
22+
}).and.callThrough(),
23+
validateMock = jasmine.createSpy('validate', function () {
24+
return true;
25+
}).and.callThrough(),
1926
mocks = {
2027
'Magento_Checkout/js/model/quote': {
2128
billingAddress: ko.observable(),
2229
shippingAddress: ko.observable(),
2330
paymentMethod: ko.observable(),
2431
totals: ko.observable({})
2532

33+
},
34+
'Magento_Checkout/js/action/set-payment-information': setPaymentMock,
35+
'Magento_Checkout/js/model/payment/additional-validators': {
36+
validate: validateMock
2637
}
2738
},
2839
paypalExpressAbstract,
@@ -85,6 +96,23 @@ define([
8596
}, 500);
8697
});
8798

99+
it('setPaymentMethodAction is called before redirect to paypal', function () {
100+
spyOn(paypalExpressAbstract, 'selectPaymentMethod');
101+
paypalExpressAbstract.continueToPayPal();
102+
expect(paypalExpressAbstract.selectPaymentMethod).toHaveBeenCalled();
103+
expect(validateMock).toHaveBeenCalled();
104+
expect(validateMock.calls.mostRecent()).toEqual(jasmine.objectContaining({
105+
object: mocks['Magento_Checkout/js/model/payment/additional-validators'],
106+
args: [],
107+
returnValue: true
108+
}));
109+
expect(setPaymentMock).toHaveBeenCalled();
110+
expect(setPaymentMock.calls.mostRecent()).toEqual(jasmine.objectContaining({
111+
returnValue: successPromise
112+
}));
113+
expect(successPromise.done).toHaveBeenCalledWith(jasmine.any(Function));
114+
});
115+
88116
afterAll(function (done) {
89117
tplElement.remove();
90118
done();

0 commit comments

Comments
 (0)