/*
* Copyright 2016 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.agera.basicsample;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.RootMatchers.withDecorView;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.not;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.GeneralLocation;
import android.support.test.espresso.action.GeneralSwipeAction;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Swipe;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.LargeTest;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Tests for the main screen, which shows a list of usernames or an error message if the list
* data couldn't be obtained.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class MainActivityTest {
/**
* {@link ActivityTestRule} is a JUnit {@link Rule @Rule} to launch your activity under test.
* <p>
* Rules are interceptors which are executed for each test method and are important building
* blocks of Junit tests.
*/
@Rule
public ActivityTestRule<MainActivity> activityTestRule =
new ActivityTestRule<>(MainActivity.class);
/**
* A custom {@link Matcher} which matches a {@link ListView} by its size.
* <p>
* View constraints:
* <ul>
* <li>View must be a {@link ListView}
* <ul>
*
* @param size the expected size of the list
* @return Matcher that matches size of the given {@link ListView}
*/
private static Matcher<View> withListSize(final int size) {
return new TypeSafeMatcher<View>() {
@Override
public boolean matchesSafely(final View view) {
return ((ListView) view).getChildCount() == size;
}
@Override
public void describeTo(final Description description) {
description.appendText("ListView should have " + size + " items");
}
};
}
@Before
public void setUp() {
// Username fetcher in a state of returning 4 usernames
UsernamesFetcher.NUMBER_OF_USERS = 4;
}
@After
public void cleanUp() {
// Username fetcher in a state of returning 4 usernames
UsernamesFetcher.NUMBER_OF_USERS = 4;
}
@Test
public void firstLoad_showsList() {
// Then the correct number of usernames is displayed
onView(withId(R.id.list)).check(matches(withListSize(UsernamesFetcher.NUMBER_OF_USERS)));
}
@Test
public void refreshError_showsErrorAndPreviousList() {
// Given a list of usernames loaded
String firstUsername =
((TextView) ((ListView) activityTestRule.getActivity()
.findViewById(R.id.list)).getChildAt(0)).getText().toString();
// Given a username fetcher in a state of error
UsernamesFetcher.NUMBER_OF_USERS = -1;
// When pulled down to refresh is triggered
onView(withId(R.id.fragment)).perform(swipeDown());
// Then the error toast is shown
onView(withText(R.string.error))
// Required because of the way toasts are displayed
.inRoot(withDecorView(not(is(
activityTestRule.getActivity().getWindow().getDecorView()))))
// Check if it is visible
.check(matches(isDisplayed()));
// And the list is still shown
onView(withText(firstUsername)).check(matches(isDisplayed()));
}
@Test
public void refresh_showsUpdatedList() {
// Given a list of usernames loaded
String firstUsername =
((TextView) ((ListView) activityTestRule.getActivity()
.findViewById(R.id.list)).getChildAt(0)).getText().toString();
// Given a username fetcher in a state of returning 5 usernames
UsernamesFetcher.NUMBER_OF_USERS = 5;
// When pulled down to refresh is triggered
onView(withId(R.id.fragment)).perform(swipeDown());
// Then the correct number of usernames is displayed
onView(withId(R.id.list)).check(matches(withListSize(UsernamesFetcher.NUMBER_OF_USERS)));
}
private static ViewAction swipeDown() {
return new GeneralSwipeAction(Swipe.FAST, GeneralLocation.TOP_CENTER,
GeneralLocation.BOTTOM_CENTER, Press.FINGER);
}
}