1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settingslib.spa.framework.compose
18 
19 import androidx.compose.foundation.layout.size
20 import androidx.compose.foundation.lazy.LazyColumn
21 import androidx.compose.material3.Text
22 import androidx.compose.runtime.CompositionLocalProvider
23 import androidx.compose.runtime.LaunchedEffect
24 import androidx.compose.ui.ExperimentalComposeUiApi
25 import androidx.compose.ui.Modifier
26 import androidx.compose.ui.platform.LocalSoftwareKeyboardController
27 import androidx.compose.ui.platform.SoftwareKeyboardController
28 import androidx.compose.ui.test.junit4.createComposeRule
29 import androidx.compose.ui.unit.dp
30 import androidx.test.ext.junit.runners.AndroidJUnit4
31 import org.junit.Rule
32 import org.junit.Test
33 import org.junit.runner.RunWith
34 import org.mockito.Mock
35 import org.mockito.Mockito.never
36 import org.mockito.Mockito.verify
37 import org.mockito.junit.MockitoJUnit
38 import org.mockito.junit.MockitoRule
39 
40 @OptIn(ExperimentalComposeUiApi::class)
41 @RunWith(AndroidJUnit4::class)
42 class KeyboardsTest {
43     @get:Rule
44     val composeTestRule = createComposeRule()
45 
46     @get:Rule
47     val mockito: MockitoRule = MockitoJUnit.rule()
48 
49     @Mock
50     lateinit var keyboardController: SoftwareKeyboardController
51 
52     @Test
53     fun hideKeyboardAction_callControllerHide() {
54         lateinit var action: () -> Unit
55         composeTestRule.setContent {
56             CompositionLocalProvider(LocalSoftwareKeyboardController provides keyboardController) {
57                 action = hideKeyboardAction()
58             }
59         }
60 
61         action()
62 
63         verify(keyboardController).hide()
64     }
65 
66     @Test
67     fun rememberLazyListStateAndHideKeyboardWhenStartScroll_notCallHideInitially() {
68         setLazyColumn(scroll = false)
69 
70         verify(keyboardController, never()).hide()
71     }
72 
73     @Test
74     fun rememberLazyListStateAndHideKeyboardWhenStartScroll_callHideWhenScroll() {
75         setLazyColumn(scroll = true)
76 
77         verify(keyboardController).hide()
78     }
79 
80     private fun setLazyColumn(scroll: Boolean) {
81         composeTestRule.setContent {
82             CompositionLocalProvider(LocalSoftwareKeyboardController provides keyboardController) {
83                 val lazyListState = rememberLazyListStateAndHideKeyboardWhenStartScroll()
84                 LazyColumn(
85                     modifier = Modifier.size(100.dp),
86                     state = lazyListState,
87                 ) {
88                     items(count = 10) {
89                         Text(text = it.toString())
90                     }
91                 }
92                 if (scroll) {
93                     LaunchedEffect(Unit) {
94                         lazyListState.animateScrollToItem(1)
95                     }
96                 }
97             }
98         }
99     }
100 }
101