package io.github.hidroh.materialistic.data;
import android.content.ContentResolver;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import io.github.hidroh.materialistic.test.TestRunner;
import org.robolectric.RuntimeEnvironment;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;
import dagger.Module;
import dagger.ObjectGraph;
import dagger.Provides;
import rx.Observable;
import rx.schedulers.Schedulers;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(TestRunner.class)
public class HackerNewsClientTest {
@Inject RestServiceFactory factory;
@Inject SessionManager sessionManager;
@Inject FavoriteManager favoriteManager;
private HackerNewsClient client;
@Captor ArgumentCaptor<Item[]> getStoriesResponse;
private ResponseListener<Item> itemListener;
private ResponseListener<UserManager.User> userListener;
private ResponseListener<Item[]> storiesListener;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
ObjectGraph.create(new TestModule()).inject(this);
reset(TestRestServiceFactory.hnRestService);
reset(sessionManager);
reset(favoriteManager);
client = new HackerNewsClient(RuntimeEnvironment.application, factory, sessionManager,
favoriteManager, Schedulers.immediate());
itemListener = mock(ResponseListener.class);
storiesListener = mock(ResponseListener.class);
userListener = mock(ResponseListener.class);
}
@Test
public void testGetItemNoListener() {
client.getItem("1", ItemManager.MODE_DEFAULT, null);
verify(TestRestServiceFactory.hnRestService, never()).itemRx(any());
}
@Test
public void testGetItemSuccess() {
HackerNewsItem hnItem = mock(HackerNewsItem.class);
when(TestRestServiceFactory.hnRestService.itemRx(eq("1")))
.thenReturn(Observable.just(hnItem));
when(sessionManager.isViewed(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(false));
when(favoriteManager.check(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(false));
client.getItem("1", ItemManager.MODE_DEFAULT, itemListener);
verify(TestRestServiceFactory.hnRestService).itemRx(eq("1"));
verify(sessionManager).isViewed(any(ContentResolver.class), eq("1"));
verify(favoriteManager).check(any(ContentResolver.class), eq("1"));
verify(itemListener).onResponse(eq(hnItem));
}
@Test
public void testGetItemForceNetwork() {
client.getItem("1", ItemManager.MODE_NETWORK, itemListener);
verify(TestRestServiceFactory.hnRestService).networkItemRx(eq("1"));
}
@Test
public void testGetItemForceCache() {
HackerNewsItem hnItem = mock(HackerNewsItem.class);
when(TestRestServiceFactory.hnRestService.cachedItemRx(eq("1")))
.thenReturn(Observable.just(hnItem));
when(sessionManager.isViewed(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(false));
when(favoriteManager.check(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(false));
client.getItem("1", ItemManager.MODE_CACHE, itemListener);
verify(TestRestServiceFactory.hnRestService).cachedItemRx(eq("1"));
verify(sessionManager).isViewed(any(ContentResolver.class), eq("1"));
verify(favoriteManager).check(any(ContentResolver.class), eq("1"));
verify(itemListener).onResponse(eq(hnItem));
}
@Test
public void testGetItemForceCacheUnsatisfiable() {
when(TestRestServiceFactory.hnRestService.cachedItemRx(eq("1")))
.thenReturn(Observable.error(new IOException()));
when(TestRestServiceFactory.hnRestService.itemRx(eq("1")))
.thenReturn(Observable.just(mock(HackerNewsItem.class)));
client.getItem("1", ItemManager.MODE_CACHE, itemListener);
verify(TestRestServiceFactory.hnRestService).cachedItemRx(eq("1"));
verify(TestRestServiceFactory.hnRestService).itemRx(eq("1"));
}
@Test
public void testGetItemFailure() {
when(TestRestServiceFactory.hnRestService.itemRx(eq("1")))
.thenReturn(Observable.error(new Throwable("message")));
when(sessionManager.isViewed(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(true));
when(favoriteManager.check(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(true));
client.getItem("1", ItemManager.MODE_DEFAULT, itemListener);
verify(favoriteManager).check(any(ContentResolver.class), eq("1"));
verify(sessionManager).isViewed(any(ContentResolver.class), eq("1"));
verify(TestRestServiceFactory.hnRestService).itemRx(eq("1"));
verify(itemListener).onError(eq("message"));
}
@Test
public void testGetItemFailureNoMessage() {
when(TestRestServiceFactory.hnRestService.itemRx(eq("1")))
.thenReturn(Observable.error(new Throwable("")));
when(sessionManager.isViewed(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(true));
when(favoriteManager.check(any(ContentResolver.class), eq("1")))
.thenReturn(Observable.just(true));
client.getItem("1", ItemManager.MODE_DEFAULT, itemListener);
verify(sessionManager).isViewed(any(ContentResolver.class), eq("1"));
verify(favoriteManager).check(any(ContentResolver.class), eq("1"));
verify(TestRestServiceFactory.hnRestService).itemRx(eq("1"));
verify(itemListener).onError(eq(""));
}
@Test
public void testGetStoriesNoListener() {
client.getStories(ItemManager.TOP_FETCH_MODE, ItemManager.MODE_DEFAULT, null);
verify(TestRestServiceFactory.hnRestService, never()).topStoriesRx();
}
@Test
public void testGetTopStoriesSuccess() {
when(TestRestServiceFactory.hnRestService.topStoriesRx())
.thenReturn(Observable.just(new int[]{1, 2}));
client.getStories(ItemManager.TOP_FETCH_MODE, ItemManager.MODE_DEFAULT, storiesListener);
verify(TestRestServiceFactory.hnRestService).topStoriesRx();
verify(storiesListener).onResponse(getStoriesResponse.capture());
assertThat(getStoriesResponse.getValue()).hasSize(2);
}
@Test
public void testGetNewStoriesNull() {
when(TestRestServiceFactory.hnRestService.newStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.NEW_FETCH_MODE, ItemManager.MODE_DEFAULT, storiesListener);
verify(TestRestServiceFactory.hnRestService).newStoriesRx();
verify(storiesListener).onResponse(getStoriesResponse.capture());
assertThat(getStoriesResponse.getValue()).isNullOrEmpty();
}
@Test
public void testGetAskEmpty() {
when(TestRestServiceFactory.hnRestService.askStoriesRx())
.thenReturn(Observable.just(new int[0]));
client.getStories(ItemManager.ASK_FETCH_MODE, ItemManager.MODE_DEFAULT, storiesListener);
verify(TestRestServiceFactory.hnRestService).askStoriesRx();
verify(storiesListener).onResponse(getStoriesResponse.capture());
assertThat(getStoriesResponse.getValue()).isEmpty();
}
@Test
public void testGetShowFailure() {
when(TestRestServiceFactory.hnRestService.showStoriesRx())
.thenReturn(Observable.error(new Throwable("message")));
client.getStories(ItemManager.SHOW_FETCH_MODE, ItemManager.MODE_DEFAULT, storiesListener);
verify(TestRestServiceFactory.hnRestService).showStoriesRx();
verify(storiesListener).onError(eq("message"));
}
@Test
public void testGetStoriesForceNetwork() {
when(TestRestServiceFactory.hnRestService.networkTopStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.TOP_FETCH_MODE, ItemManager.MODE_NETWORK, storiesListener);
verify(TestRestServiceFactory.hnRestService).networkTopStoriesRx();
when(TestRestServiceFactory.hnRestService.networkNewStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.NEW_FETCH_MODE, ItemManager.MODE_NETWORK, storiesListener);
verify(TestRestServiceFactory.hnRestService).networkNewStoriesRx();
when(TestRestServiceFactory.hnRestService.networkAskStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.ASK_FETCH_MODE, ItemManager.MODE_NETWORK, storiesListener);
verify(TestRestServiceFactory.hnRestService).networkAskStoriesRx();
when(TestRestServiceFactory.hnRestService.networkJobStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.JOBS_FETCH_MODE, ItemManager.MODE_NETWORK, storiesListener);
verify(TestRestServiceFactory.hnRestService).networkJobStoriesRx();
when(TestRestServiceFactory.hnRestService.networkShowStoriesRx())
.thenReturn(Observable.just(null));
client.getStories(ItemManager.SHOW_FETCH_MODE, ItemManager.MODE_NETWORK, storiesListener);
verify(TestRestServiceFactory.hnRestService).networkShowStoriesRx();
}
@Test
public void testGetUserNoListener() {
client.getUser("username", null);
verify(TestRestServiceFactory.hnRestService, never()).userRx(any());
}
@Test
public void testGetUserSuccess() {
UserItem hnUser = mock(UserItem.class);
when(TestRestServiceFactory.hnRestService.userRx(eq("username")))
.thenReturn(Observable.just(hnUser));
client.getUser("username", userListener);
verify(TestRestServiceFactory.hnRestService).userRx(eq("username"));
verify(userListener).onResponse(eq(hnUser));
}
@Test
public void testGetUserNull() {
when(TestRestServiceFactory.hnRestService.userRx(eq("username")))
.thenReturn(Observable.just(null));
client.getUser("username", userListener);
verify(TestRestServiceFactory.hnRestService).userRx(eq("username"));
verify(userListener).onResponse((UserManager.User) isNull());
}
@Test
public void testGetUserFailure() {
when(TestRestServiceFactory.hnRestService.userRx(eq("username")))
.thenReturn(Observable.error(new Throwable("message")));
client.getUser("username", userListener);
verify(TestRestServiceFactory.hnRestService).userRx(eq("username"));
verify(userListener).onError(eq("message"));
}
@Module(
injects = HackerNewsClientTest.class,
overrides = true
)
static class TestModule {
@Provides
@Singleton
public RestServiceFactory provideRestServiceFactory() {
return new TestRestServiceFactory();
}
@Provides
@Singleton
public SessionManager provideSessionManager() {
return mock(SessionManager.class);
}
@Provides
@Singleton
public FavoriteManager provideFavoriteManager() {
return mock(FavoriteManager.class);
}
}
}