package com.mapzen.open.fragment; import com.mapzen.open.R; import com.mapzen.open.TestMapzenApplication; import com.mapzen.open.activity.BaseActivity; import com.mapzen.open.core.StyleDownLoader; import com.mapzen.open.search.OnPoiClickListener; import com.mapzen.open.support.FakeMotionEvent; import com.mapzen.open.support.MapzenTestRunner; import com.squareup.okhttp.HttpResponseCache; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.OkResponseCache; import com.squareup.otto.Bus; import org.junit.Before; 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.event.Gesture; import org.oscim.layers.marker.ItemizedLayer; import org.oscim.layers.marker.MarkerItem; import org.oscim.layers.tile.TileLayer; import org.oscim.map.Map; import org.oscim.map.TestMap; import org.oscim.tiling.TileSource; import org.oscim.tiling.source.HttpEngine; import org.oscim.tiling.source.OkHttpEngine; import org.oscim.tiling.source.UrlTileSource; import org.robolectric.Robolectric; import org.robolectric.util.FragmentTestUtil; import android.content.BroadcastReceiver; import android.content.Intent; import android.content.SharedPreferences; import android.preference.PreferenceManager; import java.io.File; import java.util.List; import javax.inject.Inject; import static com.mapzen.open.core.MapzenLocation.COM_MAPZEN_FIND_ME; import static com.mapzen.open.support.TestHelper.getTestSimpleFeature; import static com.mapzen.open.support.TestHelper.initBaseActivity; import static org.fest.assertions.api.ANDROID.assertThat; import static org.fest.assertions.api.Assertions.assertThat; import static org.fest.reflect.core.Reflection.field; @RunWith(MapzenTestRunner.class) public class MapFragmentTest { private MapFragment mapFragment; private TestPoiClickListener listener; private BaseActivity activity; @Inject StyleDownLoader styleDownLoader; @Inject Bus bus; @Before public void setUp() throws Exception { ((TestMapzenApplication) Robolectric.application).inject(this); activity = initBaseActivity(); listener = new TestPoiClickListener(); mapFragment = activity.getMapFragment(); mapFragment.setOnPoiClickListener(listener); } @Test public void shouldNotBeNull() throws Exception { assertThat(mapFragment).isNotNull(); } @Test public void shouldHavePoiLayer() throws Exception { assertThat(mapFragment.getPoiLayer()).isNotNull(); } @Test public void shouldHaveMeMarkerLayer() throws Exception { assertThat(mapFragment.getLocationMarkerLayer()).isNotNull(); } @Test public void onItemSingleTapUp_shouldNotifyListener() throws Exception { ItemizedLayer<MarkerItem> poiLayer = mapFragment.getPoiLayer(); poiLayer.addItem(new MarkerItem("Title", "Description", new GeoPoint(0, 0))); poiLayer.onGesture(Gesture.TAP, new FakeMotionEvent(0, 0)); assertThat(listener.getIndex()).isEqualTo(0); assertThat(listener.getItem().getTitle()).isEqualTo("Title"); } class TestPoiClickListener implements OnPoiClickListener { private int index = -1; private MarkerItem item; @Override public void onPoiClick(int index, MarkerItem item) { this.index = index; this.item = item; } public int getIndex() { return index; } public MarkerItem getItem() { return item; } } @Test public void onPause_shouldEmptyMeMarkers() throws Exception { ItemizedLayer<MarkerItem> meMarkerLayer = mapFragment.getLocationMarkerLayer(); meMarkerLayer.addItem(new MarkerItem("Title", "Description", new GeoPoint(0, 0))); mapFragment.onPause(); assertThat(meMarkerLayer.size()).isEqualTo(0); } @Test public void onPause_shouldEmptyPoiMarkers() throws Exception { mapFragment.addPoi(getTestSimpleFeature()); mapFragment.addPoi(getTestSimpleFeature()); ItemizedLayer<MarkerItem> poiMarkerLayer = mapFragment.getPoiLayer(); mapFragment.onPause(); assertThat(poiMarkerLayer.size()).isEqualTo(0); } @Test public void onResume_shouldRepopulatePoiMarkers() throws Exception { mapFragment.addPoi(getTestSimpleFeature()); mapFragment.addPoi(getTestSimpleFeature()); ItemizedLayer<MarkerItem> poiMarkerLayer = mapFragment.getPoiLayer(); mapFragment.onPause(); mapFragment.onResume(); assertThat(poiMarkerLayer.size()).isEqualTo(2); } @Test (expected = IllegalArgumentException.class) public void onResume_shouldRegisterLocationUpdateSubscriber() { bus.register(mapFragment); } @Test (expected = IllegalArgumentException.class) public void onPause_shouldUnregisterLocationUpdatesSubscriber() { mapFragment.onPause(); bus.unregister(mapFragment); } @Test public void onResume_shouldRegisterFindMeReceiver() { Intent expectedIntent = new Intent(COM_MAPZEN_FIND_ME); List<BroadcastReceiver> findMeReceivers = Robolectric.getShadowApplication().getReceiversForIntent(expectedIntent); assertThat(findMeReceivers).hasSize(1); } @Test public void onPause_shouldUnregisterFindMeReceiver() { mapFragment.onPause(); Intent expectedIntent = new Intent(COM_MAPZEN_FIND_ME); List<BroadcastReceiver> findMeReceivers = Robolectric.getShadowApplication().getReceiversForIntent(expectedIntent); assertThat(findMeReceivers).isEmpty(); } @Test public void clearMarkers_shouldEmptyMapPois() throws Exception { mapFragment.addPoi(getTestSimpleFeature()); mapFragment.addPoi(getTestSimpleFeature()); ItemizedLayer<MarkerItem> poiMarkerLayer = mapFragment.getPoiLayer(); mapFragment.clearMarkers(); assertThat(poiMarkerLayer.size()).isZero(); } @Test public void clearMarkers_shouldEmptyStoredPois() throws Exception { mapFragment.addPoi(getTestSimpleFeature()); mapFragment.addPoi(getTestSimpleFeature()); mapFragment.clearMarkers(); mapFragment.onPause(); mapFragment.onResume(); ItemizedLayer<MarkerItem> poiMarkerLayer = mapFragment.getPoiLayer(); assertThat(poiMarkerLayer.size()).isZero(); } @Test public void shouldPointToDefaultTileService() throws Exception { assertThat(mapFragment.getTileBaseSource()).isEqualTo( mapFragment.getActivity().getResources().getString( R.string.settings_default_mapsource)); } @Test public void shouldPointToConfiguredTileService() throws Exception { String expected = "http://test.com"; setTileSourceConfiguration(expected); assertThat(mapFragment.getTileBaseSource()).isEqualTo(expected); } @Test public void shouldUseOkHttp() throws Exception { Map map = mapFragment.getMap(); TileLayer baseLayer = field("mBaseLayer").ofType(TileLayer.class).in(map).get(); TileSource tileSource = field("mTileSource").ofType(TileSource.class).in(baseLayer).get(); HttpEngine.Factory factory = field("mHttpFactory").ofType(HttpEngine.Factory.class) .in(tileSource).get(); assertThat(factory).isInstanceOf(OkHttpEngine.OkHttpFactory.class); } @Test public void shouldUse10MegResponseCache() throws Exception { Map map = mapFragment.getMap(); TileLayer baseLayer = field("mBaseLayer").ofType(TileLayer.class).in(map).get(); UrlTileSource tileSource = (UrlTileSource) field("mTileSource"). ofType(TileSource.class).in(baseLayer).get(); HttpEngine.Factory engine = field("mHttpFactory"). ofType(HttpEngine.Factory.class).in(tileSource).get(); OkHttpClient client = field("mClient").ofType(OkHttpClient.class).in(engine).get(); HttpResponseCache cache = (HttpResponseCache) field("responseCache"). ofType(OkResponseCache.class).in(client).get(); assertThat(cache.getMaxSize()).isEqualTo(MapFragment.CACHE_SIZE); } @Test public void shouldUseResponseCacheStoredOnFile() throws Exception { Map map = mapFragment.getMap(); TileLayer baseLayer = field("mBaseLayer").ofType(TileLayer.class).in(map).get(); UrlTileSource tileSource = (UrlTileSource) field("mTileSource"). ofType(TileSource.class).in(baseLayer).get(); HttpEngine.Factory engine = field("mHttpFactory"). ofType(HttpEngine.Factory.class).in(tileSource).get(); OkHttpClient client = field("mClient").ofType(OkHttpClient.class).in(engine).get(); HttpResponseCache cache = (HttpResponseCache) field("responseCache"). ofType(OkResponseCache.class).in(client).get(); assertThat(cache.getDirectory().getAbsolutePath()). isEqualTo(activity.getExternalCacheDir().getAbsolutePath() + "/tile-cache"); } @Test public void shouldSetupLocationMarker() throws Exception { assertThat(mapFragment.getMap().layers(). contains(mapFragment.getLocationMarkerLayer())).isTrue(); } @Test public void shouldHideLocationMarker() throws Exception { mapFragment.hideLocationMarker(); assertThat(mapFragment.getMap().layers(). contains(mapFragment.getLocationMarkerLayer())).isFalse(); } @Test public void shouldShowLocationMarker() throws Exception { mapFragment.getMap().layers().remove(mapFragment.getLocationMarkerLayer()); mapFragment.showLocationMarker(); assertThat(mapFragment.getMap().layers(). contains(mapFragment.getLocationMarkerLayer())).isTrue(); } @Test public void showProgress_shouldShowProgressView() throws Exception { FragmentTestUtil.startFragment(mapFragment); mapFragment.showProgress(); assertThat(mapFragment.getView().findViewById(R.id.progress)).isVisible(); } @Test public void showProgress_shouldDisableMap() throws Exception { FragmentTestUtil.startFragment(mapFragment); mapFragment.getView().findViewById(R.id.map).setClickable(true); mapFragment.showProgress(); assertThat(mapFragment.getView().findViewById(R.id.map)).isNotClickable(); } @Test public void hideProgress_shouldHideProgressView() throws Exception { FragmentTestUtil.startFragment(mapFragment); mapFragment.showProgress(); mapFragment.hideProgress(); assertThat(mapFragment.getView().findViewById(R.id.progress)).isNotVisible(); } @Test public void hideProgress_shouldEnableMap() throws Exception { FragmentTestUtil.startFragment(mapFragment); mapFragment.getView().findViewById(R.id.map).setClickable(false); mapFragment.hideProgress(); assertThat(mapFragment.getView().findViewById(R.id.map)).isClickable(); } @Test public void onActivityCreated_shouldDoStylesheetDownload() throws Exception { FragmentTestUtil.startFragment(mapFragment); Mockito.verify(styleDownLoader).download(); } @Test public void findMe_shouldNotResetZoomAndPointNorthAfterMapPositionEvent() throws Exception { FragmentTestUtil.startFragment(mapFragment); mapFragment.findMe(); MapPosition mapPosition = new MapPosition(); mapPosition.setZoomLevel(10); activity.getMap().events.fire(Map.POSITION_EVENT, mapPosition); mapFragment.findMe(); assertThat(mapFragment.mapController.getZoomLevel()).isEqualTo(10); } @Test public void onActivityCreated_shouldVerifyTileCacheDirectoryIsAvailable() throws Exception { BaseActivityWithNullCache baseActivityWithNullCache = new BaseActivityWithNullCache(); mapFragment.setAct(baseActivityWithNullCache); mapFragment.onActivityCreated(null); } @Test public void showLocationMarker_shouldNotCrashIfMapIsNull() throws Exception { mapFragment.setAct(new BaseActivityWithNullMap()); mapFragment.showLocationMarker(); } @Test public void showLocationMarker_shouldNotCrashIfLayersIsNull() throws Exception { mapFragment.setAct(new BaseActivityWithNullLayers()); mapFragment.showLocationMarker(); } private void setTileSourceConfiguration(String source) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity); SharedPreferences.Editor prefEditor = prefs.edit(); prefEditor.putString(activity.getString(R.string.settings_key_mapsource), source); prefEditor.commit(); } public class BaseActivityWithNullCache extends BaseActivity { @Override public File getExternalCacheDir() { return null; } @Override public Map getMap() { return new TestMap(); } } public class BaseActivityWithNullMap extends BaseActivity { @Override public Map getMap() { return null; } } public class BaseActivityWithNullLayers extends BaseActivity { @Override public Map getMap() { TestMap map = Mockito.mock(TestMap.class); Mockito.when(map.layers()).thenReturn(null); return map; } } }