Merge branch 'develop' into TC-782-Mobile-Troubleshoot-notifications

This commit is contained in:
GleidsonDaniel 2024-02-20 11:50:30 -03:00
commit 93372d4dd3
44 changed files with 11458 additions and 442 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -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 }) => (
// <NavigationContainer>
// <Stack.Navigator>
// <Stack.Screen name='A' component={children} />
// </Stack.Navigator>
// </NavigationContainer>
// );
// const Content = () => (
// <MessageComposerContainer />
// )
const Render = ({ context }: { context?: Partial<IRoomContext> }) => (
<Provider store={mockedStore}>
<RoomContext.Provider value={{ ...initialContext, ...context }}>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='MessageComposer' component={MessageComposerContainer} />
</Stack.Navigator>
</NavigationContainer>
<MessageComposerContainer />
</RoomContext.Provider>
</Provider>
);
describe.skip('MessageComposer', () => {
describe('MessageComposer', () => {
test('renders correctly', () => {
render(<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(<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(<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(<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(<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,21 +96,26 @@ describe.skip('MessageComposer', () => {
});
test('send message', async () => {
const user = userEvent.setup();
const onSendMessage = jest.fn();
render(<Render context={{ onSendMessage }} />);
expect(screen.getByTestId('message-composer-send-audio')).toBeOnTheScreen();
await act(async () => {
await fireEvent.changeText(screen.getByTestId('message-composer-input'), 'test');
expect(screen.queryByTestId('message-composer-send-audio')).toBeNull();
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.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 () => {
describe('Toolbar', () => {
test('tap actions', async () => {
render(<Render />);
await act(async () => {
@ -151,205 +136,209 @@ describe.skip('MessageComposer', () => {
expect(screen.toJSON()).toMatchSnapshot();
});
// describe('Markdown', () => {
// test('tap markdown', async () => {
// render(<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();
// });
// test('tap bold', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
// 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();
// });
// test('type test and tap bold', async () => {
// const onSendMessage = jest.fn();
// render(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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(<Render context={{ onSendMessage }} />);
// 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 () => {
describe('Markdown', () => {
test('tap markdown', async () => {
render(<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-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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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(<Render context={{ onSendMessage }} />);
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();
});
});
describe('edit message', () => {
const onSendMessage = jest.fn();
const editCancel = jest.fn();
@ -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', () => {
test('Add quote `abc`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc'] }} />);
await act(async () => {
await screen.findByTestId('composer-quote-abc');
expect(screen.queryByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.toJSON()).toMatchSnapshot();
});
});
test('Add quote `def`', async () => {
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'] }} />);
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 without quotes
const { rerender } = render(<Render context={{ selectedMessages: [], onRemoveQuoteMessage }} />);
expect(screen.queryByTestId('composer-quote-abc')).toBeNull();
expect(screen.queryByTestId('composer-quote-def')).toBeNull();
expect(screen.toJSON()).toMatchSnapshot();
// Add a quote
rerender(<Render context={{ action: 'quote', selectedMessages: ['abc'], onRemoveQuoteMessage }} />);
expect(screen.getByTestId('composer-quote-abc')).toBeOnTheScreen();
expect(screen.queryByTestId('composer-quote-def')).toBeNull();
expect(screen.toJSON()).toMatchSnapshot();
// Add another quote
rerender(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
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'));
render(<Render context={{ action: 'quote', selectedMessages: ['abc', 'def'], onRemoveQuoteMessage }} />);
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();
});
});
// TODO: need to create proper mocks for getMessageById and getPermalinkMessage
// test('Send message with a quote', async () => {});
describe('Audio', () => {
test('tap record', async () => {
render(<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();
});
});
});

View File

@ -66,8 +66,13 @@ export const MessageComposer = ({
const showEmojiKeyboard = useShowEmojiKeyboard();
const showEmojiSearchbar = useShowEmojiSearchbar();
const alsoSendThreadToChannel = useAlsoSendThreadToChannel();
const { openSearchEmojiKeyboard, closeEmojiKeyboard, closeSearchEmojiKeyboard, setTrackingViewHeight } =
useMessageComposerApi();
const {
openSearchEmojiKeyboard,
closeEmojiKeyboard,
closeSearchEmojiKeyboard,
setTrackingViewHeight,
setAlsoSendThreadToChannel
} = useMessageComposerApi();
const recordingAudio = useRecordingAudio();
useKeyboardListener(trackingViewRef);
@ -101,6 +106,10 @@ export const MessageComposer = ({
const handleSendMessage = async () => {
if (!rid) return;
if (alsoSendThreadToChannel) {
setAlsoSendThreadToChannel(false);
}
if (sharing) {
onSendMessage?.();
return;
@ -200,7 +209,6 @@ export const MessageComposer = ({
const backgroundColor = action === 'edit' ? colors.statusBackgroundWarning2 : colors.surfaceLight;
const renderContent = () => {
console.count('[MessageComposer] renderContent');
if (recordingAudio) {
return <RecordAudio />;
}

File diff suppressed because it is too large Load Diff

View File

@ -340,7 +340,8 @@ export const ComposerInput = memo(
defaultValue=''
multiline
keyboardAppearance={theme === 'light' ? 'light' : 'dark'}
testID={`message-composer-input${tmid ? '-thread' : ''}`}
// eslint-disable-next-line no-nested-ternary
testID={`message-composer-input${tmid ? '-thread' : sharing ? '-share' : ''}`}
/>
);
})

View File

@ -51,8 +51,7 @@ export const SendThreadToChannel = (): React.ReactElement | null => {
* */
if (alsoSendThreadToChannelUserPref === 'default') {
const db = database.active;
const observable = db.get('threads').query(Q.where('tmid', tmid)).observe();
const observable = db.get('threads').query(Q.where('id', tmid)).observe();
subscription.current = observable.subscribe(result => {
setAlsoSendThreadToChannel(!result.length);
});

View File

@ -1,6 +1,5 @@
import { Alert } from 'react-native';
import DocumentPicker from 'react-native-document-picker';
import ImagePicker, { ImageOrVideo } from 'react-native-image-crop-picker';
import { IMAGE_PICKER_CONFIG, LIBRARY_PICKER_CONFIG, VIDEO_PICKER_CONFIG } from '../constants';
import { forceJpgExtension } from '../helpers';
@ -12,6 +11,7 @@ import { getThreadById } from '../../../lib/database/services/Thread';
import Navigation from '../../../lib/navigation/appNavigation';
import { useAppSelector } from '../../../lib/hooks';
import { useRoomContext } from '../../../views/RoomView/context';
import ImagePicker, { ImageOrVideo } from '../../../lib/methods/helpers/ImagePicker/ImagePicker';
export const useChooseMedia = ({
rid,

View File

@ -44,7 +44,7 @@ const methods: IMethods = {
keyboardType: 'numeric'
},
email: {
text: 'Verify_your_email_for_the_code_we_sent',
text: 'Enter_the_code',
keyboardType: 'numeric'
},
password: {
@ -129,7 +129,7 @@ const TwoFactor = React.memo(({ isMasterDetail }: { isMasterDetail: boolean }) =
/>
{isEmail ? (
<Text style={[styles.sendEmail, { color }]} onPress={sendEmail}>
{I18n.t('Send_me_the_code_again')}
{I18n.t('Resend_email')}
</Text>
) : null}
<View style={styles.buttonContainer}>
@ -140,7 +140,7 @@ const TwoFactor = React.memo(({ isMasterDetail }: { isMasterDetail: boolean }) =
style={styles.button}
onPress={onCancel}
/>
<Button title={I18n.t('Send')} type='primary' style={styles.button} onPress={onSubmit} testID='two-factor-send' />
<Button title={I18n.t('Verify')} type='primary' style={styles.button} onPress={onSubmit} testID='two-factor-send' />
</View>
</View>
</View>

View File

@ -1,9 +1,11 @@
import React from 'react';
import { KaTeX as KaTeXProps } from '@rocket.chat/message-parser';
import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import Katex from 'react-native-katex';
// eslint-disable-next-line import/no-unresolved
import MathView, { MathText } from 'react-native-math-view';
import Katex from 'react-native-katex';
import { isAndroid } from '../../../lib/methods/helpers';
import { useTheme } from '../../../theme';
import { DEFAULT_MESSAGE_HEIGHT } from '../../message/utils';
@ -13,11 +15,14 @@ interface IKaTeXProps {
export const KaTeX = ({ value }: IKaTeXProps): React.ReactElement | null => {
const { colors } = useTheme();
const fixAndroidWebviewCrashStyle: StyleProp<ViewStyle> = isAndroid ? { opacity: 0.99, overflow: 'hidden' } : {};
return (
<MathView
math={value}
style={{ color: colors.bodyText }}
renderError={() => <Katex expression={value} style={{ flex: 1, height: DEFAULT_MESSAGE_HEIGHT }} />}
renderError={() => (
<Katex expression={value} style={[{ flex: 1, height: DEFAULT_MESSAGE_HEIGHT }, fixAndroidWebviewCrashStyle]} />
)}
/>
);
};

View File

@ -98,7 +98,7 @@ const User = React.memo(
return (
<View style={styles.container}>
<TouchableOpacity style={styles.titleContainer} onPress={onUserPress}>
<TouchableOpacity testID={`username-header-${username}`} style={styles.titleContainer} onPress={onUserPress}>
<Text style={[styles.username, { color: colors.titleText }]} numberOfLines={1}>
{textContent}
</Text>

View File

@ -331,7 +331,6 @@
"Send_audio_message": "إرسال رسالة صوتية",
"Send_crash_report": "إرسال تقرير الأعطال",
"Send_message": "إرسال الرسالة",
"Send_me_the_code_again": "أرسل الرمز مرة أخرى",
"Send_to": "إرسال إلى...",
"Sending_to": "يتم الإرسال إلى",
"Server": "سرفر",
@ -391,7 +390,6 @@
"Uses_server_configuration": "يستخدم إعداد الخادم",
"Registration_Succeeded": "تم التسجيل بنجاح",
"Verify_email_desc": "لقد أرسلنا إليك بريداً إلكترونياً لتأكيد تسجيلك. إذا لم تتلق البريد الإلكتروني قريباً، فيرجى العودة والمحاولة مرة أخرى",
"Verify_your_email_for_the_code_we_sent": "يرجى تأكيد البريد الإلكتروني عبر الرمز المرسل",
"View_Original": "عرض المحتوى الأصلي",
"Waiting_for_network": "بانتظار توفر شبكة...",
"Websocket_disabled": "تم تعطيل Websocket لهذا الخادم.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "অডিও মেসেজ পাঠান",
"Send_crash_report": "ক্র্যাশ রিপোর্ট পাঠান",
"Send_message": "মেসেজ পাঠান",
"Send_me_the_code_again": "আবার কোড পাঠান",
"Send_to": "পাঠান...",
"Sending_to": "পাঠাচ্ছি",
"Server": "ওয়ার্কস্পেস",
@ -433,7 +432,6 @@
"Uses_server_configuration": "ওয়ার্কস্পেস কনফিগারেশন ব্যবহার করে",
"Registration_Succeeded": "নিবন্ধন সফল!",
"Verify_email_desc": "আমরা আপনার নিবন্ধন নিশ্চিত করতে একটি ইমেল পাঠিয়েছি। যদি আপনি শীঘ্রই একটি ইমেল পাননি, তবে দয়া করে ফিরে এসে আবার চেষ্টা করুন।",
"Verify_your_email_for_the_code_we_sent": "আমরা পাঠায় কোডের জন্য আপনার ইমেল যাচাই করুন",
"View_Original": "মৌলিক দেখুন",
"Waiting_for_network": "নেটওয়ার্কের জন্য অপেক্ষা করছে...",
"Websocket_disabled": "এই ওয়ার্কস্পেসের জন্য ওয়েবসকেট অক্ষম রয়েছে।\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Audio-Nachricht senden",
"Send_crash_report": "Absturzbericht senden",
"Send_message": "Nachricht senden",
"Send_me_the_code_again": "Den Code neu versenden",
"Send_to": "Senden an …",
"Sending_to": "Sende an",
"Server": "Server",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Nutzt Servereinstellungen",
"Registration_Succeeded": "Registrierung erfolgreich!",
"Verify_email_desc": "Wir haben Ihnen eine Email geschickt um Ihre Anmeldung zu bestätigen. Wenn Sie keine Email erhalten, versuchen Sie es später noch einmal.",
"Verify_your_email_for_the_code_we_sent": "Prüfen Sie Ihre Mails auf den Code, den wir Ihnen eben geschickt haben.",
"View_Original": "Original anzeigen",
"Waiting_for_network": "Warte auf das Netzwerk …",
"Websocket_disabled": "Websockets sind auf diesem Server nicht aktiviert.\n{{contact}}",

View File

@ -367,7 +367,6 @@
"Send_audio_message": "Send audio message",
"Send_crash_report": "Send crash report",
"Send_message": "Send message",
"Send_me_the_code_again": "Send me the code again",
"Send_to": "Send to...",
"Sending_to": "Sending to",
"Server": "Workspace",
@ -437,7 +436,6 @@
"Uses_server_configuration": "Uses workspace configuration",
"Registration_Succeeded": "Registration succeeded!",
"Verify_email_desc": "We have sent you an email to confirm your registration. If you do not receive an email shortly, please come back and try again.",
"Verify_your_email_for_the_code_we_sent": "Verify your email for the code we sent",
"View_Original": "View original",
"Waiting_for_network": "Waiting for network...",
"Websocket_disabled": "Websocket is disabled for this workspace.\n{{contact}}",
@ -824,5 +822,8 @@
"Microphone_access_needed_to_record_audio": "Microphone access needed to record audio",
"Go_to_your_device_settings_and_allow_microphone": "Go to your device settings and allow microphone access for Rocket.Chat",
"Check_again": "Check again",
"error-no-tokens-for-this-user": "There are no tokens for this user"
"error-no-tokens-for-this-user": "There are no tokens for this user",
"Enter_the_code": "Enter the code we just emailed you.",
"Resend_email": "Resend email",
"Verify": "Verify"
}

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Lähetä ääniviesti",
"Send_crash_report": "Lähetä kaatumisraportti",
"Send_message": "Lähetä viesti",
"Send_me_the_code_again": "Lähetä koodi uudelleen",
"Send_to": "Lähetä kohteeseen...",
"Sending_to": "Lähetetään kohteeseen",
"Server": "Palvelin",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Käyttää palvelimen määrityksiä",
"Registration_Succeeded": "Rekisteröinti onnistui!",
"Verify_email_desc": "Lähetimme rekisteröitymisvahvistuksen sähköpostiisi. Jos et saa sähköpostia pian, yritä uudelleen.",
"Verify_your_email_for_the_code_we_sent": "Vahvista sähköpostiosoitteesi lähettämällämme koodilla",
"View_Original": "Näytä alkuperäinen",
"Waiting_for_network": "Odotetaan verkkoa...",
"Websocket_disabled": "Websocket ei ole käytössä tässä palvelimessa.\n{{contact}}",

View File

@ -340,7 +340,6 @@
"Send_audio_message": "Envoyer un message audio",
"Send_crash_report": "Envoyer un rapport de plantage",
"Send_message": "Envoyer un message",
"Send_me_the_code_again": "Envoyez-moi à nouveau le code",
"Send_to": "Envoyer à...",
"Sending_to": "Envoi à",
"Server": "Serveur",
@ -401,7 +400,6 @@
"Uses_server_configuration": "Utilise la configuration du serveur",
"Registration_Succeeded": "Inscription réussie !",
"Verify_email_desc": "Nous vous avons envoyé un e-mail pour confirmer votre inscription. Si vous ne recevez pas d'e-mail sous peu, veuillez revenir et réessayer.",
"Verify_your_email_for_the_code_we_sent": "Vérifiez votre e-mail pour le code que nous avons envoyé",
"View_Original": "Voir l'original",
"Waiting_for_network": "En attente du réseau...",
"Websocket_disabled": "Le Websocket est désactivé pour ce serveur.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ऑडियो संदेश भेजें",
"Send_crash_report": "क्रैश रिपोर्ट भेजें",
"Send_message": "संदेश भेजें",
"Send_me_the_code_again": "मुझे कोड फिर से भेजें",
"Send_to": "भेजें को...",
"Sending_to": "भेजा जा रहा है",
"Server": "कार्यस्थान",
@ -433,7 +432,6 @@
"Uses_server_configuration": "कार्यस्थान समरूपण का उपयोग करता है",
"Registration_Succeeded": "पंजीकरण सफल हुआ!",
"Verify_email_desc": "हमने आपको आपके पंजीकरण की पुष्टि के लिए एक ईमेल भेजा है। यदि आपको शीघ्र एक ईमेल प्राप्त नहीं होता है, तो कृपया वापस आकर पुनः प्रयास करें।",
"Verify_your_email_for_the_code_we_sent": "हमने आपको भेजे गए कोड के लिए अपनी ईमेल की पुष्टि करें",
"View_Original": "मूल देखें",
"Waiting_for_network": "नेटवर्क के लिए प्रतीक्षा कर रहा है...",
"Websocket_disabled": "इस कार्यस्थान के लिए वेबसॉकेट निष्क्रिय है।\n{{संपर्क}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Hangüzenet küldése",
"Send_crash_report": "Összeomlás jelentés küldése",
"Send_message": "Üzenet küldése",
"Send_me_the_code_again": "Küldje el nekem a kódot újra",
"Send_to": "Küldje el...",
"Sending_to": "Küldés a",
"Server": "Munkaterület",
@ -434,7 +433,6 @@
"Uses_server_configuration": "Használja a munkaterület konfigurációját",
"Registration_Succeeded": "A regisztráció sikeres",
"Verify_email_desc": "Küldtünk Önnek egy e-mailt a regisztrációja megerősítéséhez. Ha nem kap rövidesen e-mailt, akkor térjen vissza, és próbálja meg újra.",
"Verify_your_email_for_the_code_we_sent": "Ellenőrizze az e-mail-címét azzal a kóddal, amit küldtünk",
"View_Original": "Eredeti megtekintése",
"Waiting_for_network": "Hálózatra várva...",
"Websocket_disabled": "A websocket ki van kapcsolva ehhez a munkaterülethez. {{contact}}",

View File

@ -345,7 +345,6 @@
"Send_audio_message": "Invia messaggio audio",
"Send_crash_report": "Invia report sui crash",
"Send_message": "Invia messaggio",
"Send_me_the_code_again": "Inviami nuovamente il codice",
"Send_to": "Invia a...",
"Sending_to": "Invio a",
"Server": "Server",
@ -405,7 +404,6 @@
"Uses_server_configuration": "Usa la configurazione del server",
"Registration_Succeeded": "Registrazione completata!",
"Verify_email_desc": "Ti abbiamo inviato una e-mail per confermare la tua registrazione. Se non la ricevi, ritorna qui e riprova",
"Verify_your_email_for_the_code_we_sent": "Controlla l'e-mail con il codice che ti abbiamo inviato",
"View_Original": "Mostra originale",
"Waiting_for_network": "In attesa di connessione ...",
"Websocket_disabled": "Websocket disabilitata per questo server.\n{{contact}}",

View File

@ -340,7 +340,6 @@
"Send_audio_message": "Audiobericht verzenden",
"Send_crash_report": "Crashrapport verzenden",
"Send_message": "Bericht verzenden",
"Send_me_the_code_again": "Stuur me de code opnieuw",
"Send_to": "Verzenden naar...",
"Sending_to": "Verzenden naar",
"Server": "Server",
@ -401,7 +400,6 @@
"Uses_server_configuration": "Gebruikt serverconfiguratie",
"Registration_Succeeded": "Registratie geslaagd!",
"Verify_email_desc": "We hebben je een e-mail gestuurd om je inschrijving te bevestigen. Als je binnenkort geen e-mail ontvangt, gelieve terug te komen en het opnieuw te proberen.",
"Verify_your_email_for_the_code_we_sent": "Verifieer je e-mail voor de code die we hebben gestuurd",
"View_Original": "Bekijk origineel",
"Waiting_for_network": "Wachten op netwerk...",
"Websocket_disabled": "Websocket is uitgeschakeld voor deze server.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Enviar mensagem de áudio",
"Send_crash_report": "Enviar relatório de erros",
"Send_message": "Enviar mensagem",
"Send_me_the_code_again": "Envie-me o código novamente",
"Send_to": "Enviar para...",
"Sending_to": "Envio para",
"Server": "Workspace",
@ -435,7 +434,6 @@
"Uses_server_configuration": "Usar configuração da workspace",
"Registration_Succeeded": "Registrado com sucesso!",
"Verify_email_desc": "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.",
"Verify_your_email_for_the_code_we_sent": "Verifique em seu e-mail o código que enviamos",
"View_Original": "Visualizar original",
"Waiting_for_network": "Aguardando rede...",
"Websocket_disabled": "Websocket está desativado para essa workspace.\n{{contact}}",
@ -785,10 +783,6 @@
"Jitsi_authentication_before_making_calls": "Jitsi pode exigir autenticação antes de fazer chamadas. Para saber mais sobre suas políticas, visite o site do Jitsi.",
"Jitsi_authentication_before_making_calls_ask_admin": "Se você acredita que há problemas com o Jitsi e sua autenticação, peça ajuda a um administrador do espaço de trabalho.",
"Continue": "Continuar",
"decline": "Recusar",
"accept": "Aceitar",
"Incoming_call_from": "Chamada recebida de",
"Call_started": "Chamada Iniciada",
"Your_push_was_sent_to_s_devices": "A sua notificação foi enviada para {{s}} dispositivos",
"Message_has_been_shared": "Menssagem foi compartilhada",
"No_channels_in_team": "Nenhum canal nesta equipe",
@ -816,5 +810,8 @@
"In_app_message_notifications": "Notificações de mensagens in-app",
"Vibrate": "Vibrar",
"Check_again": "Verificar novamente",
"error-no-tokens-for-this-user": "Não existem tokens para este usuário"
"error-no-tokens-for-this-user": "Não existem tokens para este usuário",
"Enter_the_code": "Insira o código que acabamos de enviar por e-mail.",
"Resend_email": "Reenviar e-mail",
"Verify": "Verificar"
}

View File

@ -351,7 +351,6 @@
"Send_audio_message": "Отправить аудиосообщение",
"Send_crash_report": "Отправить отчет об ошибке",
"Send_message": "Отправить сообщение",
"Send_me_the_code_again": "Отправить мне код снова",
"Send_to": "Отправить...",
"Sending_to": "Отправляется",
"Server": "Сервер",
@ -412,7 +411,6 @@
"Uses_server_configuration": "Используется конфигурация сервера",
"Registration_Succeeded": "Регистрация Успешна!",
"Verify_email_desc": "Вам был отправлен email для подтверждения регистрации. Если вы не получили этого сообщения, пожалуйста, попробуйте еще раз.",
"Verify_your_email_for_the_code_we_sent": "Проверка вашего email с помощью отправленного нами кода",
"View_Original": "Посмотреть оригинал",
"Waiting_for_network": "Ожидание сети...",
"Websocket_disabled": "Websocket отключен для этого сервера.\n{{contact}}",

View File

@ -348,7 +348,6 @@
"Send_audio_message": "Pošljite zvočno sporočilo",
"Send_crash_report": "Pošlji poročilo o sesutju",
"Send_message": "Pošlji sporočilo",
"Send_me_the_code_again": "Pošljite mi kodo še enkrat",
"Send_to": "Pošlji...",
"Sending_to": "Pošiljanje na",
"Server": "Strežnik",
@ -409,7 +408,6 @@
"Uses_server_configuration": "Uporablja konfiguracijo strežnika",
"Registration_Succeeded": "Registracija je bila uspešna",
"Verify_email_desc": "Poslali smo vam e -poštno sporočilo za potrditev vaše registracije. Če v kratkem ne prejmete e -pošte, se vrnite in poskusite znova.",
"Verify_your_email_for_the_code_we_sent": "Preverite svoj e -poštni naslov za kodo, ki smo jo poslali",
"View_Original": "Pogled original",
"Waiting_for_network": "Čakanje na omrežje ...",
"Websocket_disabled": "WebSocket je onemogočen za ta strežnik.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "Skicka ljudmeddelande",
"Send_crash_report": "Skicka kraschrapport",
"Send_message": "Skicka meddelande",
"Send_me_the_code_again": "Skicka mig koden igen",
"Send_to": "Skicka till...",
"Sending_to": "Skickar till",
"Server": "Server",
@ -432,7 +431,6 @@
"Uses_server_configuration": "Använder serverkonfiguration",
"Registration_Succeeded": "Registreringen är klar.",
"Verify_email_desc": "Vi har skickat ett e-postmeddelande för att bekräfta din registrering. Om du inte får e-postmeddelandet försöker du igen.",
"Verify_your_email_for_the_code_we_sent": "Titta efter koden i din e-post",
"View_Original": "Visa original",
"Waiting_for_network": "Väntar på nätverket...",
"Websocket_disabled": "Websocket är inaktiverad för servern.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ஒரு ஒலி செய்தியை அனுப்பு",
"Send_crash_report": "குழப்பத்தின் அறிகையை அனுப்பு",
"Send_message": "செய்தியை அனுப்பு",
"Send_me_the_code_again": "எனக்கு குறியீடுக்கு மீண்டும் அனுப்பு",
"Send_to": "அனுப்பு...",
"Sending_to": "அனுப்பினது",
"Server": "பணி இடம்",
@ -433,7 +432,6 @@
"Uses_server_configuration": "பணியில் உள்ளேயே உபயோகிக்குகின்றது",
"Registration_Succeeded": "பதிவு செய்தது வெற்றிகரமாகின்றது!",
"Verify_email_desc": "உங்களுக்கு உங்கள் பதிவுக்கு உறுதிப்படுத்த ஒரு மின்னஞ்சல் அனுப்பினோம். உங்களுக்கு விரைவில் ஒரு மின்னஞ்சல் பெறாதிருக்கின்றார்கள், தயவுசெய்து மீண்டும் வாருங்கள் மற்றும் முயற்சிக்கவும்.",
"Verify_your_email_for_the_code_we_sent": "நாங்கள் அனுப்பிய குறியீடுக்கு உங்கள் மின்னஞ்சலை சரிபார்க்கவும்",
"View_Original": "மூலத்தைக் காண்",
"Waiting_for_network": "பிணையத்தைக் காத்திருக்கின்றது...",
"Websocket_disabled": "இந்த பணியில் Websocket முடக்கப்பட்டுள்ளது.\n{{contact}}",

View File

@ -365,7 +365,6 @@
"Send_audio_message": "ఆడియో సందేశాన్ని పంపండి",
"Send_crash_report": "క్రాష్ నివేదించండి",
"Send_message": "సందేశాన్ని పంపండి",
"Send_me_the_code_again": "మళ్ళీ కోడ్‌ను పంపండి",
"Send_to": "పంపండి...",
"Sending_to": "పంపిస్తోంది",
"Server": "పనితనం",
@ -433,7 +432,6 @@
"Uses_server_configuration": "పనితనం ఆకృతి ఉపయోగిస్తుంది",
"Registration_Succeeded": "నమోదు విజయవంతంగా చేయబడింది!",
"Verify_email_desc": "మేము మీ నమోదుని ధ్యానంలోకి పెంపొందాం. మీరు తక్షణం ఒక ఇమెయిల్ పొందరాక, దయచేసి మళ్ళీ ప్రయత్నించండి.",
"Verify_your_email_for_the_code_we_sent": "మేము పంపిన కోడ్ కోసం మీ ఇమెయిల్‌ని ధ్యానంలోకి పెంచండి",
"View_Original": "అసలు చూడండి",
"Waiting_for_network": "నెట్వర్క్ కోసం వేచి ఉండి...",
"Websocket_disabled": "ఈ పనితనంలో వెబ్‌సాకెట్ నిషేధించబడింది.\n{{contact}}",

View File

@ -328,7 +328,6 @@
"Send_audio_message": "Sesli ileti gönder",
"Send_crash_report": "Çökme raporu gönder",
"Send_message": "İleti gönder",
"Send_me_the_code_again": "Kodu tekrar gönder",
"Send_to": "Gönderiliyor...",
"Sending_to": "Gönderiliyor:",
"Server": "Sunucu",
@ -388,7 +387,6 @@
"Uses_server_configuration": "Sunucu yapılandırmasını kullanır",
"Registration_Succeeded": "Kayıt Başarılı!",
"Verify_email_desc": "Kaydınızı onaylamak için size bir e-posta gönderdik. Kısa süre içinde bir e-posta almazsanız, lütfen geri gelin ve tekrar deneyin.",
"Verify_your_email_for_the_code_we_sent": "Gönderdiğimiz kod için e-postanızı doğrulayın",
"View_Original": "Orijinali Görüntüle",
"Waiting_for_network": "Ağ bağlantısı bekleniyor ...",
"Websocket_disabled": "Bu sunucu için Websocket devre dışı bırakıldı.\n{{contact}}",

View File

@ -324,7 +324,6 @@
"Send_audio_message": "发送音频信息",
"Send_crash_report": "送出当机报告",
"Send_message": "发送信息",
"Send_me_the_code_again": "再次发送代码给我",
"Send_to": "发送到",
"Sending_to": "正发送到",
"Server": "服务器",
@ -384,7 +383,6 @@
"Uses_server_configuration": "使用服务器设置",
"Registration_Succeeded": "注册成功",
"Verify_email_desc": "我们已经送出一封电子邮件,以确认您的注册。如果您没有很快收到,请再试一次。",
"Verify_your_email_for_the_code_we_sent": "检查您的电子邮件以取得我们发送的代码",
"View_Original": "检视原文",
"Waiting_for_network": "等待网路连接",
"Websocket_disabled": "Websocket 已于此伺服器上禁用。 \\n{{contact}}",

View File

@ -330,7 +330,6 @@
"Send_audio_message": "發送語音訊息",
"Send_crash_report": "送出當機報告",
"Send_message": "發送訊息",
"Send_me_the_code_again": "再次發送代碼給我",
"Send_to": "發送到",
"Sending_to": "正發送到",
"Server": "伺服器",
@ -390,7 +389,6 @@
"Uses_server_configuration": "使用伺服器設定",
"Registration_Succeeded": "註冊成功",
"Verify_email_desc": "我們已經送出一封電子郵件,以確認您的註冊。如果您沒有很快收到,請再試一次。",
"Verify_your_email_for_the_code_we_sent": "檢查您的電子郵件以取得我們發送的代碼",
"View_Original": "檢視原文",
"Waiting_for_network": "等待網路連線",
"Websocket_disabled": "Websocket 已於此伺服器上禁用。\\n{{contact}}",

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
import ImagePicker, { Image as ImageInterface, ImageOrVideo as ImageOrVideoType } from 'react-native-image-crop-picker';
export type Image = ImageInterface;
export type ImageOrVideo = ImageOrVideoType;
export default ImagePicker;

View File

@ -7,7 +7,7 @@ export interface IInAppFeedbackState {
export const initialState: IInAppFeedbackState = {};
export default function activeUsers(state = initialState, action: TApplicationActions): IInAppFeedbackState {
export default function inAppFeedback(state = initialState, action: TApplicationActions): IInAppFeedbackState {
switch (action.type) {
case IN_APP_FEEDBACK.SET:
const { msgId } = action;

View File

@ -25,7 +25,7 @@ import { IAvatar } from '../../definitions';
import AvatarSuggestion from './AvatarSuggestion';
import log from '../../lib/methods/helpers/log';
import { changeRoomsAvatar, changeUserAvatar, resetUserAvatar } from './submitServices';
import ImagePicker, { Image } from './ImagePicker';
import ImagePicker, { Image } from '../../lib/methods/helpers/ImagePicker/ImagePicker';
enum AvatarStateActions {
CHANGE_AVATAR = 'CHANGE_AVATAR',

View File

@ -159,7 +159,7 @@ const RoomInfoView = (): React.ReactElement => {
const loadUser = async () => {
if (isEmpty(roomUser)) {
try {
const roomUserId = getUidDirectMessage(room || { rid, t, itsMe });
const roomUserId = getUidDirectMessage({ ...(room || { rid, t }), itsMe });
const result = await Services.getUserInfo(roomUserId);
if (result.success) {
const { user } = result;

View File

@ -690,7 +690,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
onEditInit = (messageId: string) => {
const { action } = this.state;
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action) {
return;
}
@ -739,7 +738,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
}
return;
}
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action) {
return;
}
@ -776,7 +774,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
};
onReactionInit = (messageId: string) => {
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (this.state.action) {
return;
}
@ -793,7 +790,6 @@ class RoomView extends React.Component<IRoomViewProps, IRoomViewState> {
onMessageLongPress = (message: TAnyMessageModel) => {
const { action } = this.state;
// TODO: implement multiple actions running. Quoting, then edit. Edit then quote.
if (action && action !== 'quote') {
return;
}

View File

@ -126,7 +126,7 @@ class ShareView extends Component<IShareViewProps, IShareViewState> {
// if is share extension show default back button
if (!this.isShareExtension) {
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} color={themes[theme].previewTintColor} />;
options.headerLeft = () => <HeaderButton.CloseModal navigation={navigation} color={themes[theme].previewTintColor} testID='share-view-close' />;
}
if (!attachments.length && !readOnly) {

View File

@ -7,7 +7,8 @@ const defaultTextStyle: TextStyle = {
backgroundColor: 'transparent',
...Platform.select({
android: {
includeFontPadding: false
includeFontPadding: false,
alignSelf: 'stretch'
}
})
};

View File

@ -143,6 +143,20 @@ async function navigateToRoom(room: string) {
await checkRoomTitle(room);
}
async function navigateToRecentRoom(room: string) {
await waitFor(element(by.id('rooms-list-view')))
.toExist()
.withTimeout(10000);
await tapAndWaitFor(element(by.id('rooms-list-view-search')), element(by.id('rooms-list-view-search-input')), 5000);
await waitFor(element(by.id(`rooms-list-view-item-${room}`)))
.toBeVisible()
.withTimeout(10000);
await element(by.id(`rooms-list-view-item-${room}`)).tap();
await waitFor(element(by.id(`room-view-title-${room}`)))
.toBeVisible()
.withTimeout(10000);
}
async function tryTapping(
theElement: Detox.IndexableNativeElement | Detox.NativeElement,
timeout: number,
@ -261,5 +275,6 @@ export {
checkServer,
platformTypes,
expectValidRegisterOrRetry,
jumpToQuotedMessage
jumpToQuotedMessage,
navigateToRecentRoom
};

View File

@ -22,7 +22,7 @@ import random from '../../helpers/random';
const DEEPLINK_METHODS = { AUTH: 'auth', ROOM: 'room' };
let amp = '&';
const amp = '&';
const getDeepLink = (method: string, server: string, params?: string) => {
const deeplink = `rocketchat://${method}?host=${server.replace(/^(http:\/\/|https:\/\/)/, '')}${amp}${params}`;
@ -47,7 +47,6 @@ describe('Deep linking', () => {
const loginResult = await login(user.username, user.password);
({ userId, authToken } = loginResult);
const deviceType = device.getPlatform();
amp = deviceType === 'android' ? '\\&' : '&';
({ textMatcher } = platformTypes[deviceType]);
// create a thread with api
const result = await sendMessage(user, room, threadMessage);

View File

@ -5,21 +5,15 @@ import {
login,
tapBack,
sleep,
searchRoom,
tryTapping,
platformTypes,
TTextMatcher,
mockMessage
mockMessage,
navigateToRoom,
navigateToRecentRoom
} from '../../helpers/app';
import { createRandomRoom, createRandomUser, ITestUser, sendMessage } from '../../helpers/data_setup';
async function navigateToRoom(roomName: string) {
await searchRoom(`${roomName}`);
await element(by.id(`rooms-list-view-item-${roomName}`)).tap();
await waitFor(element(by.id('room-view')))
.toBeVisible()
.withTimeout(5000);
}
import { createRandomRoom, createRandomUser, deleteCreatedUsers, ITestUser, sendMessage } from '../../helpers/data_setup';
import data from '../../data';
describe('Room screen', () => {
let room: string;
@ -244,6 +238,39 @@ describe('Room screen', () => {
await element(by.id('action-sheet-handle')).swipe('down', 'fast', 0.5);
});
it('should open the profile view tapping on his username', async () => {
const { username } = user;
await waitFor(element(by.id(`username-header-${username}`)))
.toExist()
.withTimeout(2000);
await element(by.id(`username-header-${username}`)).tap();
await waitFor(element(by.id('room-info-view-username')))
.toExist()
.withTimeout(2000);
await waitFor(element(by[textMatcher](`@${username}`)))
.toExist()
.withTimeout(2000);
await tapBack();
});
it('should open the profile view tapping on other username', async () => {
const otherUser = await createRandomUser();
const { username } = otherUser;
await sendMessage(otherUser, room, 'new message');
await waitFor(element(by.id(`username-header-${username}`)))
.toExist()
.withTimeout(2000);
await element(by.id(`username-header-${username}`)).tap();
await waitFor(element(by.id('room-info-view-username')))
.toExist()
.withTimeout(2000);
await waitFor(element(by[textMatcher](`@${username}`)))
.toExist()
.withTimeout(2000);
await tapBack();
await deleteCreatedUsers([{ server: data.server, username }]);
});
it('should edit message', async () => {
const editMessage = await mockMessage('edit');
const editedMessage = `${editMessage}ed`;
@ -371,6 +398,103 @@ describe('Room screen', () => {
.toExist()
.withTimeout(60000);
await element(by[textMatcher](replyMessage)).atIndex(0).tap();
await tapBack();
});
it('should save message and quote draft correctly', async () => {
const newUser = await createRandomUser();
const { name: draftRoom } = await createRandomRoom(newUser, 'c');
const draftMessage = 'draft';
const originalMessage = '123';
const quoteMessage = '123456';
await sendMessage(newUser, draftRoom, originalMessage);
await waitFor(element(by.id('rooms-list-view')))
.toBeVisible()
.withTimeout(5000);
await navigateToRoom(draftRoom);
await waitFor(element(by[textMatcher](originalMessage)).atIndex(0))
.toBeVisible()
.withTimeout(10000);
await element(by.id('room-view-join-button')).tap();
await waitFor(element(by.id('room-view-join-button')))
.not.toBeVisible()
.withTimeout(10000);
// add draft
await element(by.id('message-composer-input')).typeText(draftMessage);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await expect(element(by.id('message-composer-input'))).toHaveText(draftMessage);
// add quote to draft
await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true);
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(5000);
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Quote')).atIndex(0).tap();
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)))
.toBeVisible()
.withTimeout(10000);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)))
.toBeVisible()
.withTimeout(10000);
// edit draft with quote
await element(by.id('message-composer-input')).replaceText(quoteMessage);
await tapBack();
await navigateToRecentRoom(draftRoom);
await sleep(500); // wait for animation
await expect(element(by.id('message-composer-input'))).toHaveText(quoteMessage);
// send message
await waitFor(element(by.id('message-composer-send')))
.toExist()
.withTimeout(5000);
await element(by.id('message-composer-send')).tap();
await waitFor(element(by.id(`reply-${newUser.name}-${originalMessage}`).withDescendant(by[textMatcher](originalMessage))))
.toBeVisible()
.withTimeout(5000);
await expect(element(by.id('message-composer-input'))).toHaveText('');
});
it('should edit message on shareview and after close the text needs to be changed on roomView', async () => {
const draftShareMessage = 'draftShare';
const originalMessage = '123';
await element(by.id('message-composer-input')).typeText(draftShareMessage);
await element(by.id('message-composer-actions')).tap();
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await element(by[textMatcher]('Choose from library')).atIndex(0).tap();
await sleep(300); // wait for animation
await waitFor(element(by.id('message-composer-input-share')))
.toHaveText(draftShareMessage)
.withTimeout(2000);
await element(by.id('message-composer-input-share')).replaceText(draftShareMessage + originalMessage);
await element(by.id('share-view-close')).tap();
await sleep(500); // wait for animation
await waitFor(element(by.id('message-composer-input')))
.toHaveText(draftShareMessage + originalMessage)
.withTimeout(2000);
// add quote to draft
await tryTapping(element(by[textMatcher](originalMessage)).atIndex(0), 2000, true);
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await expect(element(by.id('action-sheet-handle'))).toBeVisible();
await element(by.id('action-sheet-handle')).swipe('up', 'fast', 0.5);
await element(by[textMatcher]('Quote')).atIndex(0).tap();
await element(by.id('message-composer-actions')).tap();
await waitFor(element(by.id('action-sheet')))
.toExist()
.withTimeout(2000);
await element(by[textMatcher]('Choose from library')).atIndex(0).tap();
await sleep(500); // wait for animation
await waitFor(element(by.id(`markdown-preview-${originalMessage}`)).atIndex(0))
.toExist()
.withTimeout(20000);
});
});
});

View File

@ -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'),
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().mockImplementation((event, callback) => {
callback();
return {
remove: jest.fn()
addListener: () => jest.fn()
}),
createNavigationContainerRef: jest.fn(),
navigate: jest.fn(),
addListener: jest.fn(() => jest.fn())
};
})
})
}));
});
jest.mock('react-native-notifications', () => ({
Notifications: {

View File

@ -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",
@ -192,7 +191,7 @@
"babel-loader": "8.3.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"codecov": "^3.8.3",
"detox": "20.11.0",
"detox": "20.17.1",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "2.26.0",
@ -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/",

118
yarn.lock
View File

@ -4335,6 +4335,11 @@
find-up "^5.0.0"
js-yaml "^4.1.0"
"@flatten-js/interval-tree@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@flatten-js/interval-tree/-/interval-tree-1.1.2.tgz#fcc891da48bc230392884be01c26fe8c625702e8"
integrity sha512-OwLoV9E/XM6b7bes2rSFnGNjyRy7vcoIHFTnmBR2WAaZTf0Fe4EX4GdA65vU1KgFAasti7iRSg2dZfYd1Zt00Q==
"@gar/promisify@^1.0.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
@ -6292,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"
@ -6311,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"
@ -8625,6 +8619,17 @@ builtins@^1.0.3:
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==
bunyamin@^1.5.0:
version "1.5.2"
resolved "https://registry.yarnpkg.com/bunyamin/-/bunyamin-1.5.2.tgz#681db204c0b16531369d5c1f6c89dc8d760b7558"
integrity sha512-Xp2nfqk33zt3nX90OSTkLVOc5N+1zdR3MWvfLHoIrm3cGRkdxPTPYB9CCgrDV8oum5rbghJjAbmXFXOrRXvMtg==
dependencies:
"@flatten-js/interval-tree" "^1.1.2"
multi-sort-stream "^1.0.4"
stream-json "^1.7.5"
trace-event-lib "^1.3.1"
bunyan-debug-stream@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-3.1.0.tgz#78309c67ad85cfb8f011155334152c49209dcda8"
@ -8642,6 +8647,18 @@ bunyan@^1.8.12:
mv "~2"
safe-json-stringify "~1"
bunyan@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-2.0.5.tgz#9dd056755220dddd8b5bb9cf76f3d0d766e96e71"
integrity sha512-Jvl74TdxCN6rSP9W1I6+UOUtwslTDqsSFkDqZlFb/ilaSvQ+bZAnXT/GT97IZ5L+Vph0joPZPhxUyn6FLNmFAA==
dependencies:
exeunt "1.1.0"
optionalDependencies:
dtrace-provider "~0.8"
moment "^2.19.3"
mv "~2"
safe-json-stringify "~1"
bytebuffer@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd"
@ -10145,10 +10162,10 @@ detect-port@^1.3.0:
address "^1.0.1"
debug "^2.6.0"
detox@20.11.0:
version "20.11.0"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.11.0.tgz#f240e01db12334e0706b7f3477e59b8a5e4358c8"
integrity sha512-01LpETlZwfo2V7Awo+5ccUbee7E1lvH3ldLlmXxsx3mQ0pEA65f9CaO+FWhtUGYh7vQRMOQ9SnzYdej/ydQ7iQ==
detox@20.17.1:
version "20.17.1"
resolved "https://registry.yarnpkg.com/detox/-/detox-20.17.1.tgz#55b9615cf5937819e1257fbf03fb2d2d58cf2acc"
integrity sha512-10pey6CR9D5GSloRkH60ObBGZ8VS11H7iuBNY7qq6jO2swiqqckHhPLRXfH9+WGR7l3vDnfU+G/gQs7JxQkJwA==
dependencies:
ajv "^8.6.3"
bunyan "^1.8.12"
@ -10162,6 +10179,7 @@ detox@20.11.0:
funpermaproxy "^1.1.0"
glob "^8.0.3"
ini "^1.3.4"
jest-environment-emit "^1.0.5"
json-cycle "^1.3.0"
lodash "^4.17.11"
multi-sort-stream "^1.0.3"
@ -11138,6 +11156,11 @@ execa@^5.0.0, execa@^5.1.1:
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
exeunt@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/exeunt/-/exeunt-1.1.0.tgz#af72db6f94b3cb75e921aee375d513049843d284"
integrity sha512-dd++Yn/0Fp+gtJ04YHov7MeAii+LFivJc6KqnJNfplzLVUkUDrfKoQDTLlCgzcW15vY5hKlHasWeIsQJ8agHsw==
exif-parser@^0.1.12:
version "0.1.12"
resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922"
@ -13731,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"
@ -13769,6 +13782,20 @@ jest-each@^28.1.3:
jest-util "^28.1.3"
pretty-format "^28.1.3"
jest-environment-emit@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/jest-environment-emit/-/jest-environment-emit-1.0.5.tgz#e6f33451f98b88ccd48e9e1188bb535880f03c1b"
integrity sha512-OsQ08AhYxkkyDBTIow+9ogNmJheQIGWQKp0Nku+1ToLWjAj2Pd6LmypN8HgUIqYHs4HFcqkQ25kaf1qExmoZpg==
dependencies:
bunyamin "^1.5.0"
bunyan "^2.0.5"
bunyan-debug-stream "^3.1.0"
funpermaproxy "^1.1.0"
lodash.merge "^4.6.2"
node-ipc "9.2.1"
strip-ansi "^6.0.0"
tslib "^2.5.3"
jest-environment-node@^28.1.3:
version "28.1.3"
resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5"
@ -13914,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"
@ -15787,7 +15804,7 @@ ms@2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
multi-sort-stream@^1.0.3:
multi-sort-stream@^1.0.3, multi-sort-stream@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/multi-sort-stream/-/multi-sort-stream-1.0.4.tgz#e4348edc9edc36e16333e531a90c0f166235cc99"
integrity sha512-hAZ8JOEQFbgdLe8HWZbb7gdZg0/yAIHF00Qfo3kd0rXFv96nXe+/bPTrKHZ2QMHugGX4FiAyET1Lt+jiB+7Qlg==
@ -17140,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"
@ -19586,6 +19594,13 @@ stream-json@^1.7.4:
dependencies:
stream-chain "^2.2.5"
stream-json@^1.7.5:
version "1.8.0"
resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.8.0.tgz#53f486b2e3b4496c506131f8d7260ba42def151c"
integrity sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==
dependencies:
stream-chain "^2.2.5"
stream-shift@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
@ -20476,6 +20491,11 @@ tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
tslib@^2.5.3:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
tsutils@^3.21.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623"