[android] Fix robolectric test after AndroidX migration

This commit is contained in:
Torsten Grote
2019-10-16 17:10:46 -03:00
parent a592c05146
commit 9d31a0a536
4 changed files with 158 additions and 165 deletions

View File

@@ -1,115 +0,0 @@
package org.briarproject.briar.android.account;
import com.google.android.material.textfield.TextInputLayout;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.briarproject.briar.R;
import org.briarproject.briar.android.TestBriarApplication;
import org.briarproject.briar.android.login.StrengthMeter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static junit.framework.Assert.assertEquals;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.NONE;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.support.v4.SupportFragmentTestUtil.startFragment;
@RunWith(RobolectricTestRunner.class)
@Config(sdk = 21, application = TestBriarApplication.class)
public class SetPasswordFragmentTest {
private SetPasswordFragment passwordFragment = new SetPasswordFragment();
private EditText passwordEntry;
private EditText passwordConfirmation;
private TextInputLayout passwordConfirmationWrapper;
private StrengthMeter strengthMeter;
private Button createAccountButton;
@Mock
private SetupController setupController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
startFragment(passwordFragment, SetupActivity.class);
View v = passwordFragment.getView();
passwordEntry = v.findViewById(R.id.password_entry);
passwordConfirmation = v.findViewById(R.id.password_confirm);
passwordConfirmationWrapper =
v.findViewById(R.id.password_confirm_wrapper);
strengthMeter = v.findViewById(R.id.strength_meter);
createAccountButton = v.findViewById(R.id.next);
}
@Test
public void testCreateAccountUI() {
String safePass = "really.safe.password";
passwordFragment.setupController = setupController;
when(setupController.needToShowDozeFragment()).thenReturn(false);
when(setupController.estimatePasswordStrength(safePass))
.thenReturn(STRONG);
passwordEntry.setText(safePass);
passwordConfirmation.setText(safePass);
// Confirm that the create account button is clickable
assertEquals(createAccountButton.isEnabled(), true);
createAccountButton.performClick();
// assert controller has been called properly
verify(setupController, times(1)).setPassword(safePass);
verify(setupController, times(1)).createAccount();
}
@Test
public void testStrengthMeterUI() {
// Test the meters' progress and color for several values
testStrengthMeter("1234567890ab", STRONG, StrengthMeter.GREEN);
testStrengthMeter("123456789", QUITE_STRONG, StrengthMeter.LIME);
testStrengthMeter("123456", QUITE_WEAK, StrengthMeter.YELLOW);
testStrengthMeter("123", WEAK, StrengthMeter.ORANGE);
testStrengthMeter("", NONE, StrengthMeter.RED);
}
private void testStrengthMeter(String pass, float strength, int color) {
passwordEntry.setText(pass);
assertEquals(strengthMeter.getProgress(),
(int) (strengthMeter.getMax() * strength));
assertEquals(color, strengthMeter.getColor());
}
@Test
public void testPasswordMatchUI() {
// Password mismatch
passwordEntry.setText("really.safe.password");
passwordConfirmation.setText("really.safe.pass");
assertEquals(createAccountButton.isEnabled(), false);
assertEquals(passwordConfirmationWrapper.getError(),
passwordFragment.getString(R.string.passwords_do_not_match));
// Button enabled
passwordEntry.setText("really.safe.pass");
passwordConfirmation.setText("really.safe.pass");
// Confirm that the password mismatch error message is not visible
assertNotEquals(passwordConfirmationWrapper.getError(),
passwordFragment.getString(R.string.passwords_do_not_match));
// Passwords match, so button should be enabled
assertEquals(createAccountButton.isEnabled(), true);
}
}

View File

@@ -1,47 +1,147 @@
package org.briarproject.briar.android.account;
import com.google.android.material.textfield.TextInputLayout;
import android.widget.EditText;
import android.view.View;
import org.briarproject.briar.R;
import org.briarproject.briar.android.TestBriarApplication;
import org.junit.Assert;
import org.junit.Before;
import org.briarproject.briar.android.login.StrengthMeter;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static junit.framework.Assert.assertEquals;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.clearText;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.replaceText;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isEnabled;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.NONE;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.WEAK;
import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.bramble.util.StringUtils.getRandomString;
import static org.briarproject.briar.android.login.StrengthMeter.GREEN;
import static org.briarproject.briar.android.login.StrengthMeter.LIME;
import static org.briarproject.briar.android.login.StrengthMeter.ORANGE;
import static org.briarproject.briar.android.login.StrengthMeter.RED;
import static org.briarproject.briar.android.login.StrengthMeter.YELLOW;
import static org.hamcrest.Matchers.not;
@RunWith(RobolectricTestRunner.class)
@RunWith(AndroidJUnit4.class)
@Config(sdk = 21, application = TestBriarApplication.class)
public class SetupActivityTest {
private SetupActivity setupActivity;
private TextInputLayout nicknameEntryWrapper;
private EditText nicknameEntry;
@Rule
public ActivityScenarioRule<SetupActivity> rule =
new ActivityScenarioRule<>(SetupActivity.class);
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
setupActivity = Robolectric.setupActivity(SetupActivity.class);
nicknameEntryWrapper =
setupActivity.findViewById(R.id.nickname_entry_wrapper);
nicknameEntry = setupActivity.findViewById(R.id.nickname_entry);
@Test
public void testNicknameTooLongErrorShown() {
String longNick = getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
onView(withId(R.id.nickname_entry)).perform(typeText(longNick));
// Nickname should be too long
onView(withText(R.string.name_too_long)).check(matches(isDisplayed()));
}
@Test
public void testNicknameUI() {
Assert.assertNotNull(setupActivity);
String longNick = getRandomString(MAX_AUTHOR_NAME_LENGTH + 1);
nicknameEntry.setText(longNick);
// Nickname should be too long
assertEquals(nicknameEntryWrapper.getError(),
setupActivity.getString(R.string.name_too_long));
public void testPasswordMatchUI() {
moveToSetPasswordFragment();
// error shown when passwords don't match, button is disabled
onView(withId(R.id.password_entry)).perform(typeText("123456"));
onView(withId(R.id.password_confirm)).perform(typeText("654321"));
onView(withText(R.string.passwords_do_not_match))
.check(matches(isDisplayed()));
onView(withId(R.id.next)).check(matches(not(isEnabled())));
// confirming correct password, removes error, enables button
onView(withId(R.id.password_confirm)).perform(clearText());
onView(withId(R.id.password_confirm)).perform(replaceText("123456"));
onView(withText(R.string.passwords_do_not_match)).check(doesNotExist());
onView(withId(R.id.next)).check(matches(isEnabled()));
// clicking the button shows progress bar, no doze because SDK_INT==21
onView(withId(R.id.next)).perform(click());
onView(withId(R.id.progress)).check(matches(isDisplayed()));
}
@Test
public void testStrengthMeterUI() {
moveToSetPasswordFragment();
onView(withId(R.id.password_entry)).perform(typeText("1234567890ab"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(STRONG, GREEN)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123456789"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(QUITE_STRONG, LIME)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123456"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(QUITE_WEAK, YELLOW)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.password_entry)).perform(typeText("123"));
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(WEAK, ORANGE)));
onView(withId(R.id.password_entry)).perform(clearText());
onView(withId(R.id.strength_meter))
.check(matches(strengthAndColor(NONE, RED)));
}
private void moveToSetPasswordFragment() {
onView(withId(R.id.nickname_entry)).perform(typeText("test"));
onView(withId(R.id.next)).perform(click());
onView(withId(R.id.password_entry)).check(matches(isDisplayed()));
}
private Matcher<View> strengthAndColor(float strength, int color) {
return new StrengthMeterMatcher(strength, color);
}
static class StrengthMeterMatcher
extends BoundedMatcher<View, StrengthMeter> {
private final float strength;
private final int color;
private StrengthMeterMatcher(float strength, int color) {
super(StrengthMeter.class);
this.strength = strength;
this.color = color;
}
@Override
public void describeTo(Description description) {
description.appendText("is enabled");
}
@Override
public boolean matchesSafely(StrengthMeter view) {
boolean strengthMatches =
view.getProgress() == (int) (view.getMax() * strength);
boolean colorMatches = color == view.getColor();
return strengthMatches && colorMatches;
}
}
}