Files
self/app/tests/utils/deeplinks.test.ts
Justin Hernandez 9dcbdd3b9e Add thorough test cases for mobile app (#752)
* Add actor mock helper and tests

* format tests

* fix tests

* Revert non-app tests

* update tests

* fix tests

* coderabbit feedback

* revert change

* remove spurious tests
2025-07-06 21:12:28 -07:00

116 lines
3.8 KiB
TypeScript

// SPDX-License-Identifier: BUSL-1.1; Copyright (c) 2025 Social Connect Labs, Inc.; Licensed under BUSL-1.1 (see LICENSE); Apache-2.0 from 2029-06-11
import { Linking } from 'react-native';
jest.mock('../../src/navigation', () => ({
navigationRef: { navigate: jest.fn(), isReady: jest.fn(() => true) },
}));
const mockSelfAppStore = { useSelfAppStore: { getState: jest.fn() } };
jest.mock('../../src/stores/selfAppStore', () => mockSelfAppStore);
const mockUserStore = { default: { getState: jest.fn() } };
jest.mock('../../src/stores/userStore', () => ({
__esModule: true,
...mockUserStore,
}));
let setSelfApp: jest.Mock, startAppListener: jest.Mock, cleanSelfApp: jest.Mock;
let setDeepLinkUserDetails: jest.Mock;
let handleUrl: (url: string) => void;
let setupUniversalLinkListenerInNavigation: () => () => void;
describe('deeplinks', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.resetModules();
({
handleUrl,
setupUniversalLinkListenerInNavigation,
} = require('../../src/utils/deeplinks'));
setSelfApp = jest.fn();
startAppListener = jest.fn();
cleanSelfApp = jest.fn();
setDeepLinkUserDetails = jest.fn();
jest.spyOn(Linking, 'getInitialURL').mockResolvedValue(null as any);
jest
.spyOn(Linking, 'addEventListener')
.mockReturnValue({ remove: jest.fn() } as any);
mockSelfAppStore.useSelfAppStore.getState.mockReturnValue({
setSelfApp,
startAppListener,
cleanSelfApp,
});
mockUserStore.default.getState.mockReturnValue({
setDeepLinkUserDetails,
});
});
it('handles selfApp parameter', () => {
const selfApp = { sessionId: 'abc' };
const url = `scheme://open?selfApp=${encodeURIComponent(JSON.stringify(selfApp))}`;
handleUrl(url);
expect(setSelfApp).toHaveBeenCalledWith(selfApp);
expect(startAppListener).toHaveBeenCalledWith('abc');
const { navigationRef } = require('../../src/navigation');
expect(navigationRef.navigate).toHaveBeenCalledWith('ProveScreen');
});
it('handles sessionId parameter', () => {
const url = 'scheme://open?sessionId=123';
handleUrl(url);
expect(cleanSelfApp).toHaveBeenCalled();
expect(startAppListener).toHaveBeenCalledWith('123');
const { navigationRef } = require('../../src/navigation');
expect(navigationRef.navigate).toHaveBeenCalledWith('ProveScreen');
});
it('handles mock_passport parameter', () => {
const mockData = { name: 'John', surname: 'Doe' };
const url = `scheme://open?mock_passport=${encodeURIComponent(JSON.stringify(mockData))}`;
handleUrl(url);
expect(setDeepLinkUserDetails).toHaveBeenCalledWith({
name: 'John',
surname: 'Doe',
nationality: undefined,
birthDate: undefined,
gender: undefined,
});
const { navigationRef } = require('../../src/navigation');
expect(navigationRef.navigate).toHaveBeenCalledWith('MockDataDeepLink');
});
it('navigates to QRCodeTrouble for invalid data', () => {
const consoleErrorSpy = jest
.spyOn(console, 'error')
.mockImplementation(() => {});
const url = 'scheme://open?selfApp=%7Binvalid';
handleUrl(url);
const { navigationRef } = require('../../src/navigation');
expect(navigationRef.navigate).toHaveBeenCalledWith('QRCodeTrouble');
expect(consoleErrorSpy).toHaveBeenCalledWith(
'Error parsing selfApp:',
expect.any(Error),
);
consoleErrorSpy.mockRestore();
});
it('setup listener registers and cleans up', () => {
const remove = jest.fn();
(Linking.getInitialURL as jest.Mock).mockResolvedValue(undefined);
(Linking.addEventListener as jest.Mock).mockReturnValue({ remove });
const cleanup = setupUniversalLinkListenerInNavigation();
expect(Linking.addEventListener).toHaveBeenCalled();
cleanup();
expect(remove).toHaveBeenCalled();
});
});