Skip to content

Commit 814564b

Browse files
committed
fix(payment): PAYMENTS-8239 sorts recommended option first for applepay
1 parent 6420c20 commit 814564b

8 files changed

+367
-32
lines changed

packages/apple-pay-integration/src/apple-pay-button-strategy.spec.ts

+71
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,77 @@ describe('ApplePayButtonStrategy', () => {
336336
}
337337
});
338338

339+
it('gets shipping options sorted correctly with recommended option first', async () => {
340+
jest.spyOn(paymentIntegrationService, 'updateShippingAddress').mockResolvedValue(true);
341+
342+
const CheckoutButtonInitializeOptions = getApplePayButtonInitializationOptions();
343+
const newCheckout = {
344+
...getCheckout(),
345+
consignments: [
346+
{
347+
...getConsignment(),
348+
availableShippingOptions: [
349+
{
350+
...getShippingOption(),
351+
description: 'Free Shipping',
352+
additionalDescription: 'Free shipping to your order',
353+
isRecommended: false,
354+
id: '0:11111111',
355+
},
356+
{
357+
...getShippingOption(),
358+
id: '0:22222222',
359+
},
360+
],
361+
},
362+
],
363+
};
364+
365+
const freeShippingOption = newCheckout.consignments[0].availableShippingOptions[0];
366+
const flatFeeShippingOption = newCheckout.consignments[0].availableShippingOptions[1];
367+
368+
const expectedShippingMethods = [
369+
{
370+
label: flatFeeShippingOption.description,
371+
amount: flatFeeShippingOption.cost.toFixed(2),
372+
detail: flatFeeShippingOption.additionalDescription,
373+
identifier: flatFeeShippingOption.id,
374+
},
375+
{
376+
label: freeShippingOption.description,
377+
amount: freeShippingOption.cost.toFixed(2),
378+
detail: freeShippingOption.additionalDescription,
379+
identifier: freeShippingOption.id,
380+
},
381+
];
382+
383+
jest.spyOn(paymentIntegrationService.getState(), 'getCheckoutOrThrow').mockReturnValue(
384+
newCheckout,
385+
);
386+
387+
await strategy.initialize(CheckoutButtonInitializeOptions);
388+
389+
if (CheckoutButtonInitializeOptions.applepay) {
390+
const button = container.firstChild as HTMLElement;
391+
392+
if (button) {
393+
button.click();
394+
395+
const event = {
396+
shippingContact: getContactAddress(),
397+
} as ApplePayJS.ApplePayShippingContactSelectedEvent;
398+
399+
await applePaySession.onshippingcontactselected(event);
400+
401+
const actualShippingMethods =
402+
applePaySession.completeShippingContactSelection.mock.calls[0][0]
403+
.newShippingMethods;
404+
405+
expect(actualShippingMethods).toEqual(expectedShippingMethods);
406+
}
407+
}
408+
});
409+
339410
it('gets call to update shipping option in consignment fails', async () => {
340411
jest.spyOn(paymentIntegrationService, 'selectShippingOption').mockRejectedValue(false);
341412

packages/apple-pay-integration/src/apple-pay-button-strategy.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,27 @@ export default class ApplePayButtonStrategy implements CheckoutButtonStrategy {
267267
]
268268
: [];
269269

270-
unselectedOptions?.forEach((option) =>
271-
shippingOptions.push({
272-
label: option.description,
273-
amount: `${option.cost.toFixed(decimalPlaces)}`,
274-
detail: option.additionalDescription,
275-
identifier: option.id,
276-
}),
277-
);
270+
unselectedOptions
271+
?.filter((option) => option.isRecommended)
272+
?.forEach((option) =>
273+
shippingOptions.push({
274+
label: option.description,
275+
amount: `${option.cost.toFixed(decimalPlaces)}`,
276+
detail: option.additionalDescription,
277+
identifier: option.id,
278+
}),
279+
);
280+
281+
unselectedOptions
282+
?.filter((option) => !option.isRecommended)
283+
?.forEach((option) =>
284+
shippingOptions.push({
285+
label: option.description,
286+
amount: `${option.cost.toFixed(decimalPlaces)}`,
287+
detail: option.additionalDescription,
288+
identifier: option.id,
289+
}),
290+
);
278291

279292
if (!isShippingOptions(availableOptions)) {
280293
throw new Error('Shipping options not available.');

packages/apple-pay-integration/src/apple-pay-customer-strategy.spec.ts

+71
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,77 @@ describe('ApplePayCustomerStrategy', () => {
324324
}
325325
});
326326

327+
it('gets shipping options sorted correctly with recommended option first', async () => {
328+
jest.spyOn(paymentIntegrationService, 'updateShippingAddress').mockResolvedValue(true);
329+
330+
const CheckoutButtonInitializeOptions = getApplePayCustomerInitializationOptions();
331+
const newCheckout = {
332+
...getCheckout(),
333+
consignments: [
334+
{
335+
...getConsignment(),
336+
availableShippingOptions: [
337+
{
338+
...getShippingOption(),
339+
description: 'Free Shipping',
340+
additionalDescription: 'Free shipping to your order',
341+
isRecommended: false,
342+
id: '0:1111111',
343+
},
344+
{
345+
...getShippingOption(),
346+
id: '0:22222222',
347+
},
348+
],
349+
},
350+
],
351+
};
352+
353+
const freeShippingOption = newCheckout.consignments[0].availableShippingOptions[0];
354+
const flatFeeShippingOption = newCheckout.consignments[0].availableShippingOptions[1];
355+
356+
const expectedShippingMethods = [
357+
{
358+
label: flatFeeShippingOption.description,
359+
amount: flatFeeShippingOption.cost.toFixed(2),
360+
detail: flatFeeShippingOption.additionalDescription,
361+
identifier: flatFeeShippingOption.id,
362+
},
363+
{
364+
label: freeShippingOption.description,
365+
amount: freeShippingOption.cost.toFixed(2),
366+
detail: freeShippingOption.additionalDescription,
367+
identifier: freeShippingOption.id,
368+
},
369+
];
370+
371+
jest.spyOn(paymentIntegrationService.getState(), 'getCheckoutOrThrow').mockReturnValue(
372+
newCheckout,
373+
);
374+
375+
await strategy.initialize(CheckoutButtonInitializeOptions);
376+
377+
if (CheckoutButtonInitializeOptions.applepay) {
378+
const button = container.firstChild as HTMLElement;
379+
380+
if (button) {
381+
button.click();
382+
383+
const event = {
384+
shippingContact: getContactAddress(),
385+
} as ApplePayJS.ApplePayShippingContactSelectedEvent;
386+
387+
await applePaySession.onshippingcontactselected(event);
388+
389+
const actualShippingMethods =
390+
applePaySession.completeShippingContactSelection.mock.calls[0][0]
391+
.newShippingMethods;
392+
393+
expect(actualShippingMethods).toEqual(expectedShippingMethods);
394+
}
395+
}
396+
});
397+
327398
it('throws error if call to update address fails', async () => {
328399
jest.spyOn(paymentIntegrationService, 'updateShippingAddress').mockRejectedValue(false);
329400

packages/apple-pay-integration/src/apple-pay-customer-strategy.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -297,14 +297,27 @@ export default class ApplePayCustomerStrategy implements CustomerStrategy {
297297
]
298298
: [];
299299

300-
unselectedOptions?.forEach((option) =>
301-
shippingOptions.push({
302-
label: option.description,
303-
amount: `${option.cost.toFixed(decimalPlaces)}`,
304-
detail: option.additionalDescription,
305-
identifier: option.id,
306-
}),
307-
);
300+
unselectedOptions
301+
?.filter((option) => option.isRecommended)
302+
?.forEach((option) =>
303+
shippingOptions.push({
304+
label: option.description,
305+
amount: `${option.cost.toFixed(decimalPlaces)}`,
306+
detail: option.additionalDescription,
307+
identifier: option.id,
308+
}),
309+
);
310+
311+
unselectedOptions
312+
?.filter((option) => !option.isRecommended)
313+
?.forEach((option) =>
314+
shippingOptions.push({
315+
label: option.description,
316+
amount: `${option.cost.toFixed(decimalPlaces)}`,
317+
detail: option.additionalDescription,
318+
identifier: option.id,
319+
}),
320+
);
308321

309322
if (!isShippingOptions(availableOptions)) {
310323
throw new Error('Shipping options not available.');

packages/core/src/checkout-buttons/strategies/apple-pay/apple-pay-button-strategy.spec.ts

+72
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,78 @@ describe('ApplePayButtonStrategy', () => {
431431
}
432432
});
433433

434+
it('gets shipping options sorted correctly with recommended option first', async () => {
435+
const CheckoutButtonInitializeOptions = getApplePayButtonInitializationOptions();
436+
const newCheckout = {
437+
...getCheckout(),
438+
consignments: [
439+
{
440+
...getConsignment(),
441+
availableShippingOptions: [
442+
{
443+
...getShippingOption(),
444+
description: 'Free Shipping',
445+
additionalDescription: 'Free shipping to your order',
446+
isRecommended: false,
447+
id: '0:11111111',
448+
},
449+
{
450+
...getShippingOption(),
451+
id: '0:22222222',
452+
},
453+
],
454+
},
455+
],
456+
};
457+
458+
const freeShippingOption = newCheckout.consignments[0].availableShippingOptions[0];
459+
const flatFeeShippingOption = newCheckout.consignments[0].availableShippingOptions[1];
460+
461+
const expectedShippingMethods = [
462+
{
463+
label: flatFeeShippingOption.description,
464+
amount: flatFeeShippingOption.cost.toFixed(2),
465+
detail: flatFeeShippingOption.additionalDescription,
466+
identifier: flatFeeShippingOption.id,
467+
},
468+
{
469+
label: freeShippingOption.description,
470+
amount: freeShippingOption.cost.toFixed(2),
471+
detail: freeShippingOption.additionalDescription,
472+
identifier: freeShippingOption.id,
473+
},
474+
];
475+
476+
jest.spyOn(checkoutActionCreator, 'loadDefaultCheckout').mockReturnValue(() =>
477+
from([
478+
createAction(CheckoutActionType.LoadCheckoutRequested),
479+
createAction(CheckoutActionType.LoadCheckoutSucceeded, newCheckout),
480+
]),
481+
);
482+
483+
await strategy.initialize(CheckoutButtonInitializeOptions);
484+
485+
if (CheckoutButtonInitializeOptions.applepay) {
486+
const button = container.firstChild as HTMLElement;
487+
488+
if (button) {
489+
button.click();
490+
491+
const event = {
492+
shippingContact: getContactAddress(),
493+
} as ApplePayJS.ApplePayShippingContactSelectedEvent;
494+
495+
await applePaySession.onshippingcontactselected(event);
496+
497+
const actualShippingMethods =
498+
applePaySession.completeShippingContactSelection.mock.calls[0][0]
499+
.newShippingMethods;
500+
501+
expect(actualShippingMethods).toEqual(expectedShippingMethods);
502+
}
503+
}
504+
});
505+
434506
it('gets call to update shipping option in consignment fails', async () => {
435507
jest.spyOn(consignmentActionCreator, 'selectShippingOption').mockRejectedValue(false);
436508

packages/core/src/checkout-buttons/strategies/apple-pay/apple-pay-button-strategy.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,27 @@ export default class ApplePayButtonStrategy implements CheckoutButtonStrategy {
282282
]
283283
: [];
284284

285-
unselectedOptions?.forEach((option) =>
286-
shippingOptions.push({
287-
label: option.description,
288-
amount: `${option.cost.toFixed(decimalPlaces)}`,
289-
detail: option.additionalDescription,
290-
identifier: option.id,
291-
}),
292-
);
285+
unselectedOptions
286+
?.filter((option) => option.isRecommended)
287+
?.forEach((option) =>
288+
shippingOptions.push({
289+
label: option.description,
290+
amount: `${option.cost.toFixed(decimalPlaces)}`,
291+
detail: option.additionalDescription,
292+
identifier: option.id,
293+
}),
294+
);
295+
296+
unselectedOptions
297+
?.filter((option) => !option.isRecommended)
298+
?.forEach((option) =>
299+
shippingOptions.push({
300+
label: option.description,
301+
amount: `${option.cost.toFixed(decimalPlaces)}`,
302+
detail: option.additionalDescription,
303+
identifier: option.id,
304+
}),
305+
);
293306

294307
if (!isShippingOptions(availableOptions)) {
295308
throw new Error('Shipping options not available.');

0 commit comments

Comments
 (0)