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