package com.mapzen.open.route; import com.mapzen.android.lost.api.LocationServices; import com.mapzen.android.lost.internal.FusedLocationProviderApiImpl; import com.mapzen.helpers.DistanceFormatter; import com.mapzen.helpers.ZoomController; import com.mapzen.open.MapController; import com.mapzen.open.MapzenApplication; import com.mapzen.open.R; import com.mapzen.open.TestMapzenApplication; import com.mapzen.open.util.SimpleFeatureHelper; import com.mapzen.pelias.SimpleFeature; import com.mapzen.open.fragment.MapFragment; import com.mapzen.open.shadows.ShadowMint; import com.mapzen.open.support.MapzenTestRunner; import com.mapzen.open.support.TestBaseActivity; import com.mapzen.open.support.TestHelper; import com.mapzen.open.support.TestHelper.LocationUpdateSubscriber; import com.mapzen.open.support.TestHelper.ViewUpdateSubscriber; import com.mapzen.open.util.DatabaseHelper; import com.mapzen.open.util.MapzenNotificationCreator; import com.mapzen.open.util.RouteLocationIndicator; import com.mapzen.open.widget.DistanceView; import com.mapzen.osrm.Instruction; import com.mapzen.osrm.Route; import com.mapzen.osrm.Router; import com.mixpanel.android.mpmetrics.MixpanelAPI; import com.squareup.otto.Bus; import org.json.JSONObject; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mockito; import org.oscim.core.GeoPoint; import org.oscim.core.MapPosition; import org.oscim.map.TestMap; import org.oscim.map.TestViewport; import org.oscim.map.ViewController; import org.robolectric.Robolectric; import org.robolectric.shadows.ShadowApplication; import org.robolectric.shadows.ShadowEnvironment; import org.robolectric.shadows.ShadowNotification; import org.robolectric.shadows.ShadowNotificationManager; import org.robolectric.shadows.ShadowTextToSpeech; import org.robolectric.shadows.ShadowToast; import org.robolectric.shadows.ShadowView; import org.robolectric.tester.android.view.TestMenu; import org.robolectric.util.FragmentTestUtil; import android.annotation.SuppressLint; import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.content.res.Resources; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.location.Location; import android.os.Environment; import android.preference.PreferenceManager; import android.speech.tts.TextToSpeech; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.TextView; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import javax.inject.Inject; import static com.mapzen.pelias.SimpleFeature.TEXT; import static com.mapzen.open.support.TestHelper.MOCK_ACE_HOTEL; import static com.mapzen.open.support.TestHelper.MOCK_AROUND_THE_BLOCK; import static com.mapzen.open.support.TestHelper.MOCK_NY_TO_VT; import static com.mapzen.open.support.TestHelper.MOCK_ROUTE_JSON; import static com.mapzen.open.support.TestHelper.enableDebugMode; import static com.mapzen.open.support.TestHelper.getTestInstruction; import static com.mapzen.open.support.TestHelper.getTestLastInstruction; import static com.mapzen.open.support.TestHelper.getTestLocation; import static com.mapzen.open.support.TestHelper.getTestSimpleFeature; import static com.mapzen.open.support.TestHelper.initBaseActivityWithMenu; import static com.mapzen.open.util.DatabaseHelper.COLUMN_GROUP_ID; import static com.mapzen.open.util.DatabaseHelper.COLUMN_MSG; import static com.mapzen.open.util.DatabaseHelper.COLUMN_READY_FOR_UPLOAD; import static com.mapzen.open.util.DatabaseHelper.COLUMN_ROUTE_ID; import static com.mapzen.open.util.DatabaseHelper.COLUMN_TABLE_ID; import static com.mapzen.open.util.DatabaseHelper.TABLE_GROUPS; import static com.mapzen.open.util.DatabaseHelper.TABLE_ROUTES; import static com.mapzen.open.util.DatabaseHelper.TABLE_ROUTE_GEOMETRY; import static com.mapzen.open.util.DatabaseHelper.TABLE_ROUTE_GROUP; import static com.mapzen.open.util.MixpanelHelper.Event.ROUTING_START; import static org.fest.assertions.api.ANDROID.assertThat; import static org.fest.assertions.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.robolectric.Robolectric.application; import static org.robolectric.Robolectric.shadowOf; import static org.robolectric.Robolectric.shadowOf_; @RunWith(MapzenTestRunner.class) public class RouteFragmentTest { @Inject Router router; @Inject MapController mapController; @Inject ZoomController zoomController; @Inject MixpanelAPI mixpanelAPI; @Inject SQLiteDatabase db; @Inject Bus bus; @Inject RouteLocationIndicatorFactory routeLocationIndicatorFactory; private static TestMenu menu = new TestMenu(); private static TestBaseActivity act = initBaseActivityWithMenu(menu); private RouteFragment fragment; private ShadowApplication app; private ArrayList<Instruction> testInstructions; private Location startLocation; @Before public void setUp() throws Exception { ((TestMapzenApplication) Robolectric.application).inject(this); initTestFragment(); app = Robolectric.getShadowApplication(); GeoPoint start = SimpleFeatureHelper.getGeoPoint(fragment.getSimpleFeature()); startLocation = getTestLocation(start.getLatitude(), start.getLongitude()); } @Test public void shouldNotBeNull() throws Exception { assertThat(fragment).isNotNull(); } @Test public void shouldNotBeAdded() throws Exception { assertThat(fragment).isNotAdded(); } @Test public void shouldRetainInstance() throws Exception { assertThat(fragment.getRetainInstance()).isTrue(); } @Test public void shouldHideActionBar() throws Exception { TestHelper.startFragment(fragment, act); assertThat(act.getSupportActionBar().isShowing()).isFalse(); } @Test public void shouldKeepScreenOn() throws Exception { LayoutInflater inflater = act.getLayoutInflater(); View view = inflater.inflate(R.layout.route_widget, null, false); assertThat(view.findViewById(R.id.routes)).isKeepingScreenOn(); } @Test public void shouldCreateView() throws Exception { TestHelper.startFragment(fragment, act); View view = fragment.getView(); assertThat(view).isNotNull(); } @Test public void shouldHaveRoutesViewPager() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.pager).isNotNull(); } @Test public void shouldShowRouteAttribution() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getView().findViewById(R.id.route_attribution)).isVisible(); } @Test public void shouldHideBaseAttribution() throws Exception { TestHelper.startFragment(fragment, act); Robolectric.runUiThreadTasksIncludingDelayedTasks(); assertThat(act.findViewById(R.id.attribution)).isNotVisible(); } @Test public void locateButtonShouldNotBeVisible() throws Exception { TestHelper.startFragment(fragment, act); assertThat(act.findViewById(R.id.locate_button)).isNotVisible(); } @Test public void onDestroy_locateButtonShouldBeVisible() throws Exception { TestHelper.startFragment(fragment, act); fragment.onDestroy(); assertThat(act.findViewById(R.id.locate_button)).isVisible(); } @Test public void onSnapLocation_shouldStoreOriginalLocationRecordInDatabase() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location expected = fragment.getRoute().getGeometry().get(2); fragment.onSnapLocation(expected, fragment.getRoute().snapToRoute(expected)); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_LAT, DatabaseHelper.COLUMN_LNG }, null, null, null, null, null); cursor.moveToNext(); assertThat(cursor.getString(0)).isEqualTo(String.valueOf(expected.getLatitude())); assertThat(cursor.getString(1)).isEqualTo(String.valueOf(expected.getLongitude())); } @Test public void onSnapLocation_shouldStoreCorrectedLocationRecordInDatabase() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = fragment.getRoute().getGeometry().get(2); fragment.onSnapLocation(testLocation, fragment.getRoute().snapToRoute(testLocation)); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_CORRECTED_LAT, DatabaseHelper.COLUMN_CORRECTED_LNG }, null, null, null, null, null); cursor.moveToNext(); assertThat(cursor.getString(0)).isNotNull(); assertThat(cursor.getString(1)).isNotNull(); } @Test public void onMapSwipe_ShouldDisplayResumeButton() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); simulateUserDrag(); assertThat(fragment.getView().findViewById(R.id.resume_button)).isVisible(); } @Test public void onMapTwoFingerScroll_ShouldNotDisplayResumeButton() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); assertThat(fragment.getView().findViewById(R.id.resume_button)).isNotVisible(); simulateTwoFingerDrag(); assertThat(fragment.getView().findViewById(R.id.resume_button)).isNotVisible(); } @Test public void onLocationChange_shouldStoreInstructionPointsRecordInDatabase() throws Exception { initTestFragment(); ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Location expected = fragment.getRoute().getGeometry().get(0); Location sample1 = fragment.getRoute().getGeometry().get(1); Location sample2 = fragment.getRoute().getGeometry().get(2); instructions.add(getTestInstruction(expected.getLatitude(), expected.getLongitude())); instructions.add(getTestInstruction(sample1.getLatitude(), sample1.getLongitude())); TestHelper.startFragment(fragment, act); fragment.setInstructions(instructions); Location testLocation = getTestLocation(sample2.getLatitude(), sample2.getLongitude()); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_INSTRUCTION_LAT, DatabaseHelper.COLUMN_INSTRUCTION_LNG }, null, null, null, null, null); assertThat(cursor).hasCount(1); cursor.moveToNext(); assertThat(cursor.getString(0)).isEqualTo(String.valueOf(expected.getLatitude())); assertThat(cursor.getString(1)).isEqualTo(String.valueOf(expected.getLongitude())); } @Test public void drawRoute_shouldStoreCoordinates() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); fragment.createRouteTo(getTestLocation(100.0, 100.0)); fragment.success(new Route(MOCK_ROUTE_JSON)); fragment.onPause(); Cursor cursor = db.query(TABLE_ROUTE_GEOMETRY, new String[] { COLUMN_ROUTE_ID }, COLUMN_ROUTE_ID + " = ?", new String[] { String.valueOf(fragment.getRouteId()) }, null, null, null); assertThat(cursor).hasCount(fragment.getRoute().getGeometry().size()); } @Test public void drawRoute_shouldNotStoreCoordinates() throws Exception { TestHelper.startFragment(fragment, act); fragment.onPause(); Cursor cursor = db.query(TABLE_ROUTE_GEOMETRY, new String[] { COLUMN_ROUTE_ID }, COLUMN_ROUTE_ID + " = ?", new String[] { String.valueOf(fragment.getRouteId()) }, null, null, null); assertThat(cursor).hasCount(0); } @Test public void onLocationChange_shouldStoreInstructionBearingRecordInDatabase() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = fragment.getRoute().getGeometry().get(2); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_INSTRUCTION_BEARING }, null, null, null, null, null); assertThat(cursor).hasCount(1); cursor.moveToNext(); assertThat(cursor.getInt(0)).isEqualTo( fragment.getRoute().getRouteInstructions().get(0).getBearing()); } @Test public void onLocationChange_shouldStoreSpeedInDatabase() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = fragment.getRoute().getGeometry().get(2); float expectedSpeed = 44.0f; testLocation.setSpeed(expectedSpeed); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_SPEED }, null, null, null, null, null); assertThat(cursor).hasCount(1); cursor.moveToNext(); assertThat(cursor.getFloat(0)).isEqualTo(expectedSpeed); } @Test public void onLocationChange_shouldStoreBearingInDatabase() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = fragment.getRoute().getGeometry().get(2); float expectedBearing = 44.0f; testLocation.setBearing(expectedBearing); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_BEARING }, null, null, null, null, null); assertThat(cursor).hasCount(1); cursor.moveToNext(); assertThat(cursor.getFloat(0)).isEqualTo(expectedBearing); } @Test public void onLocationChange_shouldNotStoreDatabaseRecord() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction(99.0, 89.0)); instructions.add(getTestInstruction(0, 0)); TestHelper.startFragment(fragment, act); fragment.setInstructions(instructions); Location testLocation = getTestLocation(20.0, 30.0); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { DatabaseHelper.COLUMN_INSTRUCTION_BEARING }, null, null, null, null, null); assertThat(cursor).hasCount(0); } @Test public void onLocationChange_shouldStoreAssociatedRoute() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = fragment.getRoute().getGeometry().get(2); fragment.onLocationChanged(testLocation); Cursor cursor = db.query(DatabaseHelper.TABLE_LOCATIONS, new String[] { COLUMN_ROUTE_ID }, COLUMN_ROUTE_ID + " = ?", new String[] { String.valueOf(fragment.getRouteId()) }, null, null, null); assertThat(cursor).hasCount(1); } @Test public void onRecalculate_shouldCreateNewRoute() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Route oldRoute = fragment.getRoute(); fragment.onRecalculate(getTestLocation(111.0, 111.0)); fragment.success(new Route(MOCK_NY_TO_VT)); assertThat(fragment.getRoute()).isNotSameAs(oldRoute); } @Test public void onCreate_shouldFireMixpanelEvent() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); verify(mixpanelAPI).track(eq(ROUTING_START), any(JSONObject.class)); } @Test public void onCreate_shouldHideLocationMarker() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getMapFragment().getMap().layers(). contains(fragment.getMapFragment().getLocationMarkerLayer())).isFalse(); } @Test public void success_shouldHideLocationMarker() throws Exception { TestHelper.startFragment(fragment, act); fragment.getActivity().findViewById(R.id.locate_button).setVisibility(View.VISIBLE); fragment.success(new Route(MOCK_ROUTE_JSON)); Robolectric.runUiThreadTasksIncludingDelayedTasks(); assertThat(fragment.getActivity().findViewById(R.id.locate_button)).isGone(); } @Test public void onPause_shouldShowLocationMarker() throws Exception { TestHelper.startFragment(fragment, act); fragment.onPause(); assertThat(fragment.getMapFragment().getMap().layers(). contains(fragment.getMapFragment().getLocationMarkerLayer())).isTrue(); } @Test public void onBack_shouldActAsResumeButton() throws Exception { TestHelper.startFragment(fragment, act); simulateUserPagerTouch(); ImageButton resume = (ImageButton) fragment.getView().findViewById(R.id.resume_button); assertThat(resume).isVisible(); fragment.onBackAction(); assertThat(resume).isNotVisible(); } @Test public void onCreate_shouldShowRouteLocationIndicator() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getMapFragment().getMap().layers(). contains(fragment.getRouteLocationIndicator())).isTrue(); } @Test public void onPause_shouldHideRouteLocationIndicator() throws Exception { TestHelper.startFragment(fragment, act); fragment.onPause(); assertThat(fragment.getMapFragment().getMap().layers(). contains(fragment.getRouteLocationIndicator())).isFalse(); } @Test public void onDestroy_shouldRefreshRoutePreview() throws Exception { ViewUpdateSubscriber viewUpdateSubscriber = new ViewUpdateSubscriber(); bus.register(viewUpdateSubscriber); act = initBaseActivityWithMenu(menu); TestHelper.startFragment(fragment, act); fragment.onDestroy(); assertThat(viewUpdateSubscriber.getEvent()).isNotNull(); } @Test public void shouldHaveRouteLocationIndicator() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getRouteLocationIndicator()).isNotNull(); } @Test public void onResume_shouldSetRouteLocationIndicatorToStartingCoordinates() throws Exception { TestHelper.startFragment(fragment, act); fragment.onResume(); RouteLocationIndicator mockLocationIndicator = routeLocationIndicatorFactory .getRouteLocationIndicator(); verify(mockLocationIndicator, atLeastOnce()).setPosition( fragment.getRoute().getStartCoordinates().getLatitude(), fragment.getRoute().getStartCoordinates().getLongitude()); } @Test public void onResume_shouldSetRouteLocationIndicatorToStartingBearing() throws Exception { TestHelper.startFragment(fragment, act); fragment.onResume(); RouteLocationIndicator mockLocationIndicator = routeLocationIndicatorFactory .getRouteLocationIndicator(); verify(mockLocationIndicator, atLeastOnce()).setRotation( (float) fragment.getRoute().getCurrentRotationBearing()); } @Test public void onCreate_shouldCreateGroupInDatabase() throws Exception { TestHelper.startFragment(fragment, act); Cursor cursor = db.query(TABLE_GROUPS, new String[] { COLUMN_TABLE_ID }, null, null, null, null, null); assertThat(cursor).hasCount(1); } @Test public void onCreate_shouldCreateGroupInDatabaseWithDescription() throws Exception { TestHelper.startFragment(fragment, act); String expected = fragment.getGPXDescription(); Cursor cursor = db.query(TABLE_GROUPS, new String[] { COLUMN_TABLE_ID }, COLUMN_MSG + " = ?", new String[] { expected }, null, null, null); assertThat(cursor).hasCount(1); } @Test public void onCreate_shouldCreateGroupThatIsNotReadyForUploadInDatabase() throws Exception { TestHelper.startFragment(fragment, act); Cursor cursor = db.query(TABLE_GROUPS, new String[] { COLUMN_TABLE_ID }, COLUMN_READY_FOR_UPLOAD + " is null", null, null, null, null); assertThat(cursor).hasCount(1); } @Test public void onDestroy_shouldMarkGroupAsReadyForUpload() throws Exception { TestHelper.startFragment(fragment, act); fragment.onDestroy(); Cursor cursor = db.query(TABLE_GROUPS, new String[] { COLUMN_TABLE_ID }, COLUMN_READY_FOR_UPLOAD + " is not null", null, null, null, null); assertThat(cursor).hasCount(1); } @Test(expected = IllegalArgumentException.class) public void onCreate_shouldRegisterReceiver() throws Exception { TestHelper.startFragment(fragment, act); bus.register(fragment); } @Test(expected = IllegalArgumentException.class) public void onDestroy_shouldUnRegisterReceiver() throws Exception { TestHelper.startFragment(fragment, act); fragment.onDestroy(); bus.unregister(fragment); } @Test public void setFeature_shouldGenerateDestinationPoint() throws Exception { SimpleFeature simpleFeature = new SimpleFeature(); fragment.setSimpleFeature(simpleFeature); assertThat(fragment.getDestinationPoint()) .isEqualTo(SimpleFeatureHelper.getGeoPoint(simpleFeature)); } @Test public void setDestination_shouldSetFeature() throws Exception { SimpleFeature simpleFeature = getTestSimpleFeature(); fragment.setSimpleFeature(simpleFeature); assertThat(fragment.getSimpleFeature()).isEqualTo(simpleFeature); } @Test public void onCreateView_shouldShowNameOfDestination() throws Exception { TestHelper.startFragment(fragment, act); SimpleFeature simpleFeature = getTestSimpleFeature(); TextView view = (TextView) fragment.getView().findViewById(R.id.destination_name); assertThat(view.getText()).isEqualTo(act .getString(R.string.routing_to_text) + simpleFeature.getProperty(TEXT)); assertThat(view).hasEllipsize(TextUtils.TruncateAt.END); assertThat(view).hasMaxLines(1); } @Test public void onCreateView_shouldHaveTotalDistance() throws Exception { TestHelper.startFragment(fragment, act); act.showLoadingIndicator(); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); DistanceView textView = (DistanceView) view.findViewById(R.id.destination_distance); int distance = fragment.getRoute().getTotalDistance(); String expectedFormattedDistance = DistanceFormatter.format(distance, true); assertThat(textView.getText()).isEqualTo(expectedFormattedDistance); } @Test public void onCreateView_shouldNotShowResumeButton() throws Exception { TestHelper.startFragment(fragment, act); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); ImageButton resume = (ImageButton) view.findViewById(R.id.resume_button); assertThat(resume).isNotVisible(); } @Test public void onTouch_shouldDisplayResumeButton() throws Exception { TestHelper.startFragment(fragment, act); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); ImageButton resume = (ImageButton) view.findViewById(R.id.resume_button); simulateUserPagerTouch(); assertThat(resume).isVisible(); } @Test public void onTouch_shouldStoreCurrentItemWhenPagerWasFirstTouched() throws Exception { loadAceHotelMockRoute(); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(0).getLocation()); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(1).getLocation()); int expected = fragment.pager.getCurrentItem(); simulateUserPagerTouch(); fragment.pager.setCurrentItem(0); simulateUserPagerTouch(); fragment.getView().findViewById(R.id.resume_button).performClick(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(expected); } @Test public void onClickResume_shouldHideResumeButton() throws Exception { TestHelper.startFragment(fragment, act); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); ImageButton resume = (ImageButton) view.findViewById(R.id.resume_button); simulateUserPagerTouch(); resume.performClick(); assertThat(resume).isNotVisible(); } @Test public void onClickResume_shouldStartAtPagerLocation() throws Exception { Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onLocationChanged(instructions.get(1).getLocation()); fragment.onLocationChanged(instructions.get(2).getLocation()); int expected = fragment.pager.getCurrentItem(); simulateUserPagerTouch(); fragment.pager.setCurrentItem(0); ImageButton resume = (ImageButton) fragment.getView().findViewById(R.id.resume_button); resume.performClick(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(expected); } @Test public void expandedPane_shouldShowDirectionListFragment() { TestHelper.startFragment(fragment, act); simulatePaneOpenSlide(); assertThat(fragment.getChildFragmentManager()). hasFragmentWithTag(DirectionListFragment.TAG); } @Test public void collapsedPane_shouldNotShowDirectionListFragment() { TestHelper.startFragment(fragment, act); simulatePaneOpenSlide(); simulatePaneCloseSlide(); assertThat(fragment.getChildFragmentManager()) .doesNotHaveFragmentWithTag(DirectionListFragment.TAG); } @Test public void arrowButtons_ShouldPageThrough() { Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); int firstInstruction = fragment.pager.getCurrentItem(); ImageButton rightArrow = (ImageButton) getInstructionView(firstInstruction) .findViewById(R.id.right_arrow); rightArrow.performClick(); assertThat(fragment.pager.getCurrentItem() - 1).isEqualTo(firstInstruction); ImageButton leftArrow = (ImageButton) getInstructionView(firstInstruction) .findViewById(R.id.left_arrow); leftArrow.performClick(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(firstInstruction); } @Test public void shouldDecreaseDistanceOnAdvanceViaSwipe() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction firstInstruction = getTestInstruction(0, 0); firstInstruction.setDistance(5); instructions.add(firstInstruction); instructions.add(getTestInstruction(0, 0)); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); int expectedDistance = fragment.getRoute().getTotalDistance() - firstInstruction.getDistance(); String expectedFormattedDistance = DistanceFormatter.format(expectedDistance, true); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); DistanceView textView = (DistanceView) view.findViewById(R.id.destination_distance); fragment.onPageSelected(1); assertThat(textView.getText()).isEqualTo(expectedFormattedDistance); } @Test public void shouldIncreaseDistanceOnRegressViaSwipe() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction(0, 0)); instructions.add(getTestInstruction(0, 0)); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); int expectedDistance = fragment.getRoute().getTotalDistance(); String expectedFormattedDistance = DistanceFormatter.format(expectedDistance, true); View view = fragment.onCreateView(act.getLayoutInflater(), null, null); DistanceView textView = (DistanceView) view.findViewById(R.id.destination_distance); int current = fragment.pager.getCurrentItem(); fragment.pager.setCurrentItem(++current); fragment.onPageSelected(0); assertThat(textView.getText()).isEqualTo(expectedFormattedDistance); } @Test public void onResume_shouldDeactivateActivitiesMapUpdates() throws Exception { TestHelper.startFragment(fragment, act); assertThat(((MapzenApplication) application).shouldMoveMapToLocation()).isFalse(); } @Test public void onResume_shouldSetDefaultRouteZoom() throws Exception { TestHelper.startFragment(fragment, act); assertThat(mapController.getZoomLevel()).isEqualTo(zoomController.getZoom()); } @Test public void onResume_shouldSetDefaultRouteTilt() throws Exception { TestHelper.startFragment(fragment, act); TestViewport viewport = (TestViewport) act.getMap().viewport(); assertThat(viewport.getTilt()).isEqualTo(RouteFragment.DEFAULT_ROUTING_TILT); } @Test public void onResume_shouldDisableActionbar() throws Exception { TestHelper.startFragment(fragment, act); assertThat(act.getSupportActionBar().isShowing()).isFalse(); } @Test public void onDestroy_shouldActivateMoveMapToLocation() throws Exception { TestHelper.startFragment(fragment, act); fragment.onDestroy(); assertThat(((MapzenApplication) application).shouldMoveMapToLocation()).isTrue(); } @Test public void onPause_shouldEndDbTransaction() throws Exception { TestHelper.startFragment(fragment, act); fragment.onPause(); assertThat(db.inTransaction()).isFalse(); } @Test public void onLocationChange_shouldAdvance() throws Exception { loadAceHotelMockRoute(); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(0).getLocation()); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(1).getLocation()); assertThat(fragment.pager.getCurrentItem()).isEqualTo(2); } @Test public void onLocationChange_shouldNotChangeUsersMap() throws Exception { loadAceHotelMockRoute(); simulateUserPagerTouch(); double lat = fragment.getMapFragment().getMap().getMapPosition().getLatitude(); double lng = fragment.getMapFragment().getMap().getMapPosition().getLongitude(); fragment.getRoute().addSeenInstruction(fragment.getRoute().getRouteInstructions().get(0)); fragment.onLocationChanged( fragment.getRoute().getRouteInstructions().get(1).getLocation()); fragment.onLocationChanged( fragment.getRoute().getRouteInstructions().get(2).getLocation()); assertThat(lat).isEqualTo( fragment.getMapFragment().getMap().getMapPosition().getLatitude()); assertThat(lng).isEqualTo( fragment.getMapFragment().getMap().getMapPosition().getLongitude()); } @Test public void onLocationChange_shouldChangeUsersMap() throws Exception { loadAceHotelMockRoute(); simulateUserPagerTouch(); double lat = fragment.getMapFragment().getMap().getMapPosition().getLatitude(); double lng = fragment.getMapFragment().getMap().getMapPosition().getLongitude(); fragment.getRoute().addSeenInstruction( fragment.getRoute().getRouteInstructions().get(0)); fragment.onLocationChanged( fragment.getRoute().getRouteInstructions().get(1).getLocation()); fragment.onClickResume(); fragment.onLocationChanged( fragment.getRoute().getRouteInstructions().get(2).getLocation()); assertThat(lat).isNotEqualTo( fragment.getMapFragment().getMap().getMapPosition().getLatitude()); assertThat(lng).isNotEqualTo( fragment.getMapFragment().getMap().getMapPosition().getLongitude()); } @Test public void onInstructionComplete_shouldPreservePagerIndex() throws Exception { loadAceHotelMockRoute(); simulateUserPagerTouch(); fragment.getRoute().addSeenInstruction(fragment.getRoute().getRouteInstructions().get(0)); fragment.onInstructionComplete(0); fragment.onInstructionComplete(1); fragment.onInstructionComplete(2); fragment.onClickResume(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(3); } @Test public void onLocationChange_shouldAlwaysMoveRouteLocationIndicator() throws Exception { loadAceHotelMockRoute(); RouteLocationIndicator routeLocationIndicator = Mockito.mock(RouteLocationIndicator.class); fragment.setRouteLocationIndicator(routeLocationIndicator); simulateUserPagerTouch(); Location loc = fragment.getRoute().getRouteInstructions().get(1).getLocation(); fragment.onLocationChanged(loc); Mockito.verify(routeLocationIndicator).setPosition(loc.getLatitude(), loc.getLongitude()); } @Test public void onLocationChange_shouldAlwaysRotateRouteLocationIndicator() throws Exception { loadAceHotelMockRoute(); RouteLocationIndicator routeLocationIndicator = Mockito.mock(RouteLocationIndicator.class); fragment.setRouteLocationIndicator(routeLocationIndicator); simulateUserPagerTouch(); Location loc = fragment.getRoute().getRouteInstructions().get(1).getLocation(); fragment.onLocationChanged(loc); Mockito.verify(routeLocationIndicator).setRotation(Mockito.anyFloat()); } @Test public void onLocationChange_shouldNotAdvanceWhenUserHasPaged() throws Exception { Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); simulateUserPagerTouch(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(0); fragment.onLocationChanged(instructions.get(2).getLocation()); assertThat(fragment.pager.getCurrentItem()).isEqualTo(0); } @Test public void onLocationChange_shouldAdvanceWhenUserHasResumed() throws Exception { loadAceHotelMockRoute(); simulateUserPagerTouch(); fragment.onClickResume(); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(0).getLocation()); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(1).getLocation()); assertThat(fragment.pager.getCurrentItem()).isEqualTo(2); } @Test public void onLocationChange_shouldNotCrashIfClosestInstructionsAreExhausted() throws Exception { fragment.setRoute(new Route(MOCK_ROUTE_JSON)); TestHelper.startFragment(fragment, act); fragment.onResume(); Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.onLocationChanged(instructions.get(0).getLocation()); fragment.onLocationChanged(instructions.get(1).getLocation()); fragment.onLocationChanged(instructions.get(2).getLocation()); } @Test public void onLocationChanged_shouldNotAdvanceWhenDistanceEqualsTurnRadius() throws Exception { loadAceHotelMockRoute(); fragment.pager.setCurrentItem(1); fragment.onLocationChanged(getTestLocation(40.743016, -73.987105)); // 50 meters away assertThat(fragment.pager).hasCurrentItem(1); } @Test public void distanceToDestination_shouldEqualRouteDistanceAtStart() throws Exception { loadAceHotelMockRoute(); fragment.onLocationChanged(fragment.getRoute().getRouteInstructions().get(0).getLocation()); int expected = fragment.getRoute().getTotalDistance(); assertThat(fragment.distanceToDestination).hasText(DistanceFormatter.format(expected)); } @Test public void setMapPerspectiveForInstruction_shouldAlignBearing() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction instruction = getTestInstruction(0, 0); instructions.add(instruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); mapController.setMapPerspectiveForInstruction(instruction); assertThat(act.getMap().getMapPosition().getBearing()).isEqualTo( instruction.getRotationBearing()); } @Test public void getAdvanceRadius_shouldHaveDefaultValue() { TestHelper.startFragment(fragment, act); assertThat(fragment.getAdvanceRadius()).isEqualTo(ZoomController.DEFAULT_TURN_RADIUS); } @Test public void onLocationChanged_finalInstructionShouldNotAdvance() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction(0, 0)); instructions.add(getTestInstruction(0, 0)); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.pager.setCurrentItem(1); fragment.onLocationChanged(getTestLocation(0, 0)); assertThat(fragment.pager).hasCurrentItem(1); } @Test public void onApproachInstruction_shouldSpeakTurnInstruction() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction firstInstruction = getTestInstruction(0, 0); firstInstruction.setDistance(100); instructions.add(firstInstruction); Instruction secondInstruction = getTestInstruction(0, 0); secondInstruction.setDistance(200); instructions.add(secondInstruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onApproachInstruction(0); assertLastSpokenText("Head on 19th Street"); } @Test public void onApproachInstruction_shouldNotAnnounceYouHaveArrivedEarly() throws Exception { loadAceHotelMockRoute(); fragment.onApproachInstruction(fragment.getRoute().getRouteInstructions().size() - 1); assertLastSpokenText(null); } @Test public void onInstructionComplete_shouldSpeakContinueInstruction() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction firstInstruction = getTestInstruction(0, 0); firstInstruction.setDistance(100); instructions.add(firstInstruction); Instruction secondInstruction = getTestInstruction(0, 0); secondInstruction.setDistance(200); instructions.add(secondInstruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onInstructionComplete(0); assertLastSpokenText("Continue on 19th Street for 320 feet"); } @Test public void onInstructionComplete_shouldVerifyNextIndexIsWithinBounds() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction(0, 0)); instructions.add(getTestInstruction(0, 0)); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onInstructionComplete(1); } @Test public void onRouteComplete_shouldAdvancePagerToFinalInstruction() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction()); instructions.add(getTestLastInstruction()); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onRouteComplete(); assertThat(fragment.pager).hasCurrentItem(1); } @Test public void onRouteComplete_shouldAnnounceFinalInstruction() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction()); instructions.add(getTestLastInstruction()); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onRouteComplete(); assertLastSpokenText(getTestLastInstruction().getSimpleInstruction(fragment.getActivity())); } @Test public void onRouteComplete_shouldSetZeroDistanceToDestination() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); instructions.add(getTestInstruction()); instructions.add(getTestLastInstruction()); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onRouteComplete(); assertThat(fragment.distanceToDestination.getDistance()).isEqualTo(0); } @Test public void onRouteComplete_shouldHideFooter() throws Exception { loadAceHotelMockRoute(); fragment.onRouteComplete(); assertThat(fragment.getView().findViewById(R.id.footer_wrapper)).isNotVisible(); } @Test public void onPageSelected_shouldTurnMap() throws Exception { Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); simulateUserPagerTouch(); assertThat(fragment.pager.getCurrentItem()).isEqualTo(0); fragment.onPageSelected(2); Instruction i = instructions.get(2); assertThat(act.getMap().getMapPosition().getBearing()).isEqualTo(i.getRotationBearing()); } @Test public void onPageSelected_shouldNotTurnMap() throws Exception { Route route = fragment.getRoute(); ArrayList<Instruction> instructions = route.getRouteInstructions(); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); assertThat(fragment.pager.getCurrentItem()).isEqualTo(0); fragment.onPageSelected(2); Instruction i = instructions.get(2); TestViewport viewport = (TestViewport) act.getMap().viewport(); assertThat(viewport.getRotation()).isNotEqualTo(i.getRotationBearing()); } @Test public void onRecalculate_shouldAnnounceRecalculation() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); Location testLocation = getTestLocation(111.0, 111.0); fragment.onRecalculate(testLocation); assertLastSpokenText(act.getString(R.string.recalculating)); } @Test public void onRecalculate_shouldUpdateCurrentInstructionText() throws Exception { act = initBaseActivityWithMenu(menu); initTestFragment(); loadAceHotelMockRoute(); fragment.onRecalculate(getTestLocation(111.0, 111.0)); View view = fragment.getPagerViewForIndex(0); TextView before = (TextView) view.findViewById(R.id.full_instruction); assertThat(before).hasText(app.getString(R.string.recalculating)); TextView after = (TextView) view.findViewById(R.id.full_instruction_after_action); assertThat(after).hasText(app.getString(R.string.recalculating)); } @Test public void onRecalculate_shouldHideIconDistanceAndArrows() throws Exception { loadAceHotelMockRoute(); fragment.onRecalculate(getTestLocation(111.0, 111.0)); View view = fragment.getPagerViewForIndex(0); assertThat(view.findViewById(R.id.left_arrow)).isNotVisible(); assertThat(view.findViewById(R.id.turn_container)).isNotVisible(); assertThat(view.findViewById(R.id.right_arrow)).isNotVisible(); } @Test public void onUpdateDistance_shouldShowDistanceToDestinationAfterReroute() throws Exception { loadAceHotelMockRoute(); fragment.onRecalculate(getTestLocation(111.0, 111.0)); fragment.onUpdateDistance(0, 0); assertThat(fragment.distanceToDestination).isVisible(); } @Test public void setRoute_shouldShowRouteFooterAfterReroute() throws Exception { loadAceHotelMockRoute(); fragment.onRecalculate(getTestLocation(111.0, 111.0)); Route route = new Route(MOCK_ACE_HOTEL); fragment.setRoute(route); Robolectric.runUiThreadTasks(); assertThat(fragment.footerWrapper).isVisible(); } @Test public void turnAutoPageOff_shouldMuteVoiceNavigation() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); fragment.turnAutoPageOff(); assertThat(fragment.voiceNavigationController.isMuted()).isTrue(); } @Test public void resumeAutoPaging_shouldUnmuteVoiceNavigation() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); fragment.turnAutoPageOff(); fragment.resumeAutoPaging(); assertThat(fragment.voiceNavigationController.isMuted()).isFalse(); } @Test public void resumeAutoPaging_shouldSetPerspectiveForCurrentInstruction() throws Exception { loadAceHotelMockRoute(); fragment.turnAutoPageOff(); fragment.pager.setCurrentItem(1); fragment.resumeAutoPaging(); assertThat(fragment.pager).hasCurrentItem(0); } @Test public void onPageScrolled_shouldNotResumeAutoPagingIfAlreadyOn() throws Exception { ViewController viewport = Mockito.mock(ViewController.class); ((TestMap) mapController.getMap()).setViewport(viewport); loadAceHotelMockRoute(); fragment.onPageScrolled(0, 0, 0); Mockito.verify(viewport, atLeast(2)).setMapPosition(Mockito.any(MapPosition.class)); } @Test public void createRouteTo_shouldDisplayProgressDialog() throws Exception { TestHelper.startFragment(fragment, act); fragment.createRouteTo(getTestLocation(0, 0)); assertThat(act.getMapFragment().getView().findViewById(R.id.progress)).isVisible(); } @Test public void createRouteTo_shouldDismissProgressDialogOnError() throws Exception { TestHelper.startFragment(fragment, act); fragment.createRouteTo(getTestLocation(0, 0)); fragment.failure(500); assertThat(act.getMapFragment().getView().findViewById(R.id.map)).isVisible(); assertThat(act.getMapFragment().getView().findViewById(R.id.progress)).isNotVisible(); } @Test public void createRouteTo_shouldDismissProgressDialogOnSuccess() throws Exception { TestHelper.startFragment(fragment, act); fragment.createRouteTo(getTestLocation(0, 0)); fragment.failure(207); assertThat(act.getMapFragment().getView().findViewById(R.id.map)).isVisible(); assertThat(act.getMapFragment().getView().findViewById(R.id.progress)).isNotVisible(); } @Test public void createRouteTo_shouldToastIfNoRouteFound() throws Exception { Location testLocation = getTestLocation(100.0, 100.0); TestHelper.startFragment(fragment, act); fragment.createRouteTo(testLocation); fragment.failure(207); assertThat(ShadowToast.getTextOfLatestToast()) .isEqualTo(act.getString(R.string.no_route_found)); } @Test public void createRouteTo_shouldAddFragment() throws Exception { TestHelper.startFragment(fragment, act); fragment.success(new Route(MOCK_NY_TO_VT)); assertThat(fragment).isAdded(); } @Test public void createRouteTo_shouldResetPager() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment).isAdded(); int previousCount = fragment.pager.getAdapter().getCount(); assertThat(previousCount).isEqualTo(3); Location testLocation = getTestLocation(100.0, 100.0); fragment.createRouteTo(testLocation); Route newRoute = new Route(MOCK_NY_TO_VT); fragment.success(newRoute); assertThat(fragment.pager.getAdapter().getCount()) .isEqualTo(newRoute.getRouteInstructions().size()); } @Test public void createRouteTo_shouldRedoUrl() throws Exception { MapFragment mapFragmentMock = mock(MapFragment.class, Mockito.CALLS_REAL_METHODS); mapFragmentMock.setAct(act); fragment.setMapFragment(mapFragmentMock); TestHelper.startFragment(fragment, act); fragment.createRouteTo(getTestLocation(100.0, 200.0)); fragment.createRouteTo(getTestLocation(200.0, 300.0)); assertThat(router.getRouteUrl().toString()).contains("200.0,300.0"); assertThat(router.getRouteUrl().toString()).doesNotContain("100.0,200.0"); } @Test public void createRouteTo_shouldRequestNewRoute() throws Exception { Location testLocation = getTestLocation(100.0, 100.0); TestHelper.startFragment(fragment, act); fragment.createRouteTo(testLocation); verify(router).fetch(); } @Test public void onLocationChange_shouldDoNothingWhileRerouting() throws Exception { Location testLocation = getTestLocation(40.658563, -73.986853); RouteFragment spyFragment = spy(fragment); spyFragment.setRoute(new Route(MOCK_AROUND_THE_BLOCK)); TestHelper.startFragment(spyFragment, act); spyFragment.onLocationChanged(testLocation); spyFragment.onLocationChanged(testLocation); verify(spyFragment, Mockito.times(1)).createRouteTo(testLocation); } @Test public void onLocationChange_shouldBeReEnabledOnceReRoutingIsCompleted() throws Exception { Location testLocation = getTestLocation(40.658563, -73.986853); RouteFragment spyFragment = spy(fragment); spyFragment.setRoute(new Route(MOCK_AROUND_THE_BLOCK)); TestHelper.startFragment(spyFragment, act); spyFragment.onLocationChanged(startLocation); spyFragment.onLocationChanged(testLocation); spyFragment.success(new Route(new JSONObject(MOCK_AROUND_THE_BLOCK))); spyFragment.onLocationChanged(startLocation); spyFragment.onLocationChanged(testLocation); verify(spyFragment, Mockito.times(2)).createRouteTo(testLocation); } @Test public void onLocationChange_shouldBeReEnabledOnceReRoutingHasError() throws Exception { Location testLocation = getTestLocation(40.658563, -73.986853); RouteFragment spyFragment = spy(fragment); spyFragment.setRoute(new Route(MOCK_AROUND_THE_BLOCK)); TestHelper.startFragment(spyFragment, act); spyFragment.onLocationChanged(startLocation); spyFragment.onLocationChanged(testLocation); spyFragment.failure(500); spyFragment.onLocationChanged(testLocation); verify(spyFragment, Mockito.times(2)).createRouteTo(testLocation); } @Test public void getGPXDescription_shouldIncludeReturnBeginningAndEnd() throws Exception { TestHelper.startFragment(fragment, act); testInstructions = new ArrayList<Instruction>(); testInstructions.add(getTestInstruction(0, 0)); fragment.setInstructions(testInstructions); String actual = fragment.getGPXDescription(); assertThat(actual).contains("Route between: 19th Street [0.0, 0.0]"); assertThat(actual).contains("Test SimpleFeature [1.0, 1.0]"); } @Test public void getGPXDescription_shouldDisplay() throws Exception { String expected = "Route without instructions"; fragment.setInstructions(new ArrayList<Instruction>()); String actual = fragment.getGPXDescription(); assertThat(actual).contains(expected); } @Test public void storeRouteInDatabase_shouldCreateRoute() throws Exception { TestHelper.startFragment(fragment, act); fragment.storeRouteInDatabase(new JSONObject()); Cursor cursor = db.query(TABLE_ROUTES, new String[] { COLUMN_TABLE_ID }, COLUMN_TABLE_ID + " = ?", new String[] { fragment.getRouteId() } , null, null, null); assertThat(cursor).hasCount(1); } @Test public void newInstance_shouldCreateGroupId() throws Exception { assertThat(fragment.groupId).isNotNull(); } @Test public void setRoute_shouldCreateRouteGroupEntry() throws Exception { TestHelper.startFragment(fragment, act); fragment.setRoute(new Route(MOCK_ROUTE_JSON)); Cursor cursor = db.query(TABLE_ROUTE_GROUP, null, COLUMN_ROUTE_ID + " = ? AND " + COLUMN_GROUP_ID + " = ?", new String[] { fragment.getRouteId(), fragment.groupId }, null, null, null); assertThat(cursor).hasCount(1); } @Test public void storeRouteInDatabase_shouldSendExceptionToBugSense() throws Exception { db.close(); fragment.storeRouteInDatabase(new JSONObject()); assertThat(ShadowMint.getLastHandledException()) .isInstanceOf(IllegalStateException.class); } @Test public void addCoordinatesToDatabase_shouldSendExceptionToBugSense() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); db.close(); fragment.success(new Route(MOCK_ROUTE_JSON)); assertThat(ShadowMint.getLastHandledException()) .isInstanceOf(IllegalStateException.class); } @Test public void shouldInitDynamicZoomUsingDefaultValues() throws Exception { Resources res = act.getResources(); TestHelper.startFragment(fragment, act); Location location = fragment.getRoute().getRouteInstructions().get(0).getLocation(); setNumberOfLocationForAverageSpeed(1); assertZoomLevel(res.getInteger(R.integer.zoom_driving_0to15), 10, location); assertZoomLevel(res.getInteger(R.integer.zoom_driving_15to25), 20, location); assertZoomLevel(res.getInteger(R.integer.zoom_driving_25to35), 30, location); assertZoomLevel(res.getInteger(R.integer.zoom_driving_35to50), 40, location); assertZoomLevel(res.getInteger(R.integer.zoom_driving_over50), 50, location); } @Test public void shouldUpdateDynamicZoomWithNewValues() throws Exception { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(act); SharedPreferences.Editor editPrefs = prefs.edit(); editPrefs.putInt(act.getString(R.string.settings_zoom_driving_0to15_key), 14); editPrefs.putInt(act.getString(R.string.settings_zoom_driving_15to25_key), 13); editPrefs.putInt(act.getString(R.string.settings_zoom_driving_25to35_key), 12); editPrefs.putInt(act.getString(R.string.settings_zoom_driving_35to50_key), 11); editPrefs.putInt(act.getString(R.string.settings_zoom_driving_over50_key), 10); editPrefs.commit(); setNumberOfLocationForAverageSpeed(1); TestHelper.startFragment(fragment, act); Location location = fragment.getRoute().getRouteInstructions().get(0).getLocation(); assertZoomLevel(14, 10, location); assertZoomLevel(13, 20, location); assertZoomLevel(12, 30, location); assertZoomLevel(11, 40, location); assertZoomLevel(10, 50, location); } @Test public void debugViewShouldBeHidden() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getView().findViewById(R.id.debugging)).isNotVisible(); } @Test public void debugViewShouldBeVisible() throws Exception { enableDebugMode(Robolectric.application); TestHelper.startFragment(fragment, act); assertThat(fragment.getView().findViewById(R.id.debugging)).isVisible(); } @Test @SuppressLint("NewApi") public void shouldGenerateNotificationOnFirstInstruction() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction instruction = getTestInstruction(3, 3); instructions.add(instruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); ShadowNotification sNotification = getRoutingNotification(); assertThat(sNotification.getContentTitle()).isEqualTo("Test SimpleFeature"); assertThat(sNotification.getContentText()).isEqualTo("Head on 19th Street for 520 ft"); assertThat(sNotification.getActions().get(0).title).isEqualTo("Exit Navigation"); } @Test @SuppressLint("NewApi") public void shouldGenerateNotificationOnPageSelected() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction instruction = getTestInstruction(3, 3); instructions.add(instruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onPageSelected(0); ShadowNotification sNotification = getRoutingNotification(); assertThat(sNotification.getContentTitle()).isEqualTo("Test SimpleFeature"); assertThat(sNotification.getContentText()).isEqualTo("Head on 19th Street for 520 ft"); assertThat(sNotification.getActions().get(0).title).isEqualTo("Exit Navigation"); } @Test @SuppressLint("NewApi") public void shouldKillNotificationOnExitNavigation() throws Exception { ArrayList<Instruction> instructions = new ArrayList<Instruction>(); Instruction instruction = getTestInstruction(3, 3); instructions.add(instruction); fragment.setInstructions(instructions); TestHelper.startFragment(fragment, act); fragment.onPageSelected(0); ShadowNotification sNotification = getRoutingNotification(); sNotification.getActions().get(0).actionIntent.send(); ShadowApplication application = shadowOf(act.getApplication()); Intent broadcastIntent = application.getBroadcastIntents().get(0); String broadcastClassName = broadcastIntent.getComponent().getClassName(); boolean shouldExit = broadcastIntent.getExtras() .getBoolean(MapzenNotificationCreator.EXIT_NAVIGATION); assertThat(shouldExit).isTrue(); assertThat(broadcastClassName) .isEqualTo("com.mapzen.open.util.NotificationBroadcastReceiver"); } @Test public void getAverageSpeed_shouldDefaultToZero() throws Exception { TestHelper.startFragment(fragment, act); assertThat(fragment.getAverageSpeed()).isEqualTo(0); } @Test public void getAverageSpeed_shouldReturnAverageOfLastNLocationUpdates() throws Exception { initTestFragment(); TestHelper.startFragment(fragment, act); TestHelper.TestLocation.Builder locationBuilder = new TestHelper.TestLocation.Builder(fragment.getRoute().getGeometry().get(2)); float expectedSpeed = 10.0f; locationBuilder.setSpeed(200.0f); fragment.onLocationChanged(locationBuilder.build()); locationBuilder.setSpeed(expectedSpeed); setNumberOfLocationForAverageSpeed(10); for (int i = 0; i < fragment.getNumberOfLocationsForAverageSpeed(); i++) { fragment.onLocationChanged(locationBuilder.build()); } assertThat(fragment.getAverageSpeed()).isEqualTo(expectedSpeed); } @Ignore @Test public void shouldUseGpxTraceWhenMockModeEnabled() throws Exception { loadTestGpxTrace(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(act); prefs.edit().putBoolean(act.getString(R.string.settings_mock_gpx_key), true).commit(); fragment = RouteFragment.newInstance(act, getTestSimpleFeature()); fragment.setRoute(new Route(MOCK_ROUTE_JSON)); LocationUpdateSubscriber locationUpdateSubscriber = new LocationUpdateSubscriber(); bus.register(locationUpdateSubscriber); act = initBaseActivityWithMenu(menu); TestHelper.startFragment(fragment, act); Thread.sleep(300); Robolectric.runUiThreadTasks(); assertThat(locationUpdateSubscriber.getEvent().getLocation()).hasLatitude(0.0); assertThat(locationUpdateSubscriber.getEvent().getLocation()).hasLongitude(0.1); } @Test public void onDestroy_shouldDisableMockMode() throws Exception { loadTestGpxTrace(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(act); prefs.edit().putBoolean(act.getString(R.string.settings_mock_gpx_key), true).commit(); initTestFragment(); TestHelper.startFragment(fragment, act); fragment.onDestroy(); assertThat(((TestFusedLocationProviderApiImpl) LocationServices.FusedLocationApi).mockMode) .isFalse(); } @Test public void getGpxDescription_shouldReturnErrorMessageForNullInstructions() throws Exception { loadAceHotelMockRoute(); fragment.setInstructions(null); assertThat(fragment.getGPXDescription()).isEqualTo("Route without instructions"); } @Test public void onDetach_shouldRemoveDirectionListFragment() throws Exception { TestHelper.startFragment(fragment, act); fragment.getPanelSlideListener().onPanelSlide(fragment.getSlideLayout(), RouteFragment.SLIDING_PANEL_OFFSET_MARGIN + 1); fragment.onDetach(); assertThat(fragment.getChildFragmentManager()) .doesNotHaveFragmentWithTag(DirectionListFragment.TAG); } private void loadAceHotelMockRoute() { fragment.success(new Route(MOCK_ACE_HOTEL)); FragmentTestUtil.startFragment(fragment); fragment.onResume(); } private void loadTestGpxTrace() throws IOException { byte[] encoded = Files.readAllBytes(Paths.get("src/test/resources/lost.gpx")); String contents = new String(encoded, "UTF-8"); ShadowEnvironment.setExternalStorageState(Environment.MEDIA_MOUNTED); File directory = Environment.getExternalStorageDirectory(); File file = new File(directory, "lost.gpx"); FileWriter fileWriter = new FileWriter(file, false); fileWriter.write(contents); fileWriter.close(); } private void assertZoomLevel(int expected, float milesPerHour, Location location) { location.setSpeed(ZoomController.milesPerHourToMetersPerSecond(milesPerHour)); location.setTime(System.currentTimeMillis()); fragment.onLocationChanged(location); assertThat(mapController.getZoomLevel()).isEqualTo(expected); } private void initTestFragment() throws Exception { fragment = RouteFragment.newInstance(act, getTestSimpleFeature()); fragment.setRoute(new Route(MOCK_ROUTE_JSON)); testInstructions = new ArrayList<Instruction>(); testInstructions.add(getTestInstruction(0, 0)); testInstructions.add(getTestInstruction(1, 1)); testInstructions.add(getTestInstruction(2, 2)); fragment.setInstructions(testInstructions); setTestLocationClient(); } private ShadowNotification getRoutingNotification() { NotificationManager manager = (NotificationManager) act.getSystemService( Context.NOTIFICATION_SERVICE); ShadowNotificationManager sManager = shadowOf(manager); return shadowOf(sManager.getAllNotifications().get(0)); } private void setNumberOfLocationForAverageSpeed(int value) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(act); SharedPreferences.Editor prefEditor = prefs.edit(); prefEditor.putInt( act.getString(R.string.settings_number_of_locations_for_average_speed_key), value); prefEditor.commit(); } private void simulateUserPagerTouch() { MotionEvent motionEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 12f, 34f, 0); View.OnTouchListener listener = shadowOf(fragment.pager).getOnTouchListener(); listener.onTouch(null, motionEvent); } private void simulateUserDrag() { MotionEvent e = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 120f, 100f, 0); ShadowView view = shadowOf(act.findViewById(R.id.map)); fragment.setCurrentXCor(3.0f); view.getOnTouchListener().onTouch(null, e); } private void simulateTwoFingerDrag() { MotionEvent e = mock(MotionEvent.class); Mockito.when(e.getPointerCount()).thenReturn(2); Mockito.when(e.getAction()).thenReturn(MotionEvent.ACTION_MOVE); ShadowView view = shadowOf(act.findViewById(R.id.map)); view.getOnTouchListener().onTouch(null, e); } private void simulatePaneOpenSlide() { fragment.getPanelSlideListener().onPanelSlide(fragment.getSlideLayout(), RouteFragment.SLIDING_PANEL_OFFSET_OPEN); } private void simulatePaneCloseSlide() { fragment.getPanelSlideListener().onPanelSlide(fragment.getSlideLayout(), RouteFragment.SLIDING_PANEL_OFFSET_CLOSED); } private View getInstructionView(int position) { ViewGroup group = new ViewGroup(act) { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { } }; return (View) fragment.pager.getAdapter().instantiateItem(group, position); } private void assertLastSpokenText(String expected) { TextToSpeech tts = fragment.voiceNavigationController.getTextToSpeech(); ShadowTextToSpeech shadowTts = shadowOf_(tts); shadowTts.getOnInitListener().onInit(TextToSpeech.SUCCESS); assertThat(shadowTts.getLastSpokenText()).isEqualTo(expected); } private void setTestLocationClient() { LocationServices.FusedLocationApi = new TestFusedLocationProviderApiImpl(application); } class TestFusedLocationProviderApiImpl extends FusedLocationProviderApiImpl { private boolean mockMode = false; public TestFusedLocationProviderApiImpl(Context context) { super(context); } @Override public void setMockMode(boolean isMockMode) { super.setMockMode(isMockMode); mockMode = isMockMode; } @Override public void setMockTrace(File file) { // Prevents spawning thread to replay mock locations } } }