From f68f3120ec24c2a781e6c266f20858e7953551cb Mon Sep 17 00:00:00 2001 From: Panagiotis Plytas Date: Mon, 7 Sep 2020 23:42:22 +0300 Subject: [PATCH] feat: support 'editable' prop on TextInput (#517) * test: Add tests for non-editable TextInput * feat: use editable prop to check for event handling --- src/__tests__/fireEvent.test.js | 40 +++++++++++++++++++++++++++++++++ src/fireEvent.js | 13 +++++++++-- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/__tests__/fireEvent.test.js b/src/__tests__/fireEvent.test.js index 21b1258a..74d97aa9 100644 --- a/src/__tests__/fireEvent.test.js +++ b/src/__tests__/fireEvent.test.js @@ -193,6 +193,46 @@ test('should not fire on disabled Pressable', () => { expect(handlePress).not.toHaveBeenCalled(); }); +test('should not fire on non-editable TextInput', () => { + const placeholder = 'Test placeholder'; + const onChangeTextMock = jest.fn(); + const NEW_TEXT = 'New text'; + + const { getByPlaceholderText } = render( + + + + ); + + fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT); + expect(onChangeTextMock).not.toHaveBeenCalled(); +}); + +test('should not fire on non-editable TextInput with nested Text', () => { + const placeholder = 'Test placeholder'; + const onChangeTextMock = jest.fn(); + const NEW_TEXT = 'New text'; + + const { getByPlaceholderText } = render( + + + Test text + + + ); + + fireEvent.changeText(getByPlaceholderText(placeholder), NEW_TEXT); + expect(onChangeTextMock).not.toHaveBeenCalled(); +}); + test('should pass event up on disabled TouchableOpacity', () => { const handleInnerPress = jest.fn(); const handleOuterPress = jest.fn(); diff --git a/src/fireEvent.js b/src/fireEvent.js index 350a950e..08b9a65e 100644 --- a/src/fireEvent.js +++ b/src/fireEvent.js @@ -2,6 +2,12 @@ import act from './act'; import { ErrorWithStack } from './helpers/errors'; +const isTextInputComponent = (element: ReactTestInstance) => { + // eslint-disable-next-line import/no-extraneous-dependencies + const { TextInput } = require('react-native'); + return element.type === TextInput; +}; + const findEventHandler = ( element: ReactTestInstance, eventName: string, @@ -14,8 +20,11 @@ const findEventHandler = ( const isHostComponent = typeof element.type === 'string'; const hostElement = isHostComponent ? element : nearestHostDescendent; - const isEventEnabled = - hostElement?.props.onStartShouldSetResponder?.() !== false; + + const isEventEnabled = isTextInputComponent(element) + ? element.props.editable !== false + : hostElement?.props.onStartShouldSetResponder?.() !== false; + if (handler && isEventEnabled) return handler; // Do not bubble event to the root element