package com.badoo.chateau.example.ui.chat.messages; import android.support.annotation.NonNull; import com.badoo.chateau.core.model.Conversation; import com.badoo.chateau.core.model.Message; import com.badoo.chateau.core.repos.messages.MessageDataSource; import com.badoo.chateau.core.repos.messages.MessageDataSource.LoadResult; import com.badoo.chateau.core.repos.messages.MessageDataSource.Update; import com.badoo.chateau.core.usecases.conversations.GetConversation; import com.badoo.chateau.core.usecases.conversations.MarkConversationRead; import com.badoo.chateau.core.usecases.istyping.SubscribeToUsersTyping; import com.badoo.chateau.core.usecases.messages.LoadMessages; import com.badoo.chateau.core.usecases.messages.SendMessage; import com.badoo.chateau.core.usecases.messages.SubscribeToMessageUpdates; import com.badoo.chateau.example.data.model.ExampleUser; import com.badoo.chateau.ui.chat.messages.BaseMessageListPresenter; import com.badoo.chateau.ui.chat.messages.MessageListPresenter; import com.badoo.chateau.ui.chat.messages.MessageListPresenter.MessageListView; import com.badoo.unittest.rx.BaseRxTestCase; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; import java.util.Collections; import java.util.List; import rx.Observable; import rx.subjects.PublishSubject; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class BaseMessageListPresenterTest extends BaseRxTestCase { private static final String CONVERSATION_ID = "chatId"; @Mock private MessageListView<TestMessage> mView; @Mock private LoadMessages<TestMessage> mLoadMessages; @Mock private SubscribeToMessageUpdates<TestMessage> mSubscribeToMessageUpdates; @Mock private MarkConversationRead mMarkConversationRead; @Mock private GetConversation<TestConversation> mGetConversation; @Mock private SubscribeToUsersTyping<ExampleUser> mSubscribeToUsersTyping; @Mock private SendMessage<TestMessage> mSendMessage; @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void noUseCasesInvokedFromConstructor() { verifyZeroInteractions(mLoadMessages); verifyZeroInteractions(mSubscribeToMessageUpdates); verifyZeroInteractions(mMarkConversationRead); verifyZeroInteractions(mGetConversation); verifyZeroInteractions(mSubscribeToUsersTyping); } @Test public void messagesRequestedWhenPresenterCreated() { // Given when(mGetConversation.execute(any())).thenReturn(Observable.just(new TestConversation())); when(mLoadMessages.all(eq(CONVERSATION_ID))).thenReturn(Observable.empty()); when(mSubscribeToMessageUpdates.forConversation(any())).thenReturn(Observable.empty()); when(mSubscribeToUsersTyping.execute(any())).thenReturn(Observable.empty()); when(mMarkConversationRead.execute(any())).thenReturn(Observable.empty()); // When MessageListPresenter<TestMessage> target = createPresenter(); target.onStart(); // Then verify(mLoadMessages).all(eq(CONVERSATION_ID)); } public void viewUpdatedWithMessages() { // Given when(mGetConversation.execute(any())).thenReturn(Observable.just(new TestConversation())); List<TestMessage> messages = Collections.singletonList(new TestMessage()); LoadResult<TestMessage> loadResult = new LoadResult<>(messages, false, false); PublishSubject<Update<TestMessage>> updatePublisher = PublishSubject.create(); when(mLoadMessages.all(eq(CONVERSATION_ID))).thenAnswer(invocation -> { return Observable.just(loadResult); }); when(mSubscribeToMessageUpdates.forConversation(eq(CONVERSATION_ID))).thenReturn(updatePublisher); when(mSubscribeToUsersTyping.execute(any())).thenReturn(Observable.empty()); when(mMarkConversationRead.execute(any())).thenReturn(Observable.empty()); // When MessageListPresenter<TestMessage> target = createPresenter(); target.onStart(); // Then verify(mView).showMessages(messages); } @Test public void dontRequestMoreMessagesIfConversationEmpty() { // Given when(mGetConversation.execute(any())).thenReturn(Observable.just(new TestConversation())); Observable<LoadResult<TestMessage>> noMessages = Observable.just(new LoadResult<>(Collections.emptyList(), false, false)); when(mLoadMessages.all(eq(CONVERSATION_ID))).thenReturn(noMessages); when(mSubscribeToMessageUpdates.forConversation(any())).thenReturn(Observable.empty()); when(mSubscribeToUsersTyping.execute(any())).thenReturn(Observable.empty()); when(mMarkConversationRead.execute(any())).thenReturn(Observable.empty()); // When MessageListPresenter<TestMessage> target = createPresenter(); target.onStart(); target.onMoreMessagesRequired(); // Then verify(mLoadMessages, times(1)).all(eq(CONVERSATION_ID)); // Requested once in onCreate } @NonNull private MessageListPresenter<TestMessage> createPresenter() { return new BaseMessageListPresenter<>(CONVERSATION_ID, mView, mLoadMessages, mSubscribeToMessageUpdates, mMarkConversationRead, mSendMessage); } private static class TestMessage implements Message { } private static class TestConversation implements Conversation { } }