From e582ddd98f31b82a4016bbf6de1ec336073308e3 Mon Sep 17 00:00:00 2001 From: pierrezimmermann Date: Sun, 4 Sep 2022 16:10:41 +0200 Subject: [PATCH 1/4] fix: prevent non editable textinputs from being updated through getByTestID --- src/__tests__/fireEvent.test.tsx | 18 ++++++++++++++++++ src/fireEvent.ts | 10 +++++++++- src/helpers/filterNodeByType.ts | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx index a8a7dca84..decd2aa03 100644 --- a/src/__tests__/fireEvent.test.tsx +++ b/src/__tests__/fireEvent.test.tsx @@ -235,6 +235,24 @@ test('should not fire on non-editable TextInput', () => { expect(onChangeTextMock).not.toHaveBeenCalled(); }); +test('should not fire on non-editable TextInput getting by testID', () => { + const testID = 'my-text-input'; + const onChangeTextMock = jest.fn(); + const NEW_TEXT = 'New text'; + + const { getByTestId } = render( + + ); + + fireEvent.changeText(getByTestId(testID), 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(); diff --git a/src/fireEvent.ts b/src/fireEvent.ts index 0f95381e4..b66f4afdd 100644 --- a/src/fireEvent.ts +++ b/src/fireEvent.ts @@ -1,5 +1,6 @@ import { ReactTestInstance } from 'react-test-renderer'; import act from './act'; +import { filterNodeByType } from './helpers/filterNodeByType'; type EventHandler = (...args: any) => unknown; @@ -8,8 +9,15 @@ const isHostElement = (element?: ReactTestInstance) => { }; const isTextInput = (element?: ReactTestInstance) => { + if (!element) { + return false; + } + const { TextInput } = require('react-native'); - return element?.type === TextInput; + return ( + filterNodeByType(element, TextInput) || + filterNodeByType(element, 'TextInput') + ); }; const isTouchResponder = (element?: ReactTestInstance) => { diff --git a/src/helpers/filterNodeByType.ts b/src/helpers/filterNodeByType.ts index 751e73b3f..1330d41c5 100644 --- a/src/helpers/filterNodeByType.ts +++ b/src/helpers/filterNodeByType.ts @@ -3,5 +3,5 @@ import * as React from 'react'; export const filterNodeByType = ( node: ReactTestInstance | React.ReactElement, - type: React.ElementType + type: React.ElementType | string ) => node.type === type; From a23787e23f23d00919729461bdd9da4ae0ebbbf6 Mon Sep 17 00:00:00 2001 From: pierrezimmermann Date: Mon, 5 Sep 2022 22:14:22 +0200 Subject: [PATCH 2/4] refactor: add comment to explain double check in isTextInput function --- src/fireEvent.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/fireEvent.ts b/src/fireEvent.ts index b66f4afdd..2da697383 100644 --- a/src/fireEvent.ts +++ b/src/fireEvent.ts @@ -14,6 +14,12 @@ const isTextInput = (element?: ReactTestInstance) => { } const { TextInput } = require('react-native'); + // We have to test if the element type is either the TextInput component + // (which would if it is a composite component) or the string + // TextInput (which would be true if it is a host component) + // All queries but the one by testID return composite component and event + // if all queries returned host components, since fireEvent bubbles up + // it would trigger the parent prop without the composite component check return ( filterNodeByType(element, TextInput) || filterNodeByType(element, 'TextInput') From 9d4aaf136da80a1397e014907ca8db0f685042ba Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 13 Sep 2022 16:15:22 +0200 Subject: [PATCH 3/4] Update src/__tests__/fireEvent.test.tsx --- src/__tests__/fireEvent.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx index decd2aa03..3d5414d22 100644 --- a/src/__tests__/fireEvent.test.tsx +++ b/src/__tests__/fireEvent.test.tsx @@ -235,7 +235,7 @@ test('should not fire on non-editable TextInput', () => { expect(onChangeTextMock).not.toHaveBeenCalled(); }); -test('should not fire on non-editable TextInput getting by testID', () => { +test('should not fire on non-editable host TextInput, () => { const testID = 'my-text-input'; const onChangeTextMock = jest.fn(); const NEW_TEXT = 'New text'; From 26d484b0c3bec742953bfb057b20312ace00bbb7 Mon Sep 17 00:00:00 2001 From: Maciej Jastrzebski Date: Tue, 13 Sep 2022 16:17:44 +0200 Subject: [PATCH 4/4] Update src/__tests__/fireEvent.test.tsx --- src/__tests__/fireEvent.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/fireEvent.test.tsx b/src/__tests__/fireEvent.test.tsx index 3d5414d22..30afd8848 100644 --- a/src/__tests__/fireEvent.test.tsx +++ b/src/__tests__/fireEvent.test.tsx @@ -235,7 +235,7 @@ test('should not fire on non-editable TextInput', () => { expect(onChangeTextMock).not.toHaveBeenCalled(); }); -test('should not fire on non-editable host TextInput, () => { +test('should not fire on non-editable host TextInput', () => { const testID = 'my-text-input'; const onChangeTextMock = jest.fn(); const NEW_TEXT = 'New text';