package de.vanmar.android.yarrn.projects; import android.widget.Spinner; import com.meetme.android.horizontallistview.HorizontalListView; import com.octo.android.robospice.SpiceManager; import com.octo.android.robospice.request.SpiceRequest; import com.octo.android.robospice.request.listener.RequestListener; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.robolectric.Robolectric; import org.robolectric.util.ActivityController; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; import de.vanmar.android.yarrn.FragmentFactory; import de.vanmar.android.yarrn.MainActivity; import de.vanmar.android.yarrn.MainActivity_; import de.vanmar.android.yarrn.R; import de.vanmar.android.yarrn.components.ViewEditText; import de.vanmar.android.yarrn.ravelry.dts.Photo; import de.vanmar.android.yarrn.ravelry.dts.PhotoResult; import de.vanmar.android.yarrn.ravelry.dts.Project; import de.vanmar.android.yarrn.ravelry.dts.ProjectResult; import de.vanmar.android.yarrn.ravelry.dts.User; import de.vanmar.android.yarrn.requests.ReorderProjectPhotosRequest; import de.vanmar.android.yarrn.requests.UpdateProjectRequest; import de.vanmar.android.yarrn.util.MyRobolectricTestRunner; import de.vanmar.android.yarrn.util.TestUtil; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; import static org.mockito.Mockito.doAnswer; @RunWith(MyRobolectricTestRunner.class) public class ProjectFragmentUnitTest { public static final int PROJECT_ID = 10014463; public static final String USERNAME = "Jillda"; @Mock private FragmentFactory fragmentFactory; @Mock private SpiceManager spiceManager; @Mock private ProjectsFragment projectsFragment; private ProjectFragment_ projectFragment; private SpiceRequest request; private ReorderProjectPhotosRequest reorderRequest; @Before public void prepare() { MockitoAnnotations.initMocks(this); TestUtil.mockBackgroundExecutor(); projectFragment = new ProjectFragment_(); projectFragment.spiceManager = this.spiceManager; ActivityController<MainActivity_> activityController = Robolectric.buildActivity(MainActivity_.class).create(); MainActivity activity = activityController.get(); TestUtil.mockValidUser(activity.prefs); activity.fragmentFactory = this.fragmentFactory; given(fragmentFactory.getProjectsFragment()).willReturn(projectsFragment); given(fragmentFactory.getProjectFragment()).willReturn(projectFragment); activityController.start().resume(); activity.onProjectSelected(PROJECT_ID, USERNAME); } @Test public void shouldGetProjectDetails() throws Exception { // given mockSpiceCall(createProjectResult()); // when projectFragment.onProjectSelected(PROJECT_ID, USERNAME); // then assertThat(projectFragment.name.getText().toString(), is("aqua diva")); assertThat(projectFragment.status.getSelectedItem().toString(), is("In Progress")); assertThat(projectFragment.progressBar.getProgress(), is(5)); assertThat((String) projectFragment.progressSpinner.getSelectedItem(), is("5%")); assertThat(projectFragment.started.getText().toString(), is("17.05.2013")); // testing with German Locale assertThat(projectFragment.completed.getText().toString(), is("Juni 2013")); } @Test public void shouldRefreshProjectDetails() throws Exception { // given assertThat(projectFragment.name.getText().toString(), is("")); mockSpiceCall(createProjectResult()); // when projectFragment.menuRefresh(); // then assertThat(projectFragment.name.getText().toString(), is("aqua diva")); assertThat(projectFragment.status.getSelectedItem().toString(), is("In Progress")); assertThat(projectFragment.progressBar.getProgress(), is(5)); assertThat((String) projectFragment.progressSpinner.getSelectedItem(), is("5%")); assertThat(projectFragment.started.getText().toString(), is("17.05.2013")); // testing with German Locale assertThat(projectFragment.completed.getText().toString(), is("Juni 2013")); } @Test public void shouldUpdateProgress() { // given Spinner progressSpinner = projectFragment.progressSpinner; assertThat((String) progressSpinner.getItemAtPosition(7), is("35%")); mockSpiceCall(createProjectResult()); projectFragment.onProjectSelected(PROJECT_ID, USERNAME); // when progressSpinner.getOnItemSelectedListener().onItemSelected(progressSpinner, null, 7, 0); // then assertThat(request, is(UpdateProjectRequest.class)); UpdateProjectRequest updateProjectRequest = (UpdateProjectRequest) request; assertThat(updateProjectRequest.getProjectId(), is(PROJECT_ID)); assertThat(updateProjectRequest.getUpdateData().get("progress").getAsInt(), is(35)); } @Test public void shouldUpdateNotes() { // given ViewEditText notes = projectFragment.notes; mockSpiceCall(createProjectResult()); projectFragment.onProjectSelected(PROJECT_ID, USERNAME); assertThat(notes.getBodyText().toString(), is("Notizfeld")); assertFalse(notes.isEditMode()); // when notes.findViewById(R.id.toggleButton).performClick(); assertTrue(notes.isEditMode()); notes.setBodyText("Neue Notiz"); notes.findViewById(R.id.toggleButton).performClick(); assertFalse(notes.isEditMode()); // then assertThat(request, is(UpdateProjectRequest.class)); UpdateProjectRequest updateProjectRequest = (UpdateProjectRequest) request; assertThat(updateProjectRequest.getProjectId(), is(PROJECT_ID)); assertThat(updateProjectRequest.getUpdateData().get("notes").getAsString(), is("Neue Notiz")); } @Test public void shouldUpdateRating() { // given Spinner rating = projectFragment.rating; mockSpiceCall(createProjectResult()); projectFragment.onProjectSelected(PROJECT_ID, USERNAME); assertThat(rating.getSelectedItemPosition(), is(2)); // when rating.getOnItemSelectedListener().onItemSelected(rating, null, 4, 0); // then assertThat(request, is(UpdateProjectRequest.class)); UpdateProjectRequest updateProjectRequest = (UpdateProjectRequest) request; assertThat(updateProjectRequest.getProjectId(), is(PROJECT_ID)); assertThat(updateProjectRequest.getUpdateData().get("rating").getAsInt(), is(4)); } @Test public void shouldUpdateStatus() { // given Spinner status = projectFragment.status; mockSpiceCall(createProjectResult()); projectFragment.onProjectSelected(PROJECT_ID, USERNAME); assertThat(status.getSelectedItemPosition(), is(0)); // when status.getOnItemSelectedListener().onItemSelected(status, null, 3, 0); // then assertThat(request, is(UpdateProjectRequest.class)); UpdateProjectRequest updateProjectRequest = (UpdateProjectRequest) request; assertThat(updateProjectRequest.getProjectId(), is(PROJECT_ID)); assertThat(updateProjectRequest.getUpdateData().get("project_status_id").getAsInt(), is(4)); } @Test public void shouldRearrangePhotos() { // given mockSpiceCall(createProjectResult()); projectFragment.onProjectSelected(PROJECT_ID, USERNAME); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { reorderRequest = (ReorderProjectPhotosRequest) invocationOnMock.getArguments()[0]; RequestListener<PhotoResult> listener = (RequestListener<PhotoResult>) invocationOnMock.getArguments()[1]; PhotoResult photoResult = new PhotoResult(); photoResult.photos = new ArrayList<Photo>(); listener.onRequestSuccess(photoResult); return null; } }).when(spiceManager).execute(any(SpiceRequest.class), any(RequestListener.class)); // when HorizontalListView gallery = projectFragment.gallery; gallery.getOnItemLongClickListener().onItemLongClick(gallery, null, 0, 0); PhotoAdapter adapter = (PhotoAdapter) gallery.getAdapter(); PhotoAdapter.PhotoAdapterListener adapterListener = adapter.getPhotoAdapterListener(); adapterListener.onMoveLeft(1); // 2 1 3 adapterListener.onMoveRight(1); // 2 3 1 adapterListener.onMoveAllRight(0); // 3 1 2 adapterListener.onMoveAllLeft(1); // 1 3 2 projectFragment.galleryEditDone.performClick(); // then List<Photo> photos = reorderRequest.getPhotos(); assertThat(photos.size(), is(3)); assertThat(photos.get(0).id, is("1")); assertThat(photos.get(1).id, is("3")); assertThat(photos.get(2).id, is("2")); } private void mockSpiceCall(final ProjectResult projectResult) { doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { request = (SpiceRequest) invocationOnMock.getArguments()[0]; RequestListener<ProjectResult> listener = (RequestListener<ProjectResult>) invocationOnMock.getArguments()[3]; listener.onRequestSuccess(projectResult); return null; } }).when(spiceManager).execute(any(SpiceRequest.class), any(), anyLong(), any(RequestListener.class)); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocationOnMock) throws Throwable { request = (SpiceRequest) invocationOnMock.getArguments()[0]; RequestListener<ProjectResult> listener = (RequestListener<ProjectResult>) invocationOnMock.getArguments()[1]; listener.onRequestSuccess(projectResult); return null; } }).when(spiceManager).execute(any(SpiceRequest.class), any(RequestListener.class)); } private ProjectResult createProjectResult() { ProjectResult projectResult = new ProjectResult(); Project project = new Project(); project.name = "aqua diva"; project.progress = 5; project.rating = 2; project.status = "In Progress"; project.statusId = 1; project.notes = "Notizfeld"; GregorianCalendar started = new GregorianCalendar(); started.set(2013, Calendar.MAY, 17); project.started = started.getTime(); project.startedDaySet = true; GregorianCalendar completed = new GregorianCalendar(); completed.set(2013, Calendar.JUNE, 21); project.completed = completed.getTime(); project.completedDaySet = false; User user = new User(); user.username = TestUtil.USERNAME; project.user = user; project.photos = new ArrayList<Photo>(); project.photos.add(createPhoto("1")); project.photos.add(createPhoto("2")); project.photos.add(createPhoto("3")); projectResult.project = project; return projectResult; } private Photo createPhoto(String id) { Photo photo = new Photo(); photo.id = id; return photo; } }