/* * Copyright 2016 Kejun Xia * * 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.shipdream.lib.android.mvc.samples.simple.mvp.view; import android.content.Intent; import android.support.test.espresso.matcher.ViewMatchers; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.LargeTest; import com.shipdream.lib.android.mvc.Mvc; import com.shipdream.lib.android.mvc.MvcComponent; import com.shipdream.lib.android.mvc.NavigationManager; import com.shipdream.lib.android.mvc.samples.simple.mvp.MainActivity; import com.shipdream.lib.android.mvc.samples.simple.mvp.R; import com.shipdream.lib.android.mvc.samples.simple.mvp.dto.IpPayload; import com.shipdream.lib.android.mvc.samples.simple.mvp.factory.ServiceFactory; import com.shipdream.lib.android.mvc.samples.simple.mvp.http.IpService; import com.shipdream.lib.poke.Provides; import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import java.io.IOException; import javax.inject.Inject; import retrofit2.Call; import retrofit2.Response; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; 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.withEffectiveVisibility; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @RunWith(AndroidJUnit4.class) @LargeTest public class TestMasterScreen { private MvcComponent testComponent; private Call<IpPayload> ipServiceCallMock; @Inject private NavigationManager navigationManager; @Rule public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>( MainActivity.class, false, // initialTouchMode false); // launchActivity. False to set intent per test); @Before public void prepareInjection() throws Exception { testComponent = new MvcComponent("TestComponent"); testComponent.register(new Object(){ /** * Prepare objects to mock http calls * @return * @throws IOException */ @Provides public ServiceFactory serviceFactory() throws IOException { ipServiceCallMock = mock(Call.class); IpService ipServiceMock = mock(IpService.class); when(ipServiceMock.getIp(anyString())).thenReturn(ipServiceCallMock); ServiceFactory serviceFactoryMock = mock(ServiceFactory.class); when(serviceFactoryMock.createService(IpService.class)).thenReturn(ipServiceMock); return serviceFactoryMock; } }); boolean overriding = true; Mvc.graph().getRootComponent().attach(testComponent, overriding); Mvc.graph().inject(this); rule.launchActivity(new Intent()); } @After public void tearDown() throws Exception { //Important!!! //To clear fragment manager's back stack navigationManager.navigate(this).back(null); navigationManager.navigate(this).back(); //Remove overriding component Mvc.graph().getRootComponent().detach(testComponent); } @Test public void should_be_able_to_increment_and_decrement_count() { //Initial value is 0 onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("0"))); //Click increment and check text view value onView(withId(R.id.screen_master_buttonIncrement)).perform(click()); onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("1"))); //Click decrement and check text view value onView(withId(R.id.screen_master_buttonDecrement)).perform(click()); onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("0"))); } @Test public void should_carry_count_to_detail_screen() { //Initial value is 0 onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("0"))); //Click increment and check text view value onView(withId(R.id.screen_master_buttonIncrement)).perform(click()); onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("1"))); //Navigate to detail screen onView(withId(R.id.fragment_master_buttonShowDetailScreen)).perform(click()); //Check count on detail screen onView(withId(R.id.screen_detail_counterDisplay)).check(matches(withText("1"))); //Click decrement and check text view value onView(withId(R.id.screen_detail_buttonIncrement)).perform(click()); onView(withId(R.id.screen_detail_counterDisplay)).check(matches(withText("2"))); navigationManager.navigate(this).back(); onView(withId(R.id.screen_master_counterDisplay)).check(matches(withText("2"))); } @Test public void should_be_able_to_get_ip() throws Exception{ //Pre check onView(withId(R.id.fragment_master_ipValue)).check( matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); final String fakeIpResult = "abc.123.456.xyz"; IpPayload payload = mock(IpPayload.class); when(payload.getIp()).thenReturn(fakeIpResult); when(ipServiceCallMock.execute()).thenReturn(Response.success(payload)); //Action onView(withId(R.id.fragment_master_ipRefresh)).perform(click()); //Check value onView(withId(R.id.fragment_master_ipValue)).check(matches(withText(fakeIpResult))); } @Test public void should_be_able_to_show_network_error_when_getting_ip_failed() throws Exception{ //Pre check onView(withId(R.id.fragment_master_ipValue)).check( matches(withEffectiveVisibility(ViewMatchers.Visibility.INVISIBLE))); //Prepare //Throw an IOException to simulate an network error IOException ioExceptionMock = mock(IOException.class); when(ipServiceCallMock.execute()).thenThrow(ioExceptionMock); //Action onView(withId(R.id.fragment_master_ipRefresh)).perform(click()); //Check value onView(withText(R.string.network_error_to_get_ip)).inRoot( withDecorView(not(is(rule.getActivity().getWindow().getDecorView())))) .check(matches(isDisplayed())); } }