connect-react-native-sdk
Version:
React Native SDK for Mastercard Open Banking Connect
526 lines (516 loc) • 17.6 kB
JavaScript
import React from 'react';
import renderer from 'react-test-renderer';
import { Connect } from './index';
import { render, screen } from '@testing-library/react-native';
import { InAppBrowser } from 'react-native-inappbrowser-reborn';
import { checkLink, ConnectReactNativeSdk } from './nativeModule';
import { ConnectEvents, CONNECT_SDK_VERSION, SDK_PLATFORM, PING_TIMEOUT } from './constants';
import { Platform } from 'react-native';
describe('Connect', () => {
const eventHandlerFns = {
onCancel: event => {
console.log('cancel event received', event);
},
onDone: event => {
console.log('done event received', event);
},
onError: event => {
console.log('error event received', event);
},
onLoad: () => {
console.log('loaded event received');
},
onRoute: event => {
console.log('route event received', event);
},
onUser: event => {
console.log('user event received', event);
}
};
test('close', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onCancel = mockFn;
instanceOf.close();
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
code: 100,
reason: 'exit'
});
});
test('render android', () => {
Platform.OS = 'android';
render( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns,
redirectUrl: "https://mastercard.com"
}));
const modal = screen.getByTestId('test-modal');
const webview = screen.getByTestId('test-webview');
expect(webview).toBeDefined();
expect(modal.props.presentationStyle).toBe('fullScreen');
});
test('render ios', () => {
Platform.OS = 'ios';
render( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns,
redirectUrl: "https://mastercard.com"
}));
const modal = screen.getByTestId('test-modal');
const webview = screen.getByTestId('test-webview');
expect(webview).toBeDefined();
expect(modal.props.presentationStyle).toBe('pageSheet');
});
test('postMessage', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
const mockFn = jest.fn();
instanceOf.webViewRef = {
postMessage: mockFn
};
instanceOf.postMessage({
test: true
});
expect(mockFn).toHaveBeenCalledWith(JSON.stringify({
test: true
}));
// handle null webView
instanceOf.webViewRef = null;
jest.spyOn(instanceOf, 'postMessage');
expect(instanceOf.postMessage).not.toThrow();
});
test('open Browser ios', () => {
Platform.OS = 'ios';
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create route event
const event = {
nativeEvent: {
data: ''
}
};
instanceOf.state.browserDisplayed = false;
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.URL,
url: 'https://b2b.mastercard.com'
});
// mock route event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onRoute = mockFn;
instanceOf.handleEvent(event);
expect(checkLink).toHaveBeenCalledTimes(1);
expect(checkLink).toHaveBeenLastCalledWith('https://b2b.mastercard.com');
});
test('open Browser android', () => {
Platform.OS = 'android';
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create route event
const event = {
nativeEvent: {
data: ''
}
};
instanceOf.state.browserDisplayed = false;
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.URL,
url: 'https://b2b.mastercard.com'
});
// mock route event callback
const mockFn = jest.fn();
instanceOf.dismissBrowser = jest.fn();
instanceOf.state.eventHandlers.onRoute = mockFn;
instanceOf.handleEvent(event);
instanceOf.openBrowser('https://b2b.mastercard.com');
expect(instanceOf.dismissBrowser).not.toHaveBeenCalled();
});
test('pingConnect', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// expect postMessage to be called to inform Connect of SDK
const mockFn = jest.fn();
instanceOf.postMessage = mockFn;
instanceOf.pingConnect();
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
type: ConnectEvents.PING,
redirectUrl: '',
sdkVersion: CONNECT_SDK_VERSION,
platform: SDK_PLATFORM
});
// expect to call stopPingingConnect if webViewRef = null
const mockFn2 = jest.fn();
instanceOf.stopPingingConnect = mockFn2;
instanceOf.webViewRef = null;
instanceOf.pingConnect();
expect(mockFn2).toHaveBeenCalledTimes(1);
});
test('dismissBrowser (no-op)', async () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
const postMessageMockFn = jest.fn();
instanceOf.postMessage = postMessageMockFn;
instanceOf.state.browserDisplayed = false;
await instanceOf.dismissBrowser();
expect(InAppBrowser.close).toHaveBeenCalledTimes(0);
expect(postMessageMockFn).toHaveBeenCalledTimes(0);
});
test('close popup', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create close popup event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.CLOSE_POPUP
});
// mock dismiss browser to catch call to dismissBrowser, set state to browser displayed.
const mockFn = jest.fn();
instanceOf.state.browserDisplayed = true;
instanceOf.dismissBrowser = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
});
test('ack', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create ack event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.ACK
});
// mock stopPingingConnect, and eventHandler loaded to catch calls to these functions
const mockStopPingFn = jest.fn();
instanceOf.stopPingingConnect = mockStopPingFn;
const mockLoadedEventFn = jest.fn();
instanceOf.state.eventHandlers.onLoad = mockLoadedEventFn;
instanceOf.handleEvent(event);
expect(mockStopPingFn).toHaveBeenCalledTimes(1);
expect(mockLoadedEventFn).toHaveBeenCalledTimes(1);
});
test('parseEventData', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// invalid JSON event
const event = {
nativeEvent: {
data: '{0}'
}
};
jest.spyOn(instanceOf, 'handleEvent');
expect(instanceOf.handleEvent.bind(instanceOf, event)).not.toThrow();
// valid event
event.nativeEvent.data = {
type: ConnectEvents.CANCEL,
data: {
code: 100,
reason: 'exit'
}
};
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onCancel = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenLastCalledWith({
code: 100,
reason: 'exit'
});
// valid JSON event
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.CANCEL,
data: {
code: 100,
reason: 'exit'
}
});
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenLastCalledWith({
code: 100,
reason: 'exit'
});
});
test('cancel Event', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create cancel event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.CANCEL,
data: {
code: 100,
reason: 'exit'
}
});
// mock cancel event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onCancel = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
code: 100,
reason: 'exit'
});
});
test('done Event', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create done event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.DONE,
data: {
code: 200,
reason: 'complete'
}
});
// mock done event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onDone = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
code: 200,
reason: 'complete'
});
});
test('error Event', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create error event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.ERROR,
data: {
code: 500,
reason: 'error'
}
});
// mock error event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onError = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
code: 500,
reason: 'error'
});
});
test('route Event', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create route event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.ROUTE,
data: {
params: {},
screen: 'search'
}
});
// mock route event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onRoute = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
params: {},
screen: 'search'
});
});
test('startPingingConnect/stopPingingConnect', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// expect to use set interval timer to post ping message to Connect
jest.useFakeTimers();
const mockFn = jest.fn();
instanceOf.pingConnect = mockFn;
instanceOf.startPingingConnect();
jest.advanceTimersByTime(PING_TIMEOUT + 1);
expect(mockFn).toHaveBeenCalledTimes(1);
// Stop pinging Connect
expect(instanceOf.state.pingingConnect).toEqual(true);
expect(instanceOf.state.pingIntervalId).not.toEqual(0);
instanceOf.stopPingingConnect();
expect(instanceOf.state.pingingConnect).toEqual(false);
expect(instanceOf.state.pingIntervalId).toEqual(0);
});
test('user Event', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create user event
const event = {
nativeEvent: {
data: ''
}
};
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.USER,
data: {
action: 'Initialize',
customerId: '5003205004',
experience: null,
partnerId: '2445582695152',
sessionId: 'c004a06ffc4cccd485df796fba74f1a4b647ab4fee3e691b227db2d6b2c5d9e3',
timestamp: '1617009241542',
ttl: '1617016441542',
type: 'default'
}
});
// mock user event callback
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onUser = mockFn;
instanceOf.handleEvent(event);
expect(mockFn).toHaveBeenCalledTimes(1);
expect(mockFn).toHaveBeenLastCalledWith({
action: 'Initialize',
customerId: '5003205004',
experience: null,
partnerId: '2445582695152',
sessionId: 'c004a06ffc4cccd485df796fba74f1a4b647ab4fee3e691b227db2d6b2c5d9e3',
timestamp: '1617009241542',
ttl: '1617016441542',
type: 'default'
});
});
test('open Browser ios - checkLink resolves to true', async () => {
Platform.OS = 'ios';
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// create URL event
const event = {
nativeEvent: {
data: JSON.stringify({
type: ConnectEvents.URL,
url: 'https://b2b.mastercard.com'
})
}
};
instanceOf.state.browserDisplayed = false;
const mockFn = jest.fn();
instanceOf.openBrowser = mockFn;
// Mock checkLink to resolve to true
checkLink.mockResolvedValueOnce(true);
await instanceOf.handleEvent(event);
expect(checkLink).toHaveBeenCalledTimes(1);
expect(checkLink).toHaveBeenLastCalledWith('https://b2b.mastercard.com');
expect(mockFn).not.toHaveBeenCalled();
});
test('close popup when browser not displayed', () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
const event = {
nativeEvent: {
data: JSON.stringify({
type: ConnectEvents.CLOSE_POPUP
})
}
};
const mockFn = jest.fn();
instanceOf.dismissBrowser = mockFn;
instanceOf.state.browserDisplayed = false;
instanceOf.handleEvent(event);
expect(mockFn).not.toHaveBeenCalled();
});
test('should not call checkLink or open browser when URL is null or empty', () => {
Platform.OS = 'ios';
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
const event = {
nativeEvent: {
data: ''
}
};
instanceOf.state.browserDisplayed = false;
event.nativeEvent.data = JSON.stringify({
type: ConnectEvents.URL,
url: null
});
const mockFn = jest.fn();
instanceOf.state.eventHandlers.onRoute = mockFn;
instanceOf.handleEvent(event);
expect(checkLink).toHaveBeenCalledTimes(0);
});
test('openBrowser should return early when URL is null or empty', async () => {
const instanceOf = renderer.create( /*#__PURE__*/React.createElement(Connect, {
connectUrl: "https://b2b.mastercard.com/open-banking-solutions/",
eventHandlers: eventHandlerFns
})).getInstance();
// Spy on InAppBrowser and ConnectReactNativeSdk.open
const inAppBrowserSpy = jest.spyOn(InAppBrowser, 'open');
const sdkOpenSpy = jest.spyOn(ConnectReactNativeSdk, 'open');
// Test with null URL
await instanceOf.openBrowser(null);
expect(inAppBrowserSpy).not.toHaveBeenCalled();
expect(sdkOpenSpy).not.toHaveBeenCalled();
expect(instanceOf.state.browserDisplayed).toBeFalsy();
// Test with empty string URL
await instanceOf.openBrowser('');
expect(inAppBrowserSpy).not.toHaveBeenCalled();
expect(sdkOpenSpy).not.toHaveBeenCalled();
expect(instanceOf.state.browserDisplayed).toBeFalsy();
// Clean up spies
inAppBrowserSpy.mockRestore();
sdkOpenSpy.mockRestore();
});
});
//# sourceMappingURL=index.test.js.map