Skip to content

Commit

Permalink
fastlane wrapper unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme committed Nov 26, 2024
1 parent 4331406 commit 7be420a
Show file tree
Hide file tree
Showing 3 changed files with 165 additions and 3 deletions.
148 changes: 148 additions & 0 deletions packages/lib/src/components/PayPalFastlane/FastlaneSDK.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import { mockDeep, mock, mockReset } from 'jest-mock-extended';
import initializeFastlane from './initializeFastlane';
import { httpPost } from '../../core/Services/http';
import Script from '../../utils/Script';
import type { Fastlane, FastlaneProfile, FastlaneShipping } from './types';

const fastlaneMock = mockDeep<Fastlane>();
const fastlaneConstructorMock = jest.fn().mockResolvedValue(fastlaneMock);

const mockScriptLoaded = jest.fn().mockImplementation(() => {
window.paypal = {};
window.paypal.Fastlane = fastlaneConstructorMock;
return Promise.resolve();
});

jest.mock('../../core/Services/http');
jest.mock('../../utils/Script', () => {
return jest.fn().mockImplementation(() => {
return { load: mockScriptLoaded };
});
});

const httpPostMock = (httpPost as jest.Mock).mockResolvedValue({
id: 'RANDOM-ID',
clientId: 'CLIENT-ID',
merchantId: 'XXXYYYZZZ',
value: 'TOKEN-VALUE',
expiresAt: '2024-11-01T13:34:01.804+00:00'
});

describe('FastlaneSDK', () => {
beforeEach(() => {
mockReset(fastlaneMock);
});

test('should initialize the Fastlane SDK', async () => {
await initializeFastlane({
clientKey: 'test_xxx',
environment: 'test'
});

expect(fastlaneConstructorMock).toHaveBeenCalledTimes(1);
expect(fastlaneConstructorMock).toHaveBeenCalledWith({});
expect(fastlaneMock.setLocale).toHaveBeenCalledWith('en_us');
expect(httpPostMock).toHaveBeenCalledWith({
loadingContext: 'https://checkoutshopper-test.adyen.com/checkoutshopper/',
path: 'utility/v1/payPalFastlane/tokens?clientKey=test_xxx',
errorLevel: 'fatal'
});
expect(Script).toHaveBeenCalledWith(
'https://www.paypal.com/sdk/js?client-id=CLIENT-ID&components=buttons,fastlane',
'body',
{},
{ sdkClientToken: 'TOKEN-VALUE' }
);
});

test('should return not_found if email is not recognized', async () => {
fastlaneMock.identity.lookupCustomerByEmail.mockResolvedValue({
customerContextId: null
});

const fastlane = await initializeFastlane({
clientKey: 'test_xxx',
environment: 'test'
});

const authResult = await fastlane.authenticate('[email protected]');

expect(authResult.authenticationState).toBe('not_found');
expect(authResult.profileData).toBeUndefined();
});

test('should authenticate the user with email', async () => {
const customerContextId = 'customer-context-id';
const mockedFastlaneProfile = mock<FastlaneProfile>();

fastlaneMock.identity.lookupCustomerByEmail.mockResolvedValue({
customerContextId
});

fastlaneMock.identity.triggerAuthenticationFlow.mockResolvedValue({
authenticationState: 'succeeded',
profileData: mockedFastlaneProfile
});

const fastlane = await initializeFastlane({
clientKey: 'test_xxx',
environment: 'test'
});

const authResult = await fastlane.authenticate('[email protected]');

expect(fastlaneMock.identity.lookupCustomerByEmail).toHaveBeenCalledWith('[email protected]');
expect(fastlaneMock.identity.triggerAuthenticationFlow).toHaveBeenCalledWith(customerContextId);
expect(authResult.authenticationState).toBe('succeeded');
expect(authResult.profileData).toBeDefined();
});

test('should call Fastlane shipping address selector method', async () => {
const customerContextId = 'customer-context-id';
const mockedFastlaneProfile = mock<FastlaneProfile>();
const mockedFastlaneShipping = mock<FastlaneShipping>();

const fastlane = await initializeFastlane({
clientKey: 'test_xxx',
environment: 'test'
});

fastlaneMock.profile.showShippingAddressSelector.mockResolvedValue({
selectionChanged: false,
selectedAddress: mockedFastlaneShipping
});

fastlaneMock.identity.lookupCustomerByEmail.mockResolvedValue({
customerContextId
});

fastlaneMock.identity.triggerAuthenticationFlow.mockResolvedValue({
authenticationState: 'succeeded',
profileData: mockedFastlaneProfile
});

await fastlane.authenticate('[email protected]');
const addressSelectorResult = await fastlane.showShippingAddressSelector();

expect(fastlaneMock.profile.showShippingAddressSelector).toHaveBeenCalledTimes(1);
expect(addressSelectorResult.selectionChanged).toBeFalsy();
});

test('should mount Fastlane watermark', async () => {
const componentMock = {
render: jest.fn()
};
fastlaneMock.FastlaneWatermarkComponent.mockResolvedValue(componentMock);

const fastlane = await initializeFastlane({
clientKey: 'test_xxx',
environment: 'test'
});

await fastlane.mountWatermark('.my-div');

expect(fastlaneMock.FastlaneWatermarkComponent).toHaveBeenCalledTimes(1);
expect(componentMock.render).toHaveBeenCalledTimes(1);
expect(componentMock.render).toHaveBeenCalledWith('.my-div');
});
});
18 changes: 16 additions & 2 deletions packages/lib/src/components/PayPalFastlane/FastlaneSDK.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import Script from '../../utils/Script';
import type { Fastlane, FastlaneAuthenticatedCustomerResult, FastlaneShippingAddressSelectorResult } from './types';
import type { FastlaneTokenData } from './services/request-fastlane-token';
import type { CoreConfiguration } from '../../core/types';
import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError';

export interface FastlaneSDKConfiguration {
clientKey: string;
environment: CoreConfiguration['environment'];
locale?: 'en-US' | 'es-US' | 'fr-RS' | 'zh-US';
environment?: CoreConfiguration['environment'];
}

class FastlaneSDK {
Expand All @@ -21,6 +22,9 @@ class FastlaneSDK {
private fastlaneSdk: Fastlane;

constructor(configuration: FastlaneSDKConfiguration) {
if (!configuration.environment) throw new AdyenCheckoutError('IMPLEMENTATION_ERROR', "FastlaneSDK: 'environment' property is required");
if (!configuration.clientKey) throw new AdyenCheckoutError('IMPLEMENTATION_ERROR', "FastlaneSDK: 'clientKey' property is required");

const { apiUrl } = resolveEnvironments(configuration.environment);

this.checkoutShopperURL = apiUrl;
Expand All @@ -36,6 +40,10 @@ class FastlaneSDK {
}

public async authenticate(email: string): Promise<FastlaneAuthenticatedCustomerResult> {
if (!this.fastlaneSdk) {
throw new AdyenCheckoutError('IMPLEMENTATION_ERROR', 'FastlaneSDK is not initialized');
}

const { customerContextId } = await this.fastlaneSdk.identity.lookupCustomerByEmail(email);

if (customerContextId) {
Expand All @@ -49,11 +57,17 @@ class FastlaneSDK {
}

public showShippingAddressSelector(): Promise<FastlaneShippingAddressSelectorResult> {
if (!this.fastlaneSdk.profile) return null;
if (!this.fastlaneSdk) {
throw new AdyenCheckoutError('IMPLEMENTATION_ERROR', 'FastlaneSDK is not initialized');
}
return this.fastlaneSdk.profile.showShippingAddressSelector();
}

public async mountWatermark(container: HTMLElement | string, options = { includeAdditionalInfo: false }): Promise<void> {
if (!this.fastlaneSdk) {
throw new AdyenCheckoutError('IMPLEMENTATION_ERROR', 'FastlaneSDK is not initialized');
}

const component = await this.fastlaneSdk.FastlaneWatermarkComponent(options);
component.render(container);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function requestFastlaneToken(url: string, clientKey: string): Promise<FastlaneT
// id: '2747bd08-783a-45c6-902b-3efbda5497b7',
// clientId: 'AXy9hIzWB6h_LjZUHjHmsbsiicSIbL4GKOrcgomEedVjduUinIU4C2llxkW5p0OG0zTNgviYFceaXEnj',
// merchantId: 'C3UCKQHMW4948',
// value: 'eyJraWQiOiJkMTA2ZTUwNjkzOWYxMWVlYjlkMTAyNDJhYzEyMDAwMiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwczovL2FwaS5zYW5kYm94LnBheXBhbC5jb20iLCJhdWQiOlsiaHR0cHM6Ly9hcGkuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJjaGVja291dC1wbGF5Z3JvdW5kLm5ldGxpZnkuYXBwIl0sInN1YiI6Ik02VE5BRVNaNUZHTk4iLCJhY3IiOlsiY2xpZW50Il0sInNjb3BlIjpbIkJyYWludHJlZTpWYXVsdCJdLCJvcHRpb25zIjp7fSwiYXoiOiJjY2cxOC5zbGMiLCJleHRlcm5hbF9pZCI6WyJQYXlQYWw6QzNVQ0tRSE1XNDk0OCIsIkJyYWludHJlZTozZGI4aG5rdHJ0bXpzMmd0Il0sImV4cCI6MTczMjUzMjkzNSwiaWF0IjoxNzMyNTMyMDM1LCJqdGkiOiJVMkFBTC16eVMxcXhaSjRxSWM5ei1wei0tODRGSkx1M2NDWFFKblZCb0tWemVoWmhTZzNHTVNCQW9WcHhoNmZFY2pNM3hqTnJWRzM2NTdVOUJCWHFjSlhRVW9ucjQ0dlZJcEZlaUZua1lmSmZHR3d0M1Z5ZW5jUWJVeHc1S0szQSJ9.3wp9h4NBcDqs8VhHFLRmQfEN-rFutInOCrRN0mYrkS1_fsqB2IZ6jWt0SjRhY16jPtbvyxnHa_6Cv7_1MVPlQQ',
// value: 'eyJraWQiOiJkMTA2ZTUwNjkzOWYxMWVlYjlkMTAyNDJhYzEyMDAwMiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2In0.eyJpc3MiOiJodHRwczovL2FwaS5zYW5kYm94LnBheXBhbC5jb20iLCJhdWQiOlsiaHR0cHM6Ly9hcGkuYnJhaW50cmVlZ2F0ZXdheS5jb20iLCJjaGVja291dC1wbGF5Z3JvdW5kLm5ldGxpZnkuYXBwIl0sInN1YiI6Ik02VE5BRVNaNUZHTk4iLCJhY3IiOlsiY2xpZW50Il0sInNjb3BlIjpbIkJyYWludHJlZTpWYXVsdCJdLCJvcHRpb25zIjp7fSwiYXoiOiJjY2cxOC5zbGMiLCJleHRlcm5hbF9pZCI6WyJQYXlQYWw6QzNVQ0tRSE1XNDk0OCIsIkJyYWludHJlZTozZGI4aG5rdHJ0bXpzMmd0Il0sImV4cCI6MTczMjYxOTg0MywiaWF0IjoxNzMyNjE4OTQzLCJqdGkiOiJVMkFBSWhhVzBDam5sZkViM1lZWllKOTFRUzktV3RiZWluZnFnOVdFeDZEREhyRW9XcEFVQ0Y1RmstNHp6U05EWjd6R0NTTmdQaktJUWFhWG56WV8zcFdPeHlLRm8tTEFlT3V1S3pCZVNoYjlXOWs5dDBPN09FbFJpdk1zV210ZyJ9.fAUJHc1TzxVzN2JPEF48b7Eh7-tPQtQW55oDVyuTgr2Cn4OLVJaBcjey-Xknju02jpIpqlow2fUYBU6kawiPZQ',
// expiresAt: '2024-11-01T13:34:01.804+00:00'
// });
}
Expand Down

0 comments on commit 7be420a

Please sign in to comment.