/*
* Copyright 2015 Google Inc. All rights reserved.
*
* 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.feedback;
import android.app.LoaderManager;
import android.content.Context;
import android.content.CursorLoader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.test.suitebuilder.annotation.SmallTest;
import com.google.samples.apps.iosched.archframework.Model;
import com.google.samples.apps.iosched.feedback.SessionFeedbackModel.SessionFeedbackData;
import com.google.samples.apps.iosched.provider.ScheduleContract;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
@SmallTest
public class SessionFeedbackModelTest {
private static final String FAKE_TITLE = "FAKE TITLE";
private static final int SESSION_TITLE_COLUMN_INDEX = 1;
@Mock
private FeedbackHelper mMockFeedbackHelper;
@Mock
private Uri mMockUri;
@Mock
private Context mMockContext;
@Mock
private Cursor mMockCursor;
@Mock
private Bundle mMockBundle;
@Mock
private LoaderManager mMockLoaderManager;
@Mock
private Model.UserActionCallback mMockUserActionCallback;
private SessionFeedbackModel mSessionFeedbackModel;
@Before
public void setUp() {
// Mocks
initMockCursors();
// Create an instance of the model.
mSessionFeedbackModel = new SessionFeedbackModel(mMockLoaderManager, mMockUri, mMockContext,
mMockFeedbackHelper);
}
@Test
public void deliverUserAction_SubmitFeedback_Success() {
// Given a mock bundle with feedback data and a mock FeedbackHelper
SessionFeedbackModel spyModel =
spy(new SessionFeedbackModel(mMockLoaderManager, mMockUri, mMockContext,
mMockFeedbackHelper));
doReturn(FAKE_TITLE).when(spyModel).getSessionId(mMockUri);
doNothing().when(spyModel)
.sendAnalyticsEvent(anyString(), anyString(), anyString());
final String comments = "My comment";
int rating = 1;
int sessionRelevantAnswer = 2;
int contentAnswer = 3;
int speakerAnswer = 2;
when(mMockBundle.getInt(SessionFeedbackModel.DATA_RATING_INT)).thenReturn(rating);
when(mMockBundle.getInt(SessionFeedbackModel.DATA_SESSION_RELEVANT_ANSWER_INT))
.thenReturn(sessionRelevantAnswer);
when(mMockBundle.getInt(SessionFeedbackModel.DATA_CONTENT_ANSWER_INT))
.thenReturn(contentAnswer);
when(mMockBundle.getInt(SessionFeedbackModel.DATA_SPEAKER_ANSWER_INT))
.thenReturn(speakerAnswer);
when(mMockBundle.getString(SessionFeedbackModel.DATA_COMMENT_STRING)).thenReturn(comments);
// When ran with the submit user action and the mock bundle
spyModel.deliverUserAction(
SessionFeedbackModel.SessionFeedbackUserActionEnum.SUBMIT, mMockBundle,
mMockUserActionCallback);
// Then the saveSessionFeedback method in the FeedbackHelper is called with the correct
// feedback data parameters
ArgumentCaptor<SessionFeedbackData> saveSessionCaptor =
ArgumentCaptor.forClass(SessionFeedbackData.class);
verify(mMockFeedbackHelper).saveSessionFeedback(saveSessionCaptor.capture());
assertThat(saveSessionCaptor.getValue().sessionId, is(spyModel.getSessionId(mMockUri)));
assertThat(saveSessionCaptor.getValue().sessionRating, is(rating));
assertThat(saveSessionCaptor.getValue().sessionRelevantAnswer, is(sessionRelevantAnswer));
assertThat(saveSessionCaptor.getValue().contentAnswer, is(contentAnswer));
assertThat(saveSessionCaptor.getValue().speakerAnswer, is(speakerAnswer));
assertThat(saveSessionCaptor.getValue().comments, is(comments));
}
@Test
public void readDataFromCursor_SessionQuery_SessionLoaded() {
// Given a mock cursor with data
when(mMockCursor.moveToFirst()).thenReturn(true);
// When ran with a valid query
boolean success = mSessionFeedbackModel.readDataFromCursor(
mMockCursor, SessionFeedbackModel.SessionFeedbackQueryEnum.SESSION);
// Then the model is updated and the request succeeds
assertThat(mSessionFeedbackModel.getSessionTitle(), is(FAKE_TITLE));
assertThat(success, is(true));
}
@Test
public void readDataFromCursor_EmptyCursor_Unsuccessful() {
// Given an empty mock cursor
when(mMockCursor.moveToFirst()).thenReturn(false);
// When ran with a valid query
boolean result = mSessionFeedbackModel.readDataFromCursor(mMockCursor,
SessionFeedbackModel.SessionFeedbackQueryEnum.SESSION);
// Then the request model update fails
assertThat(result, is(false));
}
@Test
public void createCursorLoader_SessionQuery_Success() {
// Given a mock cursor loader set up for a session query
CursorLoader mockCursorLoaderSession = mock(CursorLoader.class);
SessionFeedbackModel spyModel = spy(
new SessionFeedbackModel(mMockLoaderManager, mMockUri, mMockContext,
mMockFeedbackHelper));
doReturn(mockCursorLoaderSession).when(spyModel).getCursorLoaderInstance(
any(Context.class), any(Uri.class), any(String[].class), any(String.class),
any(String[].class), any(String.class));
// When ran with the session query
CursorLoader createdCursorLoader1 =
(CursorLoader) spyModel
.createCursorLoader(SessionFeedbackModel.SessionFeedbackQueryEnum.SESSION,
null);
// Then the returned cursor loader is the same as the mock one
assertThat(createdCursorLoader1, sameInstance(mockCursorLoaderSession));
}
private void initMockCursors() {
// Set non empty cursor.
when(mMockCursor.moveToFirst()).thenReturn(true);
// Sets fake title
when(mMockCursor.getColumnIndex(ScheduleContract.Sessions.SESSION_TITLE))
.thenReturn(SESSION_TITLE_COLUMN_INDEX);
when(mMockCursor.getString(SESSION_TITLE_COLUMN_INDEX))
.thenReturn(FAKE_TITLE);
}
}