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 com.android.car.debuggingrestrictioncontroller; 18 19 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 20 import static androidx.test.espresso.Espresso.onView; 21 import static androidx.test.espresso.action.ViewActions.click; 22 import static androidx.test.espresso.action.ViewActions.typeText; 23 import static androidx.test.espresso.assertion.ViewAssertions.matches; 24 import static androidx.test.espresso.intent.Intents.intended; 25 import static androidx.test.espresso.intent.Intents.intending; 26 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent; 27 import static androidx.test.espresso.intent.matcher.IntentMatchers.toPackage; 28 import static androidx.test.espresso.matcher.ViewMatchers.hasErrorText; 29 import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; 30 import static androidx.test.espresso.matcher.ViewMatchers.isEnabled; 31 import static androidx.test.espresso.matcher.ViewMatchers.withId; 32 import static androidx.test.espresso.matcher.ViewMatchers.withText; 33 import static org.hamcrest.Matchers.allOf; 34 import static org.hamcrest.Matchers.not; 35 36 import android.app.Activity; 37 import android.app.Instrumentation.ActivityResult; 38 import android.content.Context; 39 import android.content.Intent; 40 import androidx.test.espresso.IdlingRegistry; 41 import androidx.test.espresso.action.ViewActions; 42 import androidx.test.espresso.idling.CountingIdlingResource; 43 import androidx.test.espresso.intent.Intents; 44 import androidx.test.ext.junit.rules.ActivityScenarioRule; 45 import androidx.test.ext.junit.runners.AndroidJUnit4; 46 import com.android.car.debuggingrestrictioncontroller.ui.login.LoginActivity; 47 import com.android.car.debuggingrestrictioncontroller.ui.token.TokenActivity; 48 import com.google.firebase.auth.FirebaseAuth; 49 import org.junit.After; 50 import org.junit.Before; 51 import org.junit.Rule; 52 import org.junit.Test; 53 import org.junit.runner.RunWith; 54 55 @RunWith(AndroidJUnit4.class) 56 public class LoginTest { 57 58 private static final String TEST_EMAIL = BuildConfig.DRC_TEST_EMAIL; 59 private static final String TEST_PASSWORD = BuildConfig.DRC_TEST_PASSWORD; 60 private static final String INVALID_EMAIL = "invalid_email@"; 61 private static final String SHORT_PASSWORD = "word"; 62 private static final String WRONG_PASSWORD = "wrong_password"; 63 private final FirebaseAuth firebaseAuth = FirebaseAuth.getInstance(); 64 65 @Rule 66 public ActivityScenarioRule<LoginActivity> activityScenarioRule = 67 new ActivityScenarioRule<LoginActivity>(LoginActivity.class); 68 69 private CountingIdlingResource idlingResource; 70 71 @Before setUp()72 public void setUp() { 73 activityScenarioRule 74 .getScenario() 75 .onActivity( 76 activity -> { 77 idlingResource = activity.getIdlingResource(); 78 }); 79 IdlingRegistry.getInstance().register(idlingResource); 80 Intents.init(); 81 firebaseAuth.signOut(); 82 } 83 84 @After tearDown()85 public void tearDown() { 86 IdlingRegistry.getInstance().unregister(idlingResource); 87 Intents.release(); 88 firebaseAuth.signOut(); 89 } 90 91 @Test invalidEmail()92 public void invalidEmail() { 93 Context ctx = getApplicationContext(); 94 onView(withId(R.id.username)).perform(typeText(INVALID_EMAIL), ViewActions.closeSoftKeyboard()); 95 onView(withId(R.id.username)) 96 .check(matches(hasErrorText(ctx.getString(R.string.invalid_username)))); 97 onView(withId(R.id.login)).check(matches(not(isEnabled()))); 98 } 99 100 @Test invalidPassword()101 public void invalidPassword() { 102 Context ctx = getApplicationContext(); 103 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 104 onView(withId(R.id.password)) 105 .perform(typeText(SHORT_PASSWORD), ViewActions.closeSoftKeyboard()); 106 onView(withId(R.id.password)) 107 .check(matches(hasErrorText(ctx.getString(R.string.invalid_password)))); 108 onView(withId(R.id.login)).check(matches(not(isEnabled()))); 109 } 110 111 @Test initialButtonStates()112 public void initialButtonStates() { 113 onView(withId(R.id.login)).check(matches(isDisplayed())); 114 onView(withId(R.id.login)).check(matches(not(isEnabled()))); 115 onView(withId(R.id.next)).check(matches(isDisplayed())); 116 onView(withId(R.id.next)).check(matches(not(isEnabled()))); 117 } 118 119 @Test wrongPassword()120 public void wrongPassword() { 121 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 122 onView(withId(R.id.password)) 123 .perform(typeText(WRONG_PASSWORD), ViewActions.pressImeActionButton()); 124 onView(withId(R.id.next)).check(matches(not(isEnabled()))); 125 firebaseAuth.signOut(); 126 } 127 128 @Test userLogout()129 public void userLogout() { 130 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 131 onView(withId(R.id.password)).perform(typeText(TEST_PASSWORD), ViewActions.closeSoftKeyboard()); 132 133 onView(withId(R.id.login)).check(matches(isEnabled())); 134 onView(withId(R.id.login)).check(matches(withText(R.string.button_sign_in))); 135 onView(withId(R.id.login)).perform(click()); 136 onView(withId(R.id.login)).check(matches(isEnabled())); 137 onView(withId(R.id.login)).check(matches(withText(R.string.button_sign_out))); 138 onView(withId(R.id.login)).perform(click()); 139 onView(withId(R.id.login)).check(matches(isEnabled())); 140 onView(withId(R.id.login)).check(matches(withText(R.string.button_sign_in))); 141 firebaseAuth.signOut(); 142 } 143 144 @Test startTokenActivity()145 public void startTokenActivity() { 146 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 147 onView(withId(R.id.password)).perform(typeText(TEST_PASSWORD), ViewActions.closeSoftKeyboard()); 148 149 onView(withId(R.id.login)).check(matches(isEnabled())); 150 onView(withId(R.id.login)).perform(click()); 151 onView(withId(R.id.next)).check(matches(isEnabled())); 152 onView(withId(R.id.next)).perform(click()); 153 154 intended( 155 allOf( 156 toPackage(getApplicationContext().getPackageName()), 157 hasComponent(TokenActivity.class.getName()))); 158 onView(withId(R.id.agreement)).check(matches(isDisplayed())); 159 onView(withId(R.id.agree)).check(matches(isDisplayed())); 160 onView(withId(R.id.disagree)).check(matches(isDisplayed())); 161 firebaseAuth.signOut(); 162 } 163 164 @Test returnedFromTokenActivityOK()165 public void returnedFromTokenActivityOK() { 166 Intent intent = new Intent(getApplicationContext(), TokenActivity.class); 167 ActivityResult result = new ActivityResult(Activity.RESULT_OK, intent); 168 intending( 169 allOf( 170 toPackage(getApplicationContext().getPackageName()), 171 hasComponent(TokenActivity.class.getName()))) 172 .respondWith(result); 173 174 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 175 onView(withId(R.id.password)).perform(typeText(TEST_PASSWORD), ViewActions.closeSoftKeyboard()); 176 177 onView(withId(R.id.login)).check(matches(isEnabled())); 178 onView(withId(R.id.login)).perform(click()); 179 onView(withId(R.id.next)).check(matches(isEnabled())); 180 onView(withId(R.id.next)).perform(click()); 181 182 onView(withId(com.google.android.material.R.id.snackbar_text)) 183 .check(matches(withText(R.string.token_authorized))); 184 firebaseAuth.signOut(); 185 } 186 187 @Test returnedFromTokenActivityCancelled()188 public void returnedFromTokenActivityCancelled() { 189 Intent intent = new Intent(getApplicationContext(), TokenActivity.class); 190 ActivityResult result = new ActivityResult(Activity.RESULT_CANCELED, intent); 191 intending( 192 allOf( 193 toPackage(getApplicationContext().getPackageName()), 194 hasComponent(TokenActivity.class.getName()))) 195 .respondWith(result); 196 197 onView(withId(R.id.username)).perform(typeText(TEST_EMAIL), ViewActions.closeSoftKeyboard()); 198 onView(withId(R.id.password)).perform(typeText(TEST_PASSWORD), ViewActions.closeSoftKeyboard()); 199 200 onView(withId(R.id.login)).check(matches(isEnabled())); 201 onView(withId(R.id.login)).perform(click()); 202 onView(withId(R.id.next)).check(matches(isEnabled())); 203 onView(withId(R.id.next)).perform(click()); 204 205 onView(withId(com.google.android.material.R.id.snackbar_text)) 206 .check(matches(withText(R.string.token_unauthorized))); 207 firebaseAuth.signOut(); 208 } 209 } 210