1/*
2 * Copyright (C) 2017 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
17package androidx.emoji.widget;
18
19import static androidx.emoji.util.EmojiMatcher.sameCharSequence;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertFalse;
23import static org.junit.Assert.assertNotNull;
24import static org.junit.Assert.assertNull;
25import static org.junit.Assert.assertTrue;
26import static org.mockito.ArgumentMatchers.anyInt;
27import static org.mockito.ArgumentMatchers.eq;
28import static org.mockito.Mockito.mock;
29import static org.mockito.Mockito.times;
30import static org.mockito.Mockito.verify;
31import static org.mockito.Mockito.when;
32
33import android.content.Context;
34import android.inputmethodservice.InputMethodService;
35import android.support.test.InstrumentationRegistry;
36import android.support.test.annotation.UiThreadTest;
37import android.support.test.filters.SdkSuppress;
38import android.support.test.filters.SmallTest;
39import android.support.test.runner.AndroidJUnit4;
40import android.text.InputType;
41import android.view.LayoutInflater;
42import android.view.View;
43import android.view.ViewGroup;
44import android.view.inputmethod.EditorInfo;
45
46import androidx.emoji.R;
47import androidx.emoji.text.EmojiCompat;
48
49import org.junit.Before;
50import org.junit.BeforeClass;
51import org.junit.Test;
52import org.junit.runner.RunWith;
53
54@SmallTest
55@RunWith(AndroidJUnit4.class)
56public class EmojiExtractTextLayoutTest {
57
58    private InputMethodService mInputMethodService;
59
60    @BeforeClass
61    public static void setupEmojiCompat() {
62        EmojiCompat.reset(mock(EmojiCompat.class));
63    }
64
65    @Before
66    public void setup() {
67        mInputMethodService = mock(InputMethodService.class);
68    }
69
70    @Test
71    @UiThreadTest
72    public void testInflate() {
73        final Context context = InstrumentationRegistry.getTargetContext();
74        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
75                .inflate(androidx.emoji.test.R.layout.extract_view, null);
76
77        final EmojiExtractEditText extractEditText = layout.findViewById(
78                android.R.id.inputExtractEditText);
79        assertNotNull(extractEditText);
80
81        final ViewGroup inputExtractAccessories = layout.findViewById(
82                R.id.inputExtractAccessories);
83        assertNotNull(inputExtractAccessories);
84
85        final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById(
86                R.id.inputExtractAction);
87        assertNotNull(extractButton);
88    }
89
90    @Test
91    @UiThreadTest
92    public void testSetKeyListener_withNull() {
93        final Context context = InstrumentationRegistry.getTargetContext();
94        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
95                .inflate(androidx.emoji.test.R.layout.extract_view, null);
96
97        final EmojiExtractEditText extractEditText = layout.findViewById(
98                android.R.id.inputExtractEditText);
99        assertNotNull(extractEditText);
100
101        extractEditText.setKeyListener(null);
102        assertNull(extractEditText.getKeyListener());
103    }
104
105    @Test
106    @UiThreadTest
107    public void testSetEmojiReplaceStrategy() {
108        final Context context = InstrumentationRegistry.getTargetContext();
109
110        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
111                .inflate(androidx.emoji.test.R.layout.extract_view_with_attrs, null);
112
113        assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, layout.getEmojiReplaceStrategy());
114
115        final EmojiExtractEditText extractEditText = layout.findViewById(
116                android.R.id.inputExtractEditText);
117        assertNotNull(extractEditText);
118        assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT,
119                extractEditText.getEmojiReplaceStrategy());
120
121        layout.setEmojiReplaceStrategy(EmojiCompat.REPLACE_STRATEGY_ALL);
122        assertEquals(EmojiCompat.REPLACE_STRATEGY_ALL, layout.getEmojiReplaceStrategy());
123        assertEquals(EmojiCompat.REPLACE_STRATEGY_ALL, extractEditText.getEmojiReplaceStrategy());
124    }
125
126    @Test
127    @UiThreadTest
128    @SdkSuppress(minSdkVersion = 19)
129    public void testSetEmojiReplaceStrategyCallEmojiCompatWithCorrectStrategy() {
130        final Context context = InstrumentationRegistry.getTargetContext();
131
132        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
133                .inflate(androidx.emoji.test.R.layout.extract_view_with_attrs, null);
134
135        final EmojiExtractEditText extractEditText = layout.findViewById(
136                android.R.id.inputExtractEditText);
137        assertNotNull(layout);
138        assertNotNull(extractEditText);
139        assertEquals(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT, layout.getEmojiReplaceStrategy());
140
141        final EmojiCompat emojiCompat = mock(EmojiCompat.class);
142        when(emojiCompat.getLoadState()).thenReturn(EmojiCompat.LOAD_STATE_SUCCEEDED);
143        EmojiCompat.reset(emojiCompat);
144
145        final String testString = "anytext";
146        extractEditText.setText(testString);
147
148        verify(emojiCompat, times(1)).process(sameCharSequence(testString), anyInt(), anyInt(),
149                anyInt(), eq(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT));
150    }
151
152    @Test
153    @UiThreadTest
154    public void testOnUpdateExtractingViews() {
155        final Context context = InstrumentationRegistry.getTargetContext();
156        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
157                .inflate(androidx.emoji.test.R.layout.extract_view, null);
158
159        final EditorInfo editorInfo = new EditorInfo();
160        editorInfo.actionLabel = "My Action Label";
161        editorInfo.imeOptions = EditorInfo.IME_ACTION_SEND;
162        editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
163
164        when(mInputMethodService.isExtractViewShown()).thenReturn(true);
165
166        final ViewGroup inputExtractAccessories = layout.findViewById(
167                R.id.inputExtractAccessories);
168        inputExtractAccessories.setVisibility(View.GONE);
169
170        final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById(
171                R.id.inputExtractAction);
172
173        layout.onUpdateExtractingViews(mInputMethodService, editorInfo);
174
175        assertEquals(View.VISIBLE, inputExtractAccessories.getVisibility());
176        assertEquals(editorInfo.actionLabel, extractButton.getText());
177        assertTrue(extractButton.hasOnClickListeners());
178    }
179
180    @Test
181    @UiThreadTest
182    public void testOnUpdateExtractingViews_hidesAccessoriesIfNoAction() {
183        final Context context = InstrumentationRegistry.getTargetContext();
184        final EmojiExtractTextLayout layout = (EmojiExtractTextLayout) LayoutInflater.from(context)
185                .inflate(androidx.emoji.test.R.layout.extract_view, null);
186
187        final EditorInfo editorInfo = new EditorInfo();
188        editorInfo.imeOptions = EditorInfo.IME_ACTION_NONE;
189        when(mInputMethodService.isExtractViewShown()).thenReturn(true);
190
191        final ViewGroup inputExtractAccessories = layout.findViewById(
192                R.id.inputExtractAccessories);
193        final ExtractButtonCompat extractButton = inputExtractAccessories.findViewById(
194                R.id.inputExtractAction);
195
196        layout.onUpdateExtractingViews(mInputMethodService, editorInfo);
197
198        assertEquals(View.GONE, inputExtractAccessories.getVisibility());
199        assertFalse(extractButton.hasOnClickListeners());
200    }
201}
202