import { fireEvent, render, waitFor } from '@testing-library/react-native'; import { Platform, View } from 'react-native'; import WebView from 'react-native-webview'; import { WebViewNavigationEvent } from 'react-native-webview/lib/RNCWebViewNativeComponent'; import Logger from '../../core/logging/logger'; import { CSQWebView } from '../../webview/CSQWebView.ios'; import { registerWebView, unregisterWebView } from '../../webview/csqWebViewMethods'; jest.mock('../../core/logging/logger', () => ({ error: jest.fn(), warn: jest.fn(), })); jest.mock('../../webview/csqWebViewMethods', () => ({ registerWebView: jest.fn(), unregisterWebView: jest.fn(), })); jest.mock('react-native-webview', () => ({ __esModule: true, default: 'WebView', })); describe('CSQWebView', () => { beforeEach(() => { Platform.OS = 'ios'; jest.clearAllMocks(); jest.resetAllMocks(); }); describe('Implementation 2: Child WebView', () => { const mockOnLoadEnd = jest.fn(); it('should render a child webview with the correct props', () => { const { getByTestId } = render( ); const childWebView = getByTestId('child-webview'); expect(childWebView).toBeTruthy(); }); it('should log an error if more than one child is passed', () => { render( // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - Testing with multiple children ); expect(Logger.error).toHaveBeenCalledWith( 'CSQWebView component expects exactly 1 child, but received multiple. Ensure that only a single child element is passed' ); }); it('should inject webview on load end', () => { const mockEvent = { nativeEvent: { target: 123 }, } as unknown as WebViewNavigationEvent; const { getByTestId } = render( ); const childWebView = getByTestId('child-webview'); fireEvent(childWebView, 'loadEnd', mockEvent); expect(registerWebView).toHaveBeenCalledWith(123); }); it('should call onLoadEnd prop from children', () => { const { getByTestId } = render( ); const webView = getByTestId('webview'); fireEvent(webView, 'loadEnd', { nativeEvent: { target: 123 } }); expect(mockOnLoadEnd).toHaveBeenCalled(); }); it('should set applicationNameForUserAgent to "CS_WebView" when no original applicationNameForUserAgent is provided', () => { const { getByTestId } = render( ); const webView = getByTestId('webview'); expect(webView.props.applicationNameForUserAgent).toContain('CS_WebView'); }); it('should append "CS_WebView" to existing userAgent', () => { const originalUserAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)'; const { getByTestId } = render( ); const webView = getByTestId('webview'); expect(webView.props.applicationNameForUserAgent).toContain(`${originalUserAgent} CS_WebView`); }); it('should work with empty string applicationNameForUserAgent', () => { const { getByTestId } = render( ); const webView = getByTestId('webview'); expect(webView.props.applicationNameForUserAgent).toContain('CS_WebView'); }); it('should work with undefined applicationNameForUserAgent', () => { const { getByTestId } = render( ); const webView = getByTestId('webview'); expect(webView.props.applicationNameForUserAgent).toContain('CS_WebView'); }); }); it('should call removeWebViewInjection on unmount', async () => { const { getByTestId, unmount } = render( ); const childWebView = getByTestId('child-webview'); fireEvent(childWebView, 'loadEnd', { nativeEvent: { layout: { width: 100, height: 100 }, target: 123 }, }); unmount(); await waitFor(() => expect(unregisterWebView).toHaveBeenCalled()); }); });