package com.artemzin.qualitymatters.ui.presenters; import com.artemzin.qualitymatters.api.entities.Item; import com.artemzin.qualitymatters.models.AnalyticsModel; import com.artemzin.qualitymatters.models.ItemsModel; import com.artemzin.qualitymatters.performance.AsyncJob; import com.artemzin.qualitymatters.performance.AsyncJobsObserver; import com.artemzin.qualitymatters.ui.views.ItemsView; import org.junit.Before; import org.junit.Test; import java.util.List; import rx.Single; import rx.schedulers.Schedulers; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyListOf; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; public class ItemsPresenterTest { private ItemsModel itemsModel; private ItemsPresenterConfiguration presenterConfiguration; private ItemsPresenter itemsPresenter; private ItemsView itemsView; private AsyncJobsObserver asyncJobsObserver; private AsyncJob asyncJob; @Before public void beforeEachTest() { itemsModel = mock(ItemsModel.class); presenterConfiguration = ItemsPresenterConfiguration.builder() .ioScheduler(Schedulers.immediate()) // We don't need async behavior in tests. .build(); asyncJobsObserver = mock(AsyncJobsObserver.class); asyncJob = mock(AsyncJob.class); when(asyncJobsObserver.asyncJobStarted("Reload data in ItemsPresenter")).thenReturn(asyncJob); itemsPresenter = new ItemsPresenter(presenterConfiguration, itemsModel, asyncJobsObserver, mock(AnalyticsModel.class)); itemsView = mock(ItemsView.class); } @Test public void reloadData_shouldMoveViewToLoadingState() { itemsPresenter.bindView(itemsView); verifyZeroInteractions(itemsView, asyncJobsObserver); when(itemsModel.getItems()).thenReturn(Single.just(emptyList())); itemsPresenter.reloadData(); verify(itemsView).showLoadingUi(); verify(asyncJobsObserver).asyncJobStarted("Reload data in ItemsPresenter"); verify(asyncJobsObserver).asyncJobFinished(asyncJob); } @Test public void reloadData_shouldSendDataToTheView() { itemsPresenter.bindView(itemsView); verifyZeroInteractions(itemsView, asyncJobsObserver); List<Item> items = asList( Item.builder().id("1").imagePreviewUrl("i1").title("t1").shortDescription("s1").build(), Item.builder().id("2").imagePreviewUrl("i2").title("t2").shortDescription("s2").build() ); when(itemsModel.getItems()).thenReturn(Single.just(items)); itemsPresenter.reloadData(); verify(itemsView).showContentUi(items); verify(itemsView, never()).showErrorUi(any(Throwable.class)); verify(asyncJobsObserver).asyncJobStarted("Reload data in ItemsPresenter"); verify(asyncJobsObserver).asyncJobFinished(asyncJob); } @Test public void reloadData_shouldSendErrorToTheView() { itemsPresenter.bindView(itemsView); verifyZeroInteractions(itemsView, asyncJobsObserver); Throwable error = new RuntimeException(); when(itemsModel.getItems()).thenReturn(Single.error(error)); itemsPresenter.reloadData(); verify(itemsView).showErrorUi(error); verify(itemsView, never()).showContentUi(anyListOf(Item.class)); verify(asyncJobsObserver).asyncJobStarted("Reload data in ItemsPresenter"); verify(asyncJobsObserver).asyncJobFinished(asyncJob); } }