Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,11 @@ public open class ReactTextInputManager public constructor() :
}
}

editText.setOnEditorActionListener { _: TextView?, actionId: Int, _: KeyEvent? ->
editText.setOnEditorActionListener { _: TextView?, actionId: Int, keyEvent: KeyEvent? ->
// TextView calls this again on key up for a hardware Enter it already handled on key down
if (keyEvent?.action == KeyEvent.ACTION_UP) {
return@setOnEditorActionListener true
}
if ((actionId and EditorInfo.IME_MASK_ACTION) != 0 || actionId == EditorInfo.IME_NULL) {
val isMultiline = editText.isMultiline

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

@file:Suppress("DEPRECATION")

package com.facebook.react.views.textinput

import android.util.DisplayMetrics
import android.view.KeyEvent
import com.facebook.react.bridge.BridgeReactContext
import com.facebook.react.bridge.JavaOnlyMap
import com.facebook.react.bridge.ReactContext
import com.facebook.react.bridge.ReactTestHelper.createMockCatalystInstance
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlagsForTests
import com.facebook.react.uimanager.DisplayMetricsHolder
import com.facebook.react.uimanager.ReactStylesDiffMap
import com.facebook.react.uimanager.ThemedReactContext
import com.facebook.react.uimanager.UIManagerHelper
import com.facebook.react.uimanager.events.EventDispatcher
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.MockedStatic
import org.mockito.Mockito.mockStatic
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment

@RunWith(RobolectricTestRunner::class)
class ReactTextInputSubmitEditingTest {

private lateinit var themedContext: ThemedReactContext
private lateinit var eventDispatcher: EventDispatcher
private lateinit var uiManagerHelperMock: MockedStatic<UIManagerHelper>

@Before
fun setup() {
ReactNativeFeatureFlagsForTests.setUp()
val context = BridgeReactContext(RuntimeEnvironment.getApplication())
context.initializeWithInstance(createMockCatalystInstance())
themedContext = ThemedReactContext(context, context, null, -1)
DisplayMetricsHolder.setScreenDisplayMetrics(DisplayMetrics())
eventDispatcher = mock()
uiManagerHelperMock = mockStatic(UIManagerHelper::class.java)
uiManagerHelperMock
.`when`<EventDispatcher?> { UIManagerHelper.getEventDispatcher(any()) }
.thenReturn(eventDispatcher)
uiManagerHelperMock
.`when`<ReactContext> { UIManagerHelper.getReactContext(any()) }
.thenReturn(context)
}

@After
fun teardown() {
uiManagerHelperMock.close()
DisplayMetricsHolder.setScreenDisplayMetrics(null)
}

@Test
fun testHardwareEnterSubmitsMultilineOnce() {
val view =
ReactTextInputManager()
.createView(
1,
themedContext,
ReactStylesDiffMap(JavaOnlyMap.of("multiline", true, "submitBehavior", "submit")),
null,
mock(),
)

view.onKeyDown(KeyEvent.KEYCODE_ENTER, KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER))
view.onKeyUp(KeyEvent.KEYCODE_ENTER, KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER))

verify(eventDispatcher, times(1)).dispatchEvent(any<ReactTextInputSubmitEditingEvent>())
}
}
Loading