package com.mairos.twisterblog;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.IdlingResource;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.runner.AndroidJUnit4;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
import com.mairos.twisterblog.model.Post;
import com.mairos.twisterblog.network.RequestStatusObject;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.Espresso.registerIdlingResources;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.pressBack;
import static android.support.test.espresso.action.ViewActions.swipeRight;
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.isRoot;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static com.android.support.test.deps.guava.base.Preconditions.checkNotNull;
/**
* Created by Mike on 10.01.2015.
*/
@RunWith(AndroidJUnit4.class)
@LargeTest
// FIXME - anyway, ordering looks like pretty bicycle
@FixMethodOrder
public class PostsPageTest extends ActivityInstrumentationTestCase2<MainActivity_> {
private MainActivity_ mActivity;
private RequestStatusIdlingResource mRequestIR;
private static final SimpleDateFormat form = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static final Post sTestPost = new Post(12345, "post from espresso " + form.format(new Date()),
"post created from espresso testing library", "created_at", "updated_at");
@SuppressWarnings("deprecation")
public PostsPageTest() {
// This constructor was deprecated - but we want to support lower API levels.
super(MainActivity_.class);
}
@Before
public void setUp() throws Exception {
super.setUp();
// TODO
// no need to check network operations here - already done at NetworkRequestsTest
// so it's a good idea to use https://github.com/square/okhttp/tree/master/mockwebserver here
// may be with https://github.com/square/dagger/ to inject it in UI
// As the way to access Instrumentation is changed in the new runner, we need to inject it
// manually into ActivityInstrumentationTestCase2.
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
// Espresso will not launch our activity for us, we must launch it via getActivity().
mActivity = getActivity();
// in order to synchronize
RequestStatusObject rso = RequestStatusObject.getInstance();
mRequestIR = new RequestStatusIdlingResource(rso);
registerIdlingResources(mRequestIR);
}
@Test
public void testAddPost() throws IOException {
onView(withId(R.id.action_add))
.perform(click());
onView(withId(R.id.button_add))
.check(matches(withText("add post")));
onView(withId(R.id.text_title))
.perform(typeText(sTestPost.title));
onView(withId(R.id.text_body))
.perform(typeText(sTestPost.body));
onView(withId(R.id.button_add))
.perform(click());
// TODO write correct matcher
// https://code.google.com/p/android-test-kit/wiki/EspressoSamples#Asserting_that_a_data_item_is_not_in_an_adapter
onView(Matchers.allOf(ViewMatchers.withId(R.id.text_title),
ViewMatchers.hasSibling(ViewMatchers.withText(sTestPost.title))))
.check(matches(withText(sTestPost.title)));
}
@Test
public void testPostsListClick() throws IOException {
onView(Matchers.allOf(ViewMatchers.withId(R.id.text_title),
ViewMatchers.hasSibling(ViewMatchers.withText(sTestPost.title)))).perform(click());
onView(withId(R.id.post_content))
.check(matches(withText(sTestPost.body)));
onView(isRoot()).perform(pressBack());
}
@Test
public void testRemovePost() throws IOException {
onView(Matchers.allOf(ViewMatchers.withId(R.id.text_title),
ViewMatchers.hasSibling(ViewMatchers.withText(sTestPost.title)))).perform(swipeRight());
// 3000 delay in EnhancedListView before network "delete post" request
mRequestIR.lock();
onView(withText(sTestPost.title))
.check(doesNotExist());
}
@After
public void tearDown() throws Exception {
// Make sure that we call the tearDown() method of ActivityInstrumentationTestCase2
// to clean up and not leak any objects.
super.tearDown();
}
private class RequestStatusIdlingResource implements IdlingResource,
RequestStatusObject.RequestStatusChange {
private RequestStatusObject mState;
private ResourceCallback mCallback;
public RequestStatusIdlingResource(RequestStatusObject status) {
mState = checkNotNull(status);
}
@Override
public String getName() {
return "is request finished";
}
@Override
public boolean isIdleNow() {
return !mState.getState().equals(RequestStatusObject.IN_PROCESS);
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
mCallback = resourceCallback;
mState.setResourceCallback(this);
}
@Override
public void onChange() {
mCallback.onTransitionToIdle();
}
public void lock() {
mState.setStarted();
}
}
}