summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt')
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt356
1 files changed, 356 insertions, 0 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt
new file mode 100644
index 0000000000..121c8f2d22
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/plugins/locationlayer/LocationLayerTest.kt
@@ -0,0 +1,356 @@
+package com.mapbox.mapboxsdk.plugins.locationlayer
+
+import android.Manifest
+import android.R
+import android.content.Context
+import android.location.Location
+import android.support.test.espresso.Espresso.onView
+import android.support.test.espresso.IdlingRegistry
+import android.support.test.espresso.UiController
+import android.support.test.espresso.assertion.ViewAssertions.matches
+import android.support.test.espresso.matcher.ViewMatchers.isDisplayed
+import android.support.test.espresso.matcher.ViewMatchers.withId
+import android.support.test.filters.LargeTest
+import android.support.test.rule.ActivityTestRule
+import android.support.test.rule.GrantPermissionRule
+import android.support.test.rule.GrantPermissionRule.grant
+import android.support.test.runner.AndroidJUnit4
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory
+import com.mapbox.mapboxsdk.constants.Style
+import com.mapbox.mapboxsdk.geometry.LatLng
+import com.mapbox.mapboxsdk.maps.MapboxMap
+import com.mapbox.mapboxsdk.plugins.locationlayer.LocationLayerConstants.*
+import com.mapbox.mapboxsdk.plugins.locationlayer.modes.RenderMode
+import com.mapbox.mapboxsdk.plugins.utils.*
+import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.MAPBOX_HEAVY_STYLE
+import com.mapbox.mapboxsdk.plugins.utils.MapboxTestingUtils.Companion.pushSourceUpdates
+import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_CONNECTION_DELAY
+import com.mapbox.mapboxsdk.plugins.utils.PluginGenerationUtil.Companion.MAP_RENDER_DELAY
+import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
+import com.mapbox.mapboxsdk.testapp.activity.SingleActivity
+import org.hamcrest.CoreMatchers.`is`
+import org.hamcrest.CoreMatchers.notNullValue
+import org.hamcrest.Matchers.equalTo
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TestName
+import org.junit.runner.RunWith
+import timber.log.Timber
+
+@RunWith(AndroidJUnit4::class)
+@LargeTest
+class LocationLayerTest {
+
+ @Rule
+ @JvmField
+ val activityRule = ActivityTestRule(SingleActivity::class.java)
+
+ @Rule
+ @JvmField
+ val nameRule = TestName()
+
+ @Rule
+ @JvmField
+ val permissionRule: GrantPermissionRule = grant(Manifest.permission.ACCESS_FINE_LOCATION)
+
+ private lateinit var idlingResource: OnMapReadyIdlingResource
+ private lateinit var styleChangeIdlingResource: StyleChangeIdlingResource
+ private lateinit var mapboxMap: MapboxMap
+ private val location: Location by lazy {
+ val initLocation = Location("test")
+ initLocation.latitude = 15.0
+ initLocation.longitude = 17.0
+ initLocation.accuracy = 2000f
+ initLocation
+ }
+
+ @Before
+ fun beforeTest() {
+ Timber.e("@Before: ${nameRule.methodName} - register idle resource")
+ // If idlingResource is null, throw Kotlin exception
+ idlingResource = OnMapReadyIdlingResource(activityRule.activity)
+ styleChangeIdlingResource = StyleChangeIdlingResource()
+ IdlingRegistry.getInstance().register(idlingResource)
+ IdlingRegistry.getInstance().register(styleChangeIdlingResource)
+ onView(withId(android.R.id.content)).check(matches(isDisplayed()))
+ mapboxMap = idlingResource.mapboxMap
+ }
+
+ //
+ // Location Source
+ //
+
+ @Test
+ fun renderModeNormal_sourceDoesGetAdded() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.NORMAL
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ assertThat(mapboxMap.getSource(LOCATION_SOURCE), notNullValue())
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ //
+ // Location Layers
+ //
+
+ @Test
+ fun renderModeNormal_trackingNormalLayersDoGetAdded() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.NORMAL
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun renderModeCompass_bearingLayersDoGetAdded() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.COMPASS
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(true))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun renderModeGps_navigationLayersDoGetAdded() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.GPS
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun dontShowPuckWhenRenderModeSetAndPluginDisabled() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.forceLocationUpdate(location)
+ plugin.isLocationLayerEnabled = false
+ plugin.renderMode = RenderMode.GPS
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun whenLocationLayerPluginDisabled_doesSetAllLayersToVisibilityNone() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.NORMAL
+ plugin.forceLocationUpdate(location)
+ plugin.isLocationLayerEnabled = false
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+
+ // Check that all layers visibilities are set to none
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(false))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun onMapChange_locationLayerLayersDoGetRedrawn() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.renderMode = RenderMode.NORMAL
+ plugin.forceLocationUpdate(location)
+ mapboxMap.setStyleUrl(Style.LIGHT)
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY)
+
+ assertThat(plugin.renderMode, `is`(equalTo(RenderMode.NORMAL)))
+
+ // Check that the Source has been re-added to the new map style
+ val source: GeoJsonSource? = mapboxMap.getSourceAs(LOCATION_SOURCE)
+ assertThat(source, notNullValue())
+
+ // Check that all layers visibilities are set to visible
+ assertThat(mapboxMap.isLayerVisible(FOREGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BACKGROUND_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(SHADOW_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(ACCURACY_LAYER), `is`(true))
+ assertThat(mapboxMap.isLayerVisible(BEARING_LAYER), `is`(false))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+//
+// Stale state test
+//
+
+ @Test
+ fun whenStyleChanged_continuesUsingStaleIcons() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(100).build())
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(200)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+
+ assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
+
+ mapboxMap.setStyleUrl(Style.LIGHT)
+ uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY)
+
+ assertThat(mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0].getBooleanProperty(PROPERTY_LOCATION_STALE), `is`(true))
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun whenStyleChanged_staleStateChanges() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ plugin.applyStyle(LocationLayerOptions.builder(context).staleStateTimeout(1).build())
+ styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE)
+ pushSourceUpdates(styleChangeIdlingResource) {
+ plugin.forceLocationUpdate(location)
+ }
+ }
+ }
+ executePluginTest(pluginAction)
+
+ // Waiting for style to finish loading while pushing updates
+ onView(withId(R.id.content)).check(matches(isDisplayed()))
+ }
+
+ @Test
+ fun whenStyleChanged_layerVisibilityUpdates() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ styleChangeIdlingResource.waitForStyle(idlingResource.mapView, mapboxMap, MAPBOX_HEAVY_STYLE)
+ var show = true
+ pushSourceUpdates(styleChangeIdlingResource) {
+ plugin.isLocationLayerEnabled = show
+ show = !show
+ }
+
+ uiController.loopMainThreadForAtLeast(MAP_CONNECTION_DELAY)
+ }
+ }
+ executePluginTest(pluginAction)
+
+ // Waiting for style to finish loading while pushing updates
+ onView(withId(R.id.content)).check(matches(isDisplayed()))
+ }
+
+ @Test
+ fun accuracy_visibleWithNewLocation() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0))
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + ACCURACY_RADIUS_ANIMATION_DURATION)
+
+ assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/,
+ mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0]
+ .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f)
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun accuracy_visibleWhenCameraEased() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ mapboxMap.easeCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0), 300)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300)
+
+ assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/,
+ mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0]
+ .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f)
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @Test
+ fun accuracy_visibleWhenCameraMoved() {
+ val pluginAction = object : GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin> {
+ override fun onGenericPluginAction(plugin: LocationLayerPlugin, mapboxMap: MapboxMap,
+ uiController: UiController, context: Context) {
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ plugin.forceLocationUpdate(location)
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY)
+ mapboxMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(location), 16.0))
+ uiController.loopMainThreadForAtLeast(MAP_RENDER_DELAY + 300)
+
+ assertEquals(Utils.calculateZoomLevelRadius(mapboxMap, location) /*meters projected to radius on zoom 16*/,
+ mapboxMap.querySourceFeatures(LOCATION_SOURCE)[0]
+ .getNumberProperty(PROPERTY_ACCURACY_RADIUS).toFloat(), 0.1f)
+ }
+ }
+ executePluginTest(pluginAction)
+ }
+
+ @After
+ fun afterTest() {
+ Timber.e("@After: ${nameRule.methodName} - unregister idle resource")
+ IdlingRegistry.getInstance().unregister(idlingResource)
+ IdlingRegistry.getInstance().unregister(styleChangeIdlingResource)
+ }
+
+ private fun executePluginTest(listener: GenericPluginAction.OnPerformGenericPluginAction<LocationLayerPlugin>) {
+ onView(withId(android.R.id.content)).perform(GenericPluginAction(idlingResource.mapView, mapboxMap, PluginGenerationUtil.getLocationLayerPluginProvider(activityRule.activity), listener))
+ }
+}