/*
* Copyright (c) 2016 Google Inc.
*
* 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.google.samples.apps.iosched.archframework;
import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static com.google.samples.apps.iosched.archframework.ArchFrameworkHelperForTest
.createQueryEnumWithId;
import static com.google.samples.apps.iosched.archframework.ArchFrameworkHelperForTest
.createUserActionEnumWithId;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
@SmallTest
public class PresenterImplTest {
@Mock
private Model mMockModel;
@Mock
private UpdatableView mMockUpdatableView1;
@Mock
private UpdatableView mMockUpdatableView2;
private UpdatableView[] mMockUpdatableViews;
@Captor
private ArgumentCaptor<Model.DataQueryCallback> mDataQueryCallbackCaptor;
@Captor
private ArgumentCaptor<Model.UserActionCallback> mUserActionCallbackCaptor;
@Rule
public ExpectedException mThrown = ExpectedException.none();
private UserActionEnum[] mUserActions;
private QueryEnum[] mQueries;
private PresenterImpl mPresenterImpl;
@Before
public void setUp() {
// A presenter with one query with id 1 and one user action with id 1
mQueries = new QueryEnum[1];
mQueries[0] = createQueryEnumWithId(1);
mUserActions = new UserActionEnum[1];
mUserActions[0] = createUserActionEnumWithId(1);
// A presenter with 2 views
mMockUpdatableViews = new UpdatableView[]{mMockUpdatableView1, mMockUpdatableView2};
mPresenterImpl = new PresenterImpl(mMockModel, mMockUpdatableViews, mUserActions,
mQueries);
}
@Test
public void loadInitialQueries_emptyArray_displayDataImmediately() {
// Given an empty query array
mQueries = new QueryEnum[0];
mPresenterImpl = new PresenterImpl(mMockModel, mMockUpdatableViews, mUserActions,
mQueries);
// When loading initial queries
mPresenterImpl.loadInitialQueries();
// Then the views are updated immediately
verify(mMockUpdatableView1).displayData(mMockModel, null);
verify(mMockUpdatableView2).displayData(mMockModel, null);
}
@Test
public void loadInitialQueries_nullArray_displayDataImmediately() {
// Given a null query array
mQueries = null;
mPresenterImpl = new PresenterImpl(mMockModel, mMockUpdatableViews, mUserActions,
mQueries);
// When loading initial queries
mPresenterImpl.loadInitialQueries();
// Then the views are updated immediately
verify(mMockUpdatableView1).displayData(mMockModel, null);
verify(mMockUpdatableView2).displayData(mMockModel, null);
}
@Test
public void loadInitialQueries_oneItemInArray_modelRequestDataSuccessful_ViewIsUpdated() {
// Given a query array with one query and the model update request is successful
// When loading initial queries
mPresenterImpl.loadInitialQueries();
// Then a data request of the model is called for the query and callback is captured
verify(mMockModel).requestData(eq(mQueries[0]), mDataQueryCallbackCaptor.capture());
// When the callback is successful
mDataQueryCallbackCaptor.getValue()
.onModelUpdated(mMockModel, mQueries[0]); // Trigger callback
// Then the views are updated
verify(mMockUpdatableView1).displayData(mMockModel, mQueries[0]);
verify(mMockUpdatableView2).displayData(mMockModel, mQueries[0]);
}
@Test
public void
loadInitialQueries_oneItemInArray_modelRequestDataUnsuccessful_ViewIsUpdatedWithError() {
// Given a query array with one query and the model update request is unsuccessful
// When loading initial queries
mPresenterImpl.loadInitialQueries();
// Then a data request of the model is called for the query and callback is captured
verify(mMockModel).requestData(eq(mQueries[0]), mDataQueryCallbackCaptor.capture());
// When the callback is unsuccessful
mDataQueryCallbackCaptor.getValue().onError(mQueries[0]); // Trigger callback
// Then the views are updated with error
verify(mMockUpdatableView1).displayErrorMessage(mQueries[0]);
verify(mMockUpdatableView2).displayErrorMessage(mQueries[0]);
}
@Test
public void loadInitialQueries_threeItemsInArray_modelRequestDataForEachQuery() {
// Given a query array with 3 queries
mQueries = new QueryEnum[3];
mQueries[0] = createQueryEnumWithId(1);
mQueries[1] = createQueryEnumWithId(2);
mQueries[2] = createQueryEnumWithId(3);
mPresenterImpl = new PresenterImpl(mMockModel, mMockUpdatableViews, mUserActions,
mQueries);
// When loading initial queries
mPresenterImpl.loadInitialQueries();
// Then a data request of the model is called for each query
verify(mMockModel).requestData(eq(mQueries[0]), any(Model.DataQueryCallback.class));
verify(mMockModel).requestData(eq(mQueries[1]), any(Model.DataQueryCallback.class));
verify(mMockModel).requestData(eq(mQueries[2]), any(Model.DataQueryCallback.class));
}
@Test
public void onUserAction_validUserAction_deliveryUserActionSuccessful_ViewIsUpdated() {
// Given a user action array with 1 action
// When calling user action with that user action and bundle
Bundle bundle = new Bundle();
mPresenterImpl.onUserAction(mUserActions[0], bundle);
// Then delivering user action to the model is called for the user action and bundle and
// callback is captured
verify(mMockModel).deliverUserAction(eq(mUserActions[0]), eq(bundle),
mUserActionCallbackCaptor.capture());
// When the callback is successful
mUserActionCallbackCaptor.getValue()
.onModelUpdated(mMockModel, mUserActions[0]); // Trigger callback
// Then the views are updated
verify(mMockUpdatableView1).displayUserActionResult(mMockModel, mUserActions[0], true);
verify(mMockUpdatableView2).displayUserActionResult(mMockModel, mUserActions[0], true);
}
@Test
public void
onUserAction_validUserAction_deliveryUserActionUnsuccessful_ViewIsUpdatedWithError() {
// Given a user action array with 1 action
// When calling user action with that user action and bundle
Bundle bundle = new Bundle();
mPresenterImpl.onUserAction(mUserActions[0], bundle);
// Then delivering user action to the model is called for the user action and bundle and
// callback is captured
verify(mMockModel).deliverUserAction(eq(mUserActions[0]), eq(bundle),
mUserActionCallbackCaptor.capture());
// When the callback is unsuccessful
mUserActionCallbackCaptor.getValue().onError(mUserActions[0]); // Trigger callback
// Then the views are updated with error
verify(mMockUpdatableView1).displayUserActionResult(null, mUserActions[0], false);
verify(mMockUpdatableView2).displayUserActionResult(null, mUserActions[0], false);
}
}