Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
toResolvableModule,
} from '@bigcommerce/checkout-sdk/payment-integration-api';

import createPayPalCommerceIntegrationService from '../create-paypal-commerce-integration-service';
import { createPayPalIntegrationService } from '@bigcommerce/checkout-sdk/paypal-utils';

import PayPalCommerceAlternativeMethodsButtonStrategy from './paypal-commerce-alternative-methods-button-strategy';

Expand All @@ -12,7 +12,7 @@ const createPayPalCommerceAlternativeMethodsButtonStrategy: CheckoutButtonStrate
> = (paymentIntegrationService) =>
new PayPalCommerceAlternativeMethodsButtonStrategy(
paymentIntegrationService,
createPayPalCommerceIntegrationService(paymentIntegrationService),
createPayPalIntegrationService(paymentIntegrationService),
);

export default toResolvableModule(createPayPalCommerceAlternativeMethodsButtonStrategy, [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@ import {
getCart,
PaymentIntegrationServiceMock,
} from '@bigcommerce/checkout-sdk/payment-integrations-test-utils';

import {
getPayPalCommerceIntegrationServiceMock,
getPayPalCommercePaymentMethod,
getPayPalIntegrationServiceMock,
getPayPalPaymentMethod,
getPayPalSDKMock,
} from '../mocks';
import PayPalCommerceIntegrationService from '../paypal-commerce-integration-service';
import {
PayPalCommerceButtonsOptions,
PayPalCommerceHostWindow,
PayPalButtonsOptions,
PayPalHostWindow,
PayPalIntegrationService,
PayPalSDK,
} from '../paypal-commerce-types';
} from '@bigcommerce/checkout-sdk/paypal-utils';

import PayPalCommerceAlternativeMethodsButtonOptions from './paypal-commerce-alternative-methods-button-initialize-options';
import PayPalCommerceAlternativeMethodsButtonStrategy from './paypal-commerce-alternative-methods-button-strategy';
Expand All @@ -37,7 +34,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
let paymentIntegrationService: PaymentIntegrationService;
let paymentMethod: PaymentMethod;
let paypalButtonElement: HTMLDivElement;
let paypalCommerceIntegrationService: PayPalCommerceIntegrationService;
let paypalIntegrationService: PayPalIntegrationService;
let paypalSdk: PayPalSDK;

const defaultMethodId = 'paypalcommercealternativemethods';
Expand Down Expand Up @@ -85,15 +82,15 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {

eventEmitter = new EventEmitter();

paypalCommerceIntegrationService = getPayPalCommerceIntegrationServiceMock();
paymentMethod = { ...getPayPalCommercePaymentMethod(), id: defaultMethodId };
paypalIntegrationService = getPayPalIntegrationServiceMock();
paymentMethod = { ...getPayPalPaymentMethod(), id: defaultMethodId };
paypalSdk = getPayPalSDKMock();

paymentIntegrationService = new PaymentIntegrationServiceMock();

strategy = new PayPalCommerceAlternativeMethodsButtonStrategy(
paymentIntegrationService,
paypalCommerceIntegrationService,
paypalIntegrationService,
);

paypalButtonElement = document.createElement('div');
Expand All @@ -105,93 +102,87 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
paymentMethod,
);

jest.spyOn(paypalCommerceIntegrationService, 'loadPayPalSdk').mockReturnValue(
jest.spyOn(paypalIntegrationService, 'loadPayPalSdk').mockReturnValue(
Promise.resolve(paypalSdk),
);
jest.spyOn(paypalCommerceIntegrationService, 'getPayPalSdkOrThrow').mockReturnValue(
paypalSdk,
);
jest.spyOn(paypalCommerceIntegrationService, 'createBuyNowCartOrThrow').mockReturnValue(
jest.spyOn(paypalIntegrationService, 'getPayPalSdkOrThrow').mockReturnValue(paypalSdk);
jest.spyOn(paypalIntegrationService, 'createBuyNowCartOrThrow').mockReturnValue(
Promise.resolve(buyNowCart),
);
jest.spyOn(paypalCommerceIntegrationService, 'createOrder');
jest.spyOn(paypalCommerceIntegrationService, 'tokenizePayment').mockImplementation(
jest.fn(),
);
jest.spyOn(paypalCommerceIntegrationService, 'removeElement').mockImplementation(jest.fn());
jest.spyOn(paypalIntegrationService, 'createOrder');
jest.spyOn(paypalIntegrationService, 'tokenizePayment').mockImplementation(jest.fn());
jest.spyOn(paypalIntegrationService, 'removeElement').mockImplementation(jest.fn());

jest.spyOn(paypalSdk, 'Buttons').mockImplementation((options: PayPalButtonsOptions) => {
eventEmitter.on('createOrder', () => {
if (options.createOrder) {
options.createOrder();
}
});

eventEmitter.on(
'onClick',
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async (jestSuccessExpectationsCallback, jestFailureExpectationsCallback) => {
try {
if (options.onClick) {
await options.onClick(
{ fundingSource: apmProviderId },
{
reject: jest.fn(),
resolve: jest.fn(),
},
);

jest.spyOn(paypalSdk, 'Buttons').mockImplementation(
(options: PayPalCommerceButtonsOptions) => {
eventEmitter.on('createOrder', () => {
if (options.createOrder) {
options.createOrder();
}
});

eventEmitter.on(
'onClick',
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async (jestSuccessExpectationsCallback, jestFailureExpectationsCallback) => {
try {
if (options.onClick) {
await options.onClick(
{ fundingSource: apmProviderId },
{
reject: jest.fn(),
resolve: jest.fn(),
},
);

if (
jestSuccessExpectationsCallback &&
typeof jestSuccessExpectationsCallback === 'function'
) {
jestSuccessExpectationsCallback();
}
}
} catch (error) {
if (
jestFailureExpectationsCallback &&
typeof jestFailureExpectationsCallback === 'function'
jestSuccessExpectationsCallback &&
typeof jestSuccessExpectationsCallback === 'function'
) {
jestFailureExpectationsCallback(error);
jestSuccessExpectationsCallback();
}
}
},
);

eventEmitter.on('onApprove', () => {
if (options.onApprove) {
options.onApprove(
{ orderID: paypalOrderId },
{
order: {
get: jest.fn(),
},
},
);
} catch (error) {
if (
jestFailureExpectationsCallback &&
typeof jestFailureExpectationsCallback === 'function'
) {
jestFailureExpectationsCallback(error);
}
}
});
},
);

eventEmitter.on('onCancel', () => {
if (options.onCancel) {
options.onCancel();
}
});
eventEmitter.on('onApprove', () => {
if (options.onApprove) {
options.onApprove(
{ orderID: paypalOrderId },
{
order: {
get: jest.fn(),
},
},
);
}
});

return {
isEligible: jest.fn(() => true),
render: jest.fn(),
close: jest.fn(),
};
},
);
eventEmitter.on('onCancel', () => {
if (options.onCancel) {
options.onCancel();
}
});

return {
isEligible: jest.fn(() => true),
render: jest.fn(),
close: jest.fn(),
};
});
});

afterEach(() => {
jest.clearAllMocks();

delete (window as PayPalCommerceHostWindow).paypal;
delete (window as PayPalHostWindow).paypal;

if (document.getElementById(defaultButtonContainerId)) {
document.body.removeChild(paypalButtonElement);
Expand Down Expand Up @@ -308,7 +299,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
it('loads paypal commerce sdk script', async () => {
await strategy.initialize(initializationOptions);

expect(paypalCommerceIntegrationService.loadPayPalSdk).toHaveBeenCalledWith(
expect(paypalIntegrationService.loadPayPalSdk).toHaveBeenCalledWith(
defaultMethodId,
cart.currency.code,
false,
Expand All @@ -318,7 +309,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
it('loads paypal commerce sdk script with provided currency code (Buy Now flow)', async () => {
await strategy.initialize(buyNowInitializationOptions);

expect(paypalCommerceIntegrationService.loadPayPalSdk).toHaveBeenCalledWith(
expect(paypalIntegrationService.loadPayPalSdk).toHaveBeenCalledWith(
defaultMethodId,
buyNowPayPalCommerceAlternativeMethodsOptions.currencyCode,
false,
Expand Down Expand Up @@ -416,7 +407,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
},
});

expect(paypalCommerceIntegrationService.removeElement).toHaveBeenCalledWith(
expect(paypalIntegrationService.removeElement).toHaveBeenCalledWith(
defaultButtonContainerId,
);
});
Expand All @@ -430,7 +421,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {

await new Promise((resolve) => process.nextTick(resolve));

expect(paypalCommerceIntegrationService.createOrder).toHaveBeenCalledWith(
expect(paypalIntegrationService.createOrder).toHaveBeenCalledWith(
'paypalcommercealternativemethod',
);
});
Expand All @@ -449,7 +440,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {
eventEmitter.emit('onClick');
await new Promise((resolve) => process.nextTick(resolve));

expect(paypalCommerceIntegrationService.createBuyNowCartOrThrow).toHaveBeenCalled();
expect(paypalIntegrationService.createBuyNowCartOrThrow).toHaveBeenCalled();
});

it('loads checkout related to buy now cart on button click', async () => {
Expand All @@ -469,7 +460,7 @@ describe('PayPalCommerceAlternativeMethodsButtonStrategy', () => {

await new Promise((resolve) => process.nextTick(resolve));

expect(paypalCommerceIntegrationService.tokenizePayment).toHaveBeenCalledWith(
expect(paypalIntegrationService.tokenizePayment).toHaveBeenCalledWith(
defaultMethodId,
paypalOrderId,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import {
InvalidArgumentError,
PaymentIntegrationService,
} from '@bigcommerce/checkout-sdk/payment-integration-api';
import { PayPalIntegrationService } from '@bigcommerce/checkout-sdk/paypal-utils';

import PayPalCommerceIntegrationService from '../paypal-commerce-integration-service';
import {
ApproveCallbackPayload,
PayPalBuyNowInitializeOptions,
Expand All @@ -21,7 +21,7 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy
{
constructor(
private paymentIntegrationService: PaymentIntegrationService,
private paypalCommerceIntegrationService: PayPalCommerceIntegrationService,
private paypalIntegrationService: PayPalIntegrationService,
) {}

async initialize(
Expand Down Expand Up @@ -89,7 +89,7 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy
? providedCurrencyCode
: this.paymentIntegrationService.getState().getCartOrThrow().currency.code;

await this.paypalCommerceIntegrationService.loadPayPalSdk(methodId, currencyCode, false);
await this.paypalIntegrationService.loadPayPalSdk(methodId, currencyCode, false);

this.renderButton(containerId, methodId, paypalcommercealternativemethods);
}
Expand All @@ -106,7 +106,7 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy
const { apm, buyNowInitializeOptions, style, onEligibilityFailure } =
paypalcommercealternativemethods;

const paypalSdk = this.paypalCommerceIntegrationService.getPayPalSdkOrThrow();
const paypalSdk = this.paypalIntegrationService.getPayPalSdkOrThrow();
const isAvailableFundingSource = Object.values(paypalSdk.FUNDING).includes(apm);

if (!isAvailableFundingSource) {
Expand All @@ -117,11 +117,9 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy

const defaultCallbacks = {
createOrder: () =>
this.paypalCommerceIntegrationService.createOrder(
'paypalcommercealternativemethod',
),
this.paypalIntegrationService.createOrder('paypalcommercealternativemethod'),
onApprove: ({ orderID }: ApproveCallbackPayload) =>
this.paypalCommerceIntegrationService.tokenizePayment(methodId, orderID),
this.paypalIntegrationService.tokenizePayment(methodId, orderID),
};

const buyNowFlowCallbacks = {
Expand All @@ -131,7 +129,7 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy

const buttonRenderOptions: PayPalCommerceButtonsOptions = {
fundingSource: apm,
style: this.paypalCommerceIntegrationService.getValidButtonStyle(style),
style: this.paypalIntegrationService.getValidButtonStyle(style),
...defaultCallbacks,
...(buyNowInitializeOptions && buyNowFlowCallbacks),
};
Expand All @@ -143,15 +141,15 @@ export default class PayPalCommerceAlternativeMethodsButtonStrategy
} else if (onEligibilityFailure && typeof onEligibilityFailure === 'function') {
onEligibilityFailure();
} else {
this.paypalCommerceIntegrationService.removeElement(containerId);
this.paypalIntegrationService.removeElement(containerId);
}
}

private async handleClick(
buyNowInitializeOptions?: PayPalBuyNowInitializeOptions,
): Promise<void> {
if (buyNowInitializeOptions) {
const buyNowCart = await this.paypalCommerceIntegrationService.createBuyNowCartOrThrow(
const buyNowCart = await this.paypalIntegrationService.createBuyNowCartOrThrow(
buyNowInitializeOptions,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { PaymentIntegrationService } from '@bigcommerce/checkout-sdk/payment-integration-api';
import { PaymentIntegrationServiceMock } from '@bigcommerce/checkout-sdk/payment-integrations-test-utils';

import createPayPalIntegrationService from './create-paypal-integration-service';
import PaypalIntegrationService from './paypal-integration-service';

describe('createPayPalIntegrationService', () => {
let paymentIntegrationService: PaymentIntegrationService;

beforeEach(() => {
paymentIntegrationService = new PaymentIntegrationServiceMock();
});

it('instantiates PayPal integration service', () => {
const service = createPayPalIntegrationService(paymentIntegrationService);

expect(service).toBeInstanceOf(PaypalIntegrationService);
});
});
Loading