1 /*
2  * Copyright (C) 2021 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 android.translation.cts.unittests;
18 
19 import static android.view.translation.TranslationResponseValue.STATUS_SUCCESS;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import android.text.InputType;
24 import android.text.method.PasswordTransformationMethod;
25 import android.translation.cts.R;
26 import android.translation.cts.SimpleActivity;
27 import android.util.Log;
28 import android.view.translation.TranslationResponseValue;
29 import android.view.translation.TranslationSpec;
30 import android.view.translation.ViewTranslationRequest;
31 import android.view.translation.ViewTranslationResponse;
32 import android.widget.TextView;
33 
34 import androidx.test.core.app.ActivityScenario;
35 import androidx.test.ext.junit.rules.ActivityScenarioRule;
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import org.junit.After;
39 import org.junit.Before;
40 import org.junit.Rule;
41 import org.junit.Test;
42 import org.junit.runner.RunWith;
43 
44 import java.util.function.Consumer;
45 
46 /**
47  * Tests for {@link TextView} translation related APIs.
48  */
49 @RunWith(AndroidJUnit4.class)
50 public class TextViewTranslationTest {
51 
52     private static final String TAG = "TextViewTranslationTest";
53     private static final int[] SUPPORTED_DATA_FORMAT = new int[]{TranslationSpec.DATA_FORMAT_TEXT};
54 
55     @Rule
56     public ActivityScenarioRule<SimpleActivity> mActivityRule = new ActivityScenarioRule<>(
57             SimpleActivity.class);
58 
59     ActivityScenario<SimpleActivity> mScenario;
60     TextView mTestTextView;
61     TestRequestConsumer mRequestConsumer;
62 
63     @Before
setup()64     public void setup() throws Exception {
65         mScenario = mActivityRule.getScenario();
66         mScenario.onActivity(activity -> {
67             mTestTextView = activity.findViewById(R.id.hello);
68         });
69         mRequestConsumer = new TestRequestConsumer();
70     }
71 
72     @After
cleanup()73     public void cleanup() throws Exception {
74         if (mScenario != null) {
75             mScenario.close();
76             mScenario = null;
77         }
78         mTestTextView = null;
79     }
80 
81     @Test
testOnCreateViewTranslationRequest()82     public void testOnCreateViewTranslationRequest() throws Throwable {
83         mScenario.onActivity(activity -> {
84             // Normal text view
85             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
86         });
87         ViewTranslationRequest request = mRequestConsumer.getRequest();
88         Log.d(TAG, "Collect request = " + request);
89 
90         assertThat(request).isNotNull();
91         assertThat(request.getAutofillId()).isEqualTo(mTestTextView.getAutofillId());
92         assertThat(request.getValue(ViewTranslationRequest.ID_TEXT).getText().toString())
93                 .isEqualTo(mTestTextView.getText().toString());
94     }
95 
96     @Test
testOnCreateViewTranslationRequest_emptyText_returnsNull()97     public void testOnCreateViewTranslationRequest_emptyText_returnsNull() throws Throwable {
98         mScenario.onActivity(activity -> {
99             // TextView with empty
100             mTestTextView.setText("");
101             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
102         });
103         Log.d(TAG, "Collect request = " + mRequestConsumer.getRequest());
104 
105         assertThat(mRequestConsumer.getRequest()).isNull();
106     }
107 
108     @Test
testOnCreateViewTranslationRequest_hasPassword_returnsNull()109     public void testOnCreateViewTranslationRequest_hasPassword_returnsNull() throws Throwable {
110         mScenario.onActivity(activity -> {
111             // TextView with android:password true
112             mTestTextView = activity.findViewById(R.id.textview_password);
113             mTestTextView.setText("fake_password");
114             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
115         });
116         Log.d(TAG, "Collect request = " + mRequestConsumer.getRequest());
117 
118         assertThat(mRequestConsumer.getRequest()).isNull();
119     }
120 
121     @Test
testOnCreateViewTranslationRequest_hasPasswordTransformationMethod_returnsNull()122     public void testOnCreateViewTranslationRequest_hasPasswordTransformationMethod_returnsNull()
123             throws Throwable {
124         mScenario.onActivity(activity -> {
125             // TextView with PasswordTransformationMethod
126             mTestTextView.setTransformationMethod(new PasswordTransformationMethod());
127             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
128         });
129         Log.d(TAG, "Collect request = " + mRequestConsumer.getRequest());
130 
131         assertThat(mRequestConsumer.getRequest()).isNull();
132     }
133 
134     @Test
testOnCreateViewTranslationRequest_textSelectable_returnsNull()135     public void testOnCreateViewTranslationRequest_textSelectable_returnsNull()
136             throws Throwable {
137         mScenario.onActivity(activity -> {
138             // TextView is selectable
139             mTestTextView.setTextIsSelectable(true);
140             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
141         });
142         Log.d(TAG, "Collect request = " + mRequestConsumer.getRequest());
143 
144         assertThat(mRequestConsumer.getRequest()).isNull();
145     }
146 
147     @Test
testOnCreateViewTranslationRequest_textEditable_returnsNull()148     public void testOnCreateViewTranslationRequest_textEditable_returnsNull()
149             throws Throwable {
150         mScenario.onActivity(activity -> {
151             // TextView is editable
152             mTestTextView.setText("Test", TextView.BufferType.EDITABLE);
153             mTestTextView.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
154             mTestTextView.onCreateViewTranslationRequest(SUPPORTED_DATA_FORMAT, mRequestConsumer);
155         });
156         Log.d(TAG, "Collect request = " + mRequestConsumer.getRequest());
157 
158         assertThat(mRequestConsumer.getRequest()).isNull();
159     }
160 
161     @Test
testonViewTranslationResponse()162     public void testonViewTranslationResponse() throws Throwable {
163         final ViewTranslationResponse expectedResponse =
164                 new ViewTranslationResponse.Builder(mTestTextView.getAutofillId())
165                         .setValue(ViewTranslationRequest.ID_TEXT,
166                                 new TranslationResponseValue.Builder(STATUS_SUCCESS)
167                                         .setText("HELLO WORLD").build()).build();
168         mScenario.onActivity(activity -> {
169             // ViewTranslationResponse is set in onViewTranslationResponse
170             mTestTextView.onViewTranslationResponse(expectedResponse);
171         });
172         final ViewTranslationResponse response = mTestTextView.getViewTranslationResponse();
173         Log.d(TAG, "response = " + response);
174 
175         assertThat(response).isNotNull();
176         assertThat(mTestTextView.getViewTranslationResponse()).isEqualTo(expectedResponse);
177     }
178 
179     private static final class TestRequestConsumer implements Consumer<ViewTranslationRequest> {
180         private ViewTranslationRequest mRequest;
181 
182         @Override
accept(ViewTranslationRequest request)183         public void accept(ViewTranslationRequest request) {
184             mRequest = request;
185         }
186 
getRequest()187         ViewTranslationRequest getRequest() {
188             return mRequest;
189         }
190     }
191 }
192