From e55b172bc196a7ac2d73222673b4b394fed25d16 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Mon, 19 Feb 2024 11:08:17 -0300 Subject: [PATCH] tests: message composer unit tests (#5556) * jest.fn issue * Working on tests * Add quotes test * Audio * Mock search * Fix some act errors from jest --------- Co-authored-by: Gleidson Daniel Silva --- .../MessageComposer/MessageComposer.test.tsx | 514 +- .../MessageComposer/MessageComposer.tsx | 1 - .../MessageComposer.test.tsx.snap | 10802 ++++++++++++++++ jest.setup.js | 53 +- package.json | 5 +- yarn.lock | 48 +- 6 files changed, 11108 insertions(+), 315 deletions(-) create mode 100644 app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap diff --git a/app/containers/MessageComposer/MessageComposer.test.tsx b/app/containers/MessageComposer/MessageComposer.test.tsx index 7257fe012..f1326120c 100644 --- a/app/containers/MessageComposer/MessageComposer.test.tsx +++ b/app/containers/MessageComposer/MessageComposer.test.tsx @@ -1,8 +1,6 @@ import React from 'react'; -import { act, fireEvent, render, screen } from '@testing-library/react-native'; +import { act, fireEvent, render, screen, userEvent } from '@testing-library/react-native'; import { Provider } from 'react-redux'; -import { NavigationContainer } from '@react-navigation/native'; -import { createStackNavigator } from '@react-navigation/stack'; import { MessageComposerContainer } from './MessageComposerContainer'; import { setPermissions } from '../../actions/permissions'; @@ -27,7 +25,7 @@ const initialStoreState = () => { initialStoreState(); const initialContext = { - rid: '', + rid: 'rid', tmid: undefined, sharing: false, action: null, @@ -38,33 +36,15 @@ const initialContext = { onRemoveQuoteMessage: jest.fn() }; -const Stack = createStackNavigator(); - -// const Navigation = ({ children }: { children: any }) => ( -// -// -// -// -// -// ); - -// const Content = () => ( -// -// ) - const Render = ({ context }: { context?: Partial }) => ( - - - - - + ); -describe.skip('MessageComposer', () => { +describe('MessageComposer', () => { test('renders correctly', () => { render(); expect(screen.getByTestId('message-composer-input')).toBeOnTheScreen(); @@ -76,14 +56,14 @@ describe.skip('MessageComposer', () => { test('renders correctly with audio recorder disabled', () => { mockedStore.dispatch(addSettings({ Message_AudioRecorderEnabled: false })); render(); - expect(screen.queryByTestId('message-composer-send-audio')).toBeNull(); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); expect(screen.toJSON()).toMatchSnapshot(); }); test('renders correctly without audio upload permissions', () => { mockedStore.dispatch(setPermissions({})); render(); - expect(screen.queryByTestId('message-composer-send-audio')).toBeNull(); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); expect(screen.toJSON()).toMatchSnapshot(); }); @@ -91,7 +71,7 @@ describe.skip('MessageComposer', () => { mockedStore.dispatch(addSettings({ Message_AudioRecorderEnabled: false })); mockedStore.dispatch(setPermissions({})); render(); - expect(screen.queryByTestId('message-composer-send-audio')).toBeNull(); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); expect(screen.toJSON()).toMatchSnapshot(); }); @@ -100,9 +80,9 @@ describe.skip('MessageComposer', () => { render(); expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen(); expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen(); - expect(screen.queryByTestId('message-composer-open-emoji')).toBeNull(); - expect(screen.queryByTestId('message-composer-open-markdown')).toBeNull(); - expect(screen.queryByTestId('message-composer-mention')).toBeNull(); + expect(screen.queryByTestId('message-composer-open-emoji')).not.toBeOnTheScreen(); + expect(screen.queryByTestId('message-composer-open-markdown')).not.toBeOnTheScreen(); + expect(screen.queryByTestId('message-composer-mention')).not.toBeOnTheScreen(); await act(async () => { await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); @@ -116,238 +96,247 @@ describe.skip('MessageComposer', () => { }); test('send message', async () => { + const user = userEvent.setup(); const onSendMessage = jest.fn(); render(); expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen(); + + await user.type(screen.getByTestId('message-composer-input'), 'test'); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-send')).toBeOnTheScreen(); + await act(async () => { - await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - expect(screen.queryByTestId('message-composer-send-audio')).toBeNull(); - expect(screen.getByTestId('message-composer-send')).toBeOnTheScreen(); await fireEvent.press(screen.getByTestId('message-composer-send')); }); + expect(onSendMessage).toHaveBeenCalledTimes(1); expect(onSendMessage).toHaveBeenCalledWith('test', undefined); expect(screen.toJSON()).toMatchSnapshot(); }); - test('tap actions from toolbar', async () => { - render(); + describe('Toolbar', () => { + test('tap actions', async () => { + render(); - await act(async () => { - await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - await fireEvent.press(screen.getByTestId('message-composer-actions')); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-actions')); + }); + expect(screen.toJSON()).toMatchSnapshot(); }); - expect(screen.toJSON()).toMatchSnapshot(); - }); - test('tap emoji', async () => { - render(); + test('tap emoji', async () => { + render(); - await act(async () => { - await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - await fireEvent.press(screen.getByTestId('message-composer-open-emoji')); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-emoji')); + }); + expect(screen.getByTestId('message-composer-close-emoji')).toBeOnTheScreen(); + expect(screen.toJSON()).toMatchSnapshot(); }); - expect(screen.getByTestId('message-composer-close-emoji')).toBeOnTheScreen(); - expect(screen.toJSON()).toMatchSnapshot(); - }); - // describe('Markdown', () => { - // test('tap markdown', async () => { - // render(); + describe('Markdown', () => { + test('tap markdown', async () => { + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // }); - // expect(screen.getByTestId('message-composer-close-markdown')).toBeOnTheScreen(); - // expect(screen.getByTestId('message-composer-bold')).toBeOnTheScreen(); - // expect(screen.getByTestId('message-composer-italic')).toBeOnTheScreen(); - // expect(screen.getByTestId('message-composer-strike')).toBeOnTheScreen(); - // expect(screen.getByTestId('message-composer-code')).toBeOnTheScreen(); - // expect(screen.getByTestId('message-composer-code-block')).toBeOnTheScreen(); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + }); + expect(screen.getByTestId('message-composer-close-markdown')).toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-bold')).toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-italic')).toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-strike')).toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-code')).toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-code-block')).toBeOnTheScreen(); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('tap bold', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('tap bold', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // // await waitFor(() => fireEvent.press(screen.getByTestId('message-composer-open-markdown')), { timeout: 1000 }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-bold')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('**', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-bold')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('**', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('type test and tap bold', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('type test and tap bold', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { - // nativeEvent: { selection: { start: 0, end: 4 } } - // }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-bold')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('*test*', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { + nativeEvent: { selection: { start: 0, end: 4 } } + }); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-bold')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('*test*', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('tap italic', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('tap italic', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-italic')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('__', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-italic')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('__', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('type test and tap italic', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('type test and tap italic', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { - // nativeEvent: { selection: { start: 0, end: 4 } } - // }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-italic')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('_test_', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { + nativeEvent: { selection: { start: 0, end: 4 } } + }); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-italic')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('_test_', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('tap strike', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('tap strike', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-strike')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('~~', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-strike')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('~~', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('type test and tap strike', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('type test and tap strike', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { - // nativeEvent: { selection: { start: 0, end: 4 } } - // }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-strike')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('~test~', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { + nativeEvent: { selection: { start: 0, end: 4 } } + }); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-strike')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('~test~', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('tap code', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('tap code', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-code')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('``', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-code')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('``', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('type test and tap code', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('type test and tap code', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { - // nativeEvent: { selection: { start: 0, end: 4 } } - // }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-code')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('`test`', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { + nativeEvent: { selection: { start: 0, end: 4 } } + }); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-code')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('`test`', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('tap code-block', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('tap code-block', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-code-block')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('``````', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-code-block')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('``````', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); - // test('type test and tap code-block', async () => { - // const onSendMessage = jest.fn(); - // render(); + test('type test and tap code-block', async () => { + const onSendMessage = jest.fn(); + render(); - // await act(async () => { - // await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { - // nativeEvent: { selection: { start: 0, end: 4 } } - // }); - // await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); - // await fireEvent.press(screen.getByTestId('message-composer-code-block')); - // await fireEvent.press(screen.getByTestId('message-composer-send')); - // }); - // expect(onSendMessage).toHaveBeenCalledTimes(1); - // expect(onSendMessage).toHaveBeenCalledWith('```test```', undefined); - // expect(screen.toJSON()).toMatchSnapshot(); - // }); - // }); - - test('tap mention', async () => { - render(); - - await act(async () => { - await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); - // await fireEvent.press(screen.getByTestId('message-composer-mention')); + await act(async () => { + await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test'); + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent(screen.getByTestId('message-composer-input'), 'selectionChange', { + nativeEvent: { selection: { start: 0, end: 4 } } + }); + await fireEvent.press(screen.getByTestId('message-composer-open-markdown')); + await fireEvent.press(screen.getByTestId('message-composer-code-block')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('```test```', undefined); + expect(screen.toJSON()).toMatchSnapshot(); + }); + }); + + test('tap mention', async () => { + const onSendMessage = jest.fn(); + render(); + + await act(async () => { + await fireEvent(screen.getByTestId('message-composer-input'), 'focus'); + await fireEvent.press(screen.getByTestId('message-composer-mention')); + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); + expect(onSendMessage).toHaveBeenCalledTimes(1); + expect(onSendMessage).toHaveBeenCalledWith('@', undefined); + expect(screen.toJSON()).toMatchSnapshot(); }); - expect(screen.toJSON()).toMatchSnapshot(); }); describe('edit message', () => { @@ -362,19 +351,26 @@ describe.skip('MessageComposer', () => { await screen.findByTestId('message-composer'); expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 }); expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen(); - expect(screen.queryByTestId('message-composer-send-audio')).toBeNull(); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); expect(screen.getByTestId('message-composer-cancel-edit')).toBeOnTheScreen(); }); test('cancel', async () => { await screen.findByTestId('message-composer'); expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 }); - fireEvent.press(screen.getByTestId('message-composer-cancel-edit')); + await act(async () => { + await fireEvent.press(screen.getByTestId('message-composer-cancel-edit')); + }); expect(editCancel).toHaveBeenCalledTimes(1); + expect(screen.getByTestId('message-composer-actions')).toBeOnTheScreen(); + expect(screen.queryByTestId('message-composer-send-audio')).not.toBeOnTheScreen(); + expect(screen.getByTestId('message-composer-cancel-edit')).toBeOnTheScreen(); }); test('send', async () => { await screen.findByTestId('message-composer'); expect(screen.getByTestId('message-composer')).toHaveStyle({ backgroundColor: colors.light.statusBackgroundWarning2 }); - fireEvent.press(screen.getByTestId('message-composer-send')); + await act(async () => { + await fireEvent.press(screen.getByTestId('message-composer-send')); + }); expect(editRequest).toHaveBeenCalledTimes(1); expect(editRequest).toHaveBeenCalledWith({ id, msg: `Message ${id}`, rid: 'rid' }); }); @@ -404,34 +400,46 @@ describe.skip('MessageComposer', () => { })); describe('Quote', () => { - test('Adding/removing quotes', () => { - const onRemoveQuoteMessage = jest.fn(); - - // Render without quotes - const { rerender } = render(); - expect(screen.queryByTestId('composer-quote-abc')).toBeNull(); - expect(screen.queryByTestId('composer-quote-def')).toBeNull(); - expect(screen.toJSON()).toMatchSnapshot(); - - // Add a quote - rerender(); - expect(screen.getByTestId('composer-quote-abc')).toBeOnTheScreen(); - expect(screen.queryByTestId('composer-quote-def')).toBeNull(); - expect(screen.toJSON()).toMatchSnapshot(); - - // Add another quote - rerender(); - expect(screen.getByTestId('composer-quote-abc')).toBeOnTheScreen(); - expect(screen.getByTestId('composer-quote-def')).toBeOnTheScreen(); - expect(screen.toJSON()).toMatchSnapshot(); - - // Remove a quote - fireEvent.press(screen.getByTestId('composer-quote-remove-def')); - expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1); - expect(onRemoveQuoteMessage).toHaveBeenCalledWith('def'); + test('Add quote `abc`', async () => { + render(); + await act(async () => { + await screen.findByTestId('composer-quote-abc'); + expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen(); + expect(screen.toJSON()).toMatchSnapshot(); + }); }); - // TODO: need to create proper mocks for getMessageById and getPermalinkMessage - // test('Send message with a quote', async () => {}); + test('Add quote `def`', async () => { + render(); + await act(async () => { + await screen.findByTestId('composer-quote-abc'); + expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen(); + expect(screen.queryByTestId('composer-quote-def')).toBeOnTheScreen(); + expect(screen.toJSON()).toMatchSnapshot(); + }); + }); + + test('Remove a quote', async () => { + const onRemoveQuoteMessage = jest.fn(); + render(); + await act(async () => { + await screen.findByTestId('composer-quote-def'); + await fireEvent.press(screen.getByTestId('composer-quote-remove-def')); + }); + expect(onRemoveQuoteMessage).toHaveBeenCalledTimes(1); + expect(onRemoveQuoteMessage).toHaveBeenCalledWith('def'); + expect(screen.toJSON()).toMatchSnapshot(); + }); + }); + + describe('Audio', () => { + test('tap record', async () => { + render(); + expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen(); + await act(async () => { + await fireEvent.press(screen.getByTestId('message-composer-send-audio')); + }); + expect(screen.toJSON()).toMatchSnapshot(); + }); }); }); diff --git a/app/containers/MessageComposer/MessageComposer.tsx b/app/containers/MessageComposer/MessageComposer.tsx index 00337588b..5e8c9429e 100644 --- a/app/containers/MessageComposer/MessageComposer.tsx +++ b/app/containers/MessageComposer/MessageComposer.tsx @@ -200,7 +200,6 @@ export const MessageComposer = ({ const backgroundColor = action === 'edit' ? colors.statusBackgroundWarning2 : colors.surfaceLight; const renderContent = () => { - console.count('[MessageComposer] renderContent'); if (recordingAudio) { return ; } diff --git a/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap b/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap new file mode 100644 index 000000000..6633a23c7 --- /dev/null +++ b/app/containers/MessageComposer/__snapshots__/MessageComposer.test.tsx.snap @@ -0,0 +1,10802 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`MessageComposer Audio tap record 1`] = ` + + + + +  + + + 00:00 + + + + + + +  + + + + + + Recording audio message + + + + + +  + + + + + + +`; + +exports[`MessageComposer Quote Add quote \`abc\` 1`] = ` + + + + + + + +  + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + +  + + + + + + Message abc + + + + + + + +`; + +exports[`MessageComposer Quote Add quote \`def\` 1`] = ` + + + + + + + +  + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + +  + + + + + + Message abc + + + + + + + + + + + + + + + + + +  + + + + + + Message def + + + + + + + +`; + +exports[`MessageComposer Quote Remove a quote 1`] = ` + + + + + + + +  + + + + + + + + + +  + + + + + + + + + + + + + + + + + + + + + +  + + + + + + Message abc + + + + + + + + + + + + + + + + + +  + + + + + + Message def + + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap bold 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap code 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap code-block 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap italic 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap markdown 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown tap strike 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown type test and tap bold 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown type test and tap code 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown type test and tap code-block 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown type test and tap italic 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar Markdown type test and tap strike 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar tap actions 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar tap emoji 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer Toolbar tap mention 1`] = ` +Array [ + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + , + + + + + + + + + + + + @all + + + + + + Notify all in this room + + + + + + + + + + + + + + + @here + + + + + + Notify active users in this room + + + + + + + + + , +] +`; + +exports[`MessageComposer renders correctly 1`] = ` + + + + + + + +  + + + + + + + + + +  + + + + + + + +`; + +exports[`MessageComposer renders correctly with audio recorder disabled 1`] = ` + + + + + + + +  + + + + + + + + + +`; + +exports[`MessageComposer renders correctly with audio recorder disabled and without audio upload permissions 1`] = ` + + + + + + + +  + + + + + + + + + +`; + +exports[`MessageComposer renders correctly without audio upload permissions 1`] = ` + + + + + + + +  + + + + + + + + + +`; + +exports[`MessageComposer renders toolbar when focused 1`] = ` + + + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + + +  + + + + + + +`; + +exports[`MessageComposer send message 1`] = ` + + + + + + + +  + + + + + + + + + +  + + + + + + + +`; diff --git a/jest.setup.js b/jest.setup.js index ebf0b89ac..2ea537aa7 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -1,6 +1,5 @@ import React from 'react'; import '@testing-library/react-native/extend-expect'; -import '@testing-library/jest-native/legacy-extend-expect'; import mockClipboard from '@react-native-clipboard/clipboard/jest/clipboard-mock.js'; import mockAsyncStorage from '@react-native-async-storage/async-storage/jest/async-storage-mock'; @@ -17,6 +16,10 @@ jest.mock('react-native-safe-area-context', () => { }; }); +jest.mock('./node_modules/react-native/Libraries/Interaction/InteractionManager', () => ({ + runAfterInteractions: callback => callback() +})); + // @ts-ignore global.__reanimatedWorkletInit = () => {}; jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock')); @@ -41,6 +44,24 @@ jest.mock('react-native-file-viewer', () => ({ jest.mock('expo-haptics', () => jest.fn(() => null)); +jest.mock('expo-av', () => ({ + ...jest.requireActual('expo-av'), + Audio: { + ...jest.requireActual('expo-av').Audio, + getPermissionsAsync: jest.fn(() => ({ status: 'granted', granted: true, canAskAgain: true })), + Recording: jest.fn(() => ({ + prepareToRecordAsync: jest.fn(), + startAsync: jest.fn(), + stopAndUnloadAsync: jest.fn(), + setOnRecordingStatusUpdate: jest.fn() + })) + } +})); + +jest.mock('./app/lib/methods/search', () => ({ + search: () => [] +})); + jest.mock('./app/lib/database', () => jest.fn(() => null)); jest.mock('./app/containers/MessageComposer/components/EmojiKeyboard', () => jest.fn(() => null)); @@ -60,20 +81,24 @@ jest.mock('./app/lib/database/services/Message', () => ({ }) })); -const mockedNavigate = jest.fn(); - -jest.mock('@react-navigation/native', () => ({ - ...jest.requireActual('@react-navigation/native'), - useNavigation: () => ({ +jest.mock('@react-navigation/native', () => { + const actualNav = jest.requireActual('@react-navigation/native'); + const { useEffect } = require('react'); + return { + ...actualNav, + useFocusEffect: useEffect, + isFocused: () => true, + useIsFocused: () => true, + useRoute: () => jest.fn(), + useNavigation: () => ({ + navigate: jest.fn(), + addListener: () => jest.fn() + }), + createNavigationContainerRef: jest.fn(), navigate: jest.fn(), - addListener: jest.fn().mockImplementation((event, callback) => { - callback(); - return { - remove: jest.fn() - }; - }) - }) -})); + addListener: jest.fn(() => jest.fn()) + }; +}); jest.mock('react-native-notifications', () => ({ Notifications: { diff --git a/package.json b/package.json index d730f34e4..cb8fe04f0 100644 --- a/package.json +++ b/package.json @@ -165,9 +165,8 @@ "@storybook/addon-storyshots": "6.3", "@storybook/react": "6.3", "@storybook/react-native": "^6.0.1-beta.7", - "@testing-library/jest-native": "^5.4.2", "@testing-library/react-hooks": "^8.0.1", - "@testing-library/react-native": "^12.4.1", + "@testing-library/react-native": "^12.4.3", "@types/bytebuffer": "^5.0.44", "@types/ejson": "^2.1.3", "@types/i18n-js": "^3.8.3", @@ -224,7 +223,7 @@ "node_modules" ], "transformIgnorePatterns": [ - "node_modules/(?!(jest-)?@?react-native|@react-native-community|@react-navigation|expo)" + "node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg)" ], "preset": "./jest.preset.js", "coverageDirectory": "./coverage/", diff --git a/yarn.lock b/yarn.lock index 9b8c094c2..d1eb84226 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6297,17 +6297,6 @@ resolve-from "^5.0.0" store2 "^2.12.0" -"@testing-library/jest-native@^5.4.2": - version "5.4.3" - resolved "https://registry.yarnpkg.com/@testing-library/jest-native/-/jest-native-5.4.3.tgz#9334c68eaf45db9eb20d0876728cc5d7fc2c3ea2" - integrity sha512-/sSDGaOuE+PJ1Z9Kp4u7PQScSVVXGud59I/qsBFFJvIbcn4P6yYw6cBnBmbPF+X9aRIsTJRDl6gzw5ZkJNm66w== - dependencies: - chalk "^4.1.2" - jest-diff "^29.0.1" - jest-matcher-utils "^29.0.1" - pretty-format "^29.0.3" - redent "^3.0.0" - "@testing-library/react-hooks@^8.0.1": version "8.0.1" resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12" @@ -6316,10 +6305,10 @@ "@babel/runtime" "^7.12.5" react-error-boundary "^3.1.0" -"@testing-library/react-native@^12.4.1": - version "12.4.1" - resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-12.4.1.tgz#f15d0b6727e5e1af8bc35049aa95ce24b4420fe7" - integrity sha512-HDHwGTJwBB9//Flv0HhApghFsUYZvaKTemXOs9PCMk6P8mUl4IJby8zAud8rq7bT/ZMnehgIak8QK+mJCH6+5Q== +"@testing-library/react-native@^12.4.3": + version "12.4.3" + resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-12.4.3.tgz#57cd6a88b289f19144558b5e97336b57101af3ec" + integrity sha512-WLE7VbbR5jZJQl3vfNK7Wt+IHnzhOxyu95Mr56EHmzH3XhC8DkrPVAnUq9asq/QWj4aGnymbinFx6zZys/WZmA== dependencies: jest-matcher-utils "^29.7.0" pretty-format "^29.7.0" @@ -13765,16 +13754,6 @@ jest-diff@^28.1.3: jest-get-type "^28.0.2" pretty-format "^28.1.3" -jest-diff@^29.0.1, jest-diff@^29.6.4: - version "29.6.4" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.6.4.tgz#85aaa6c92a79ae8cd9a54ebae8d5b6d9a513314a" - integrity sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.6.3" - jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -13962,16 +13941,6 @@ jest-matcher-utils@^28.1.3: jest-get-type "^28.0.2" pretty-format "^28.1.3" -jest-matcher-utils@^29.0.1: - version "29.6.4" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.6.4.tgz#327db7ababea49455df3b23e5d6109fe0c709d24" - integrity sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ== - dependencies: - chalk "^4.0.0" - jest-diff "^29.6.4" - jest-get-type "^29.6.3" - pretty-format "^29.6.3" - jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -17188,15 +17157,6 @@ pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.0.3, pretty-format@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.6.3.tgz#d432bb4f1ca6f9463410c3fb25a0ba88e594ace7" - integrity sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812"