package com.zedeff.twittererer.ui.activities; import android.support.test.InstrumentationRegistry; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import com.zedeff.twittererer.App; import com.zedeff.twittererer.DaggerMockApplicationComponent; import com.zedeff.twittererer.MockApplicationModule; import com.zedeff.twittererer.R; import com.zedeff.twittererer.models.TimelineItem; import com.zedeff.twittererer.models.User; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.util.ArrayList; import java.util.List; import rx.Observable; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.pressImeActionButton; import static android.support.test.espresso.action.ViewActions.swipeDown; import static android.support.test.espresso.action.ViewActions.typeText; import static android.support.test.espresso.assertion.ViewAssertions.doesNotExist; import static android.support.test.espresso.assertion.ViewAssertions.matches; 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.mockito.Matchers.anyString; import static org.mockito.Mockito.when; /** * UI tests using Espresso * <p> * I prefer to use a test environment whenever I can, instead of mocking the API. * In case of Twitter the API calls have to be mocked. * <p> * Another difficulty is that log in with Twitter cannot be done with Espresso */ @RunWith(AndroidJUnit4.class) public class TimelineActivityTest { private List<TimelineItem> timelineItems; @Rule public ActivityTestRule<TimelineActivity> activityTestRule = new ActivityTestRule<TimelineActivity>(TimelineActivity.class) { @Override protected void beforeActivityLaunched() { super.beforeActivityLaunched(); App.BaseApplicationComponent component = DaggerMockApplicationComponent.builder() .mockApplicationModule(new MockApplicationModule((App) InstrumentationRegistry.getTargetContext().getApplicationContext())) .build(); App.overrideComponent(component); User bobUser = new User("Bob", "bob", "http://assets.rollingstone.com/assets/images/list_item/bob-marley-20110420/square.jpg"); when(component.twitterService().getMyDetails()).thenReturn(Observable.just(bobUser)); timelineItems = new ArrayList<>(); timelineItems.add(new TimelineItem("10m", "hello", bobUser)); when(component.twitterService().getTimelineItems()).thenReturn(Observable.just(timelineItems)); when(component.twitterService().getCurrentUser()).thenReturn(bobUser); when(component.twitterService().sendTweet(anyString())).thenReturn(Observable.just(true)); } }; @Test public void canSeeTimelineWhenThereAreTweets() { onView(withText(R.string.title_activity_twitter_feed)) .check(matches(isDisplayed())); onView(withText("Bob")) .check(matches(isDisplayed())); onView(withText("@bob")) .check(matches(isDisplayed())); onView(withText("10m")) .check(matches(isDisplayed())); onView(withText("hello")) .check(matches(isDisplayed())); } @Test public void refreshTweets() { onView(withText("Bob")) .check(matches(isDisplayed())); onView(withText("Richie Rich")) .check(doesNotExist()); //noinspection SpellCheckingInspection timelineItems.add(new TimelineItem("5s", "boo", new User("Richie Rich", "richie-rich", "http://ia.media-imdb.com/images/M/MV5BMTA4NjI0NzE2NjNeQTJeQWpwZ15BbWU4MDU0NzMwNjQx._V1_SY317_CR6,0,214,317_AL_.jpg"))); onView(withId(R.id.swipe_refresh)) .perform(swipeDown()); onView(withText("Bob")) .check(matches(isDisplayed())); onView(withText("Richie Rich")) .check(matches(isDisplayed())); onView(withText("@richie-rich")) .check(matches(isDisplayed())); onView(withText("5s")) .check(matches(isDisplayed())); onView(withText("boo")) .check(matches(isDisplayed())); } @Test public void seeNoTweetsMessageWhenThereAreNoTweets() { onView(withText(R.string.title_activity_twitter_feed)) .check(matches(isDisplayed())); timelineItems.clear(); onView(withId(R.id.swipe_refresh)) .perform(swipeDown()); onView(withText(R.string.label_no_tweets)) .check(matches(isDisplayed())); } @Test public void sendTweet() throws InterruptedException { onView(withId(R.id.action_tweet)) .perform(click()); String tweetText = "My latest unique tweet with #" + System.currentTimeMillis(); onView(withId(R.id.tweet_text)) .perform(typeText(tweetText), pressImeActionButton()); onView(withText(tweetText)) .check(matches(isDisplayed())); } }