/** * @jest-environment jsdom */ import React, { ReactElement } from 'react'; jest.mock('../heroEditorApp'); let onMessageOfLatestRendering: (event: { nativeEvent: { data: string } }) => void | undefined = undefined; jest.mock('react-native-webview', () => { const React = require('react'); class WebView extends React.Component { render() { onMessageOfLatestRendering = this.props.onMessage; return React.createElement('WebView', this.props, this.props.children); } } return { WebView, default: WebView }; }); jest.mock('../../bindings/RNWebView', () => { const React = require('react'); const actual = jest.requireActual('../../bindings/RNWebView'); const WebView = require('react-native-webview'); const postMessageMock = jest.fn(); return { postMessage: (_element: ReactElement, message: string) => { postMessageMock(message); }, postMessageMock, onMessageOfLatestRendering: WebView.onMessageOfLatestRendering, }; }); import { postMessageMock } from '../../bindings/RNWebView'; import { act, render, RenderAPI } from '@testing-library/react-native'; import * as Events from '../../bindings/Events'; import * as RichTextEditor__Event from '../RichTextEditor/Event'; import RichTextEditor from '../RichTextEditor/RichTextEditor'; describe('RichTextEditor', () => { it('should render correctly', () => { const wrapper = render( , ); expect(wrapper.toJSON()).toMatchSnapshot(); expect(wrapper.queryAllByText('this is error')).toHaveLength(1); expect(wrapper.queryByText('this is error')).toHaveStyle({ backgroundColor: 'red' }); expect(wrapper.queryAllByTestId('webview')).toHaveLength(1); expect(wrapper.queryByTestId('webview')).toHaveStyle({ backgroundColor: 'yellow' }); }); describe('onMessage', () => { const onChangeMock = jest.fn(); const onCursorChangeMock = jest.fn(); let wrapper: RenderAPI | undefined; beforeEach(() => { wrapper = render( , ); }); describe('recevied event editor-focus', () => { it('should emit correct data', () => { const eventsEmmited = []; Events.on(RichTextEditor__Event.emitter, 'rich-text-editor/editor-focus', () => { eventsEmmited.push('called'); }); onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/editor-focus", "data" : {}}' }, }); expect(eventsEmmited).toMatchObject(['called']); }); }); describe('recevied event editor-blur', () => { it('should emit correct data', () => { const eventsEmmited = []; Events.on(RichTextEditor__Event.emitter, 'rich-text-editor/editor-blur', () => { eventsEmmited.push('called'); }); onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/editor-blur", "data" : {}}' }, }); expect(eventsEmmited).toMatchObject(['called']); }); }); describe('recevied event mention-search', () => { it('should emit correct data', () => { const eventsEmmited = []; Events.on(RichTextEditor__Event.emitter, 'rich-text-editor/mention-search', () => { eventsEmmited.push('called'); }); onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/mention-search", "data" : {}}' }, }); expect(eventsEmmited).toMatchObject(['called']); }); }); describe('recevied event editor-change', () => { beforeEach(() => { onChangeMock.mockReset(); }); it('should call onChange', () => { onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/editor-change", "data" : { "value": "text"}}' }, }); expect(onChangeMock).lastCalledWith('text'); }); }); describe('recevied event cursor-change', () => { beforeEach(() => { onCursorChangeMock.mockReset(); }); it('should call onCursorChange', () => { onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/cursor-change", "data" : { "position": 32}}' }, }); expect(onCursorChangeMock).lastCalledWith({ position: 32 }); }); }); /** * @jest-environment node */ describe('recevied event editor-layout', () => { it('should update height', () => { act(() => { onMessageOfLatestRendering({ nativeEvent: { data: '{"type": "@hero-editor/webview/editor-layout", "data" : { "width": 320, "height": 480}}', }, }); wrapper.update( , ); }); expect(wrapper.toJSON()).toMatchSnapshot(); expect(wrapper.getByTestId('webview')).toHaveStyle({ height: 480 }); }); }); }); describe('postMessageToWebview', () => { const onChangeMock = jest.fn(); const onCursorChangeMock = jest.fn(); let wrapper: RenderAPI | undefined; beforeEach(() => { postMessageMock.mockReset(); wrapper = render( , ); }); it.each` emittedEventName | data | expectedMessageType | expectedMessageData ${'rich-text-editor/bold'} | ${null} | ${'@hero-editor/webview/bold'} | ${null} ${'rich-text-editor/italic'} | ${null} | ${'@hero-editor/webview/italic'} | ${null} ${'rich-text-editor/underline'} | ${null} | ${'@hero-editor/webview/underline'} | ${null} ${'rich-text-editor/bulleted-list'} | ${null} | ${'@hero-editor/webview/bulleted-list'} | ${null} ${'rich-text-editor/numbered-list'} | ${null} | ${'@hero-editor/webview/numbered-list'} | ${null} ${'rich-text-editor/heading-one'} | ${null} | ${'@hero-editor/webview/heading-one'} | ${null} ${'rich-text-editor/heading-two'} | ${null} | ${'@hero-editor/webview/heading-two'} | ${null} ${'rich-text-editor/mention-apply'} | ${'Minh Dinh'} | ${'@hero-editor/webview/mention-apply'} | ${'Minh Dinh'} `( 'Events emit $emittedEventName should postMessage $expectedMessageType', ({ emittedEventName, data, expectedMessageType, expectedMessageData }) => { RichTextEditor__Event.emitter.emit(emittedEventName, data); expect(postMessageMock).toHaveBeenCalledWith({ data: expectedMessageData, type: expectedMessageType }); }, ); }); });