import { View, Text, TouchableOpacity } from 'react-native'; import React, { ComponentType, useState } from 'react'; import { fireEvent, render, waitFor } from '@testing-library/react-native'; import MentionTextInput from '../MentionTextInput'; import noop from '../../helpers/noop'; describe('MentionTextInput', () => { describe('Functionality', () => { const Example: ComponentType<{ logger?: (_: any[]) => void }> = ({ logger = noop }) => { const [value, setValue] = useState([]); logger(value); return ( setValue(value)} renderSuggestionList={(searchValue, onSelect) => ( {searchValue} onSelect('999', 'Gia Toan')} /> )} /> ); }; it('shows the suggestion list when users press @', async () => { const { getByTestId, queryByTestId } = render(); const mentionTextInput = getByTestId('my-mention-text-input'); fireTypeEvent(mentionTextInput, 'Hello, @toan'); await waitFor(() => expect(queryByTestId('suggestion-list')).toBeTruthy()); expect(getByTestId('search-value').props.children).toBe('toan'); }); it('hides the suggestion list when users press space', async () => { const { getByTestId, queryByTestId } = render(); const mentionTextInput = getByTestId('my-mention-text-input'); fireTypeEvent(mentionTextInput, 'Hello, @toan '); await waitFor(() => expect(queryByTestId('suggestion-list')).toBeFalsy()); }); it('hides the suggestion list when users change selection', async () => { const { getByTestId, queryByTestId } = render(); const mentionTextInput = getByTestId('my-mention-text-input'); fireTypeEvent(mentionTextInput, 'Hello, @toan'); await waitFor(() => expect(queryByTestId('suggestion-list')).toBeTruthy()); fireEvent(mentionTextInput, 'selectionChange', { nativeEvent: { selection: { start: 0, end: 0, }, }, }); expect(queryByTestId('suggestion-list')).toBeFalsy(); }); it('updates value when users press a suggestion item', async () => { const logger = jest.fn(); const { getByTestId, queryByTestId } = render(); const mentionTextInput = getByTestId('my-mention-text-input'); fireTypeEvent(mentionTextInput, 'Hello, @toan'); const suggestionItem = getByTestId('suggestion-item'); fireEvent.press(suggestionItem); // pressing an item triggers selectionChange fireEvent(mentionTextInput, 'selectionChange', { nativeEvent: { selection: { start: 999, end: 999, }, }, }); expect(queryByTestId('suggestion-list')).toBeFalsy(); expect(logger).lastCalledWith([ { ref: undefined, text: 'Hello, ' }, { ref: '999', text: '@Gia Toan' }, { ref: undefined, text: ' ' }, ]); }); }); describe('Snapshot', () => { const value = [ { ref: undefined, text: 'Hello, ' }, { ref: '999', text: '@Gia Toan' }, ]; it.each` element ${( null} />)} ${( null} disabled />)} `('renders correctly', async ({ element }) => { const { toJSON } = render(element); expect(toJSON()).toMatchSnapshot(); }); }); }); const fireTypeEvent = (element, text = '') => { let value = ''; let position = 0; text.split('').forEach(char_ => { value = value + char_; position = position + 1; fireEvent.changeText(element, value); fireEvent(element, 'selectionChange', { nativeEvent: { selection: { start: position, end: position, }, }, }); fireEvent(element, 'keyPress', { nativeEvent: { key: char_, }, }); }); };