1- @file:Suppress(" PrivatePropertyName" , " MaxLineLength" )
2-
31package com.mapbox.navigation.dropin.camera
42
53import android.app.Service
64import android.content.Context
75import android.view.LayoutInflater
86import android.view.View
9- import android.view.View.OnLayoutChangeListener
107import android.widget.FrameLayout
8+ import androidx.core.view.doOnNextLayout
119import androidx.test.core.app.ApplicationProvider
10+ import com.google.android.material.bottomsheet.BottomSheetBehavior
1211import com.mapbox.navigation.dropin.R
1312import com.mapbox.navigation.dropin.databinding.MapboxNavigationViewLayoutBinding
13+ import com.mapbox.navigation.dropin.infopanel.InfoPanelBehavior
14+ import com.mapbox.navigation.dropin.navigationview.NavigationViewContext
15+ import com.mapbox.navigation.dropin.navigationview.NavigationViewModel
16+ import com.mapbox.navigation.dropin.testutil.TestLifecycleOwner
1417import com.mapbox.navigation.dropin.util.TestStore
18+ import com.mapbox.navigation.testing.LoggingFrontendTestRule
1519import com.mapbox.navigation.testing.MainCoroutineRule
1620import com.mapbox.navigation.ui.app.internal.camera.CameraAction
17- import com.mapbox.navigation.ui.app.internal.navigation.NavigationState
1821import io.mockk.mockk
1922import kotlinx.coroutines.ExperimentalCoroutinesApi
2023import kotlinx.coroutines.coroutineScope
2124import kotlinx.coroutines.launch
2225import kotlinx.coroutines.suspendCancellableCoroutine
2326import org.junit.Assert.assertEquals
24- import org.junit.Assert.assertNotEquals
2527import org.junit.Before
2628import org.junit.Rule
2729import org.junit.Test
@@ -37,9 +39,13 @@ class CameraLayoutObserverTest {
3739 @get:Rule
3840 val coroutineRule = MainCoroutineRule ()
3941
42+ @get:Rule
43+ val loggerRule = LoggingFrontendTestRule ()
44+
4045 private lateinit var store: TestStore
4146 private lateinit var binding: MapboxNavigationViewLayoutBinding
4247 private lateinit var mapView: View
48+ private lateinit var infoPanelBehavior: InfoPanelBehavior
4349 private lateinit var sut: CameraLayoutObserver
4450
4551 @Before
@@ -51,103 +57,68 @@ class CameraLayoutObserverTest {
5157 ).apply {
5258 // slightly modifying default layout to simulate layout changes
5359 guidanceLayout.bottom = 100
54- roadNameLayout.top = 100
55- actionListLayout.left = 100
56- infoPanelLayout.right = 100
60+ roadNameLayout.top = 900
61+ infoPanelLayout.right = 500
62+ }
63+ mapView = View (context).apply {
64+ bottom = 1000
5765 }
58- mapView = View (context)
5966 store = TestStore ()
60- sut = CameraLayoutObserver (store, mapView, binding)
67+ val navContext = NavigationViewContext (
68+ context,
69+ TestLifecycleOwner (),
70+ NavigationViewModel (),
71+ ) { store }
72+ infoPanelBehavior = navContext.behavior.infoPanelBehavior
73+ sut = CameraLayoutObserver (navContext, mapView, binding)
6174 }
6275
6376 @Test
6477 @Config(qualifiers = " port" )
65- fun `portrait - should update bottom padding for DestinationPreview, FreeDrive and RoutePreview state ` () =
78+ fun `portrait - should update camera paddings ` () =
6679 coroutineRule.runBlockingTest {
6780 sut.onAttached(mockk())
6881
69- triggerLayoutChangesAndVerifyDispatchedActions(
70- givenNavigationStates = listOf (
71- NavigationState .DestinationPreview ,
72- NavigationState .FreeDrive ,
73- NavigationState .RoutePreview ,
74- )
75- ) { state, action ->
76- assertEquals(" $state |top" , action.padding.top, PADDING_V_PORT , 0.001 )
77- assertNotEquals(" $state |bottom" , action.padding.bottom, PADDING_V_PORT , 0.001 )
78- assertEquals(" $state |left" , action.padding.left, PADDING_H_PORT , 0.001 )
79- assertEquals(" $state |right" , action.padding.right, PADDING_H_PORT , 0.001 )
80- }
81- }
82-
83- @Test
84- @Config(qualifiers = " port" )
85- fun `portrait - should update top and bottom padding for ActiveNavigation and Arrival state` () =
86- coroutineRule.runBlockingTest {
87- sut.onAttached(mockk())
82+ binding.coordinatorLayout.triggerLayoutChange()
8883
89- triggerLayoutChangesAndVerifyDispatchedActions(
90- givenNavigationStates = listOf (
91- NavigationState .ActiveNavigation ,
92- NavigationState .Arrival ,
93- )
94- ) { s, action ->
95- assertNotEquals(" $s |top" , action.padding.top, PADDING_V_PORT , 0.001 )
96- assertNotEquals(" $s |bottom" , action.padding.bottom, PADDING_V_PORT , 0.001 )
97- assertEquals(" $s |left" , action.padding.left, PADDING_H_PORT , 0.001 )
98- assertEquals(" $s |right" , action.padding.right, PADDING_H_PORT , 0.001 )
99- }
84+ val action = store.actions.last() as CameraAction .UpdatePadding
85+ assertEquals(" left" , paddingH, action.padding.left, 0.001 )
86+ assertEquals(" top" , 100 + paddingV, action.padding.top, 0.001 )
87+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
88+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
10089 }
10190
10291 @Test
10392 @Config(qualifiers = " land" )
104- fun `landscape - should update bottom padding for FreeDrive state ` () =
93+ fun `landscape - should update camera paddings when bottom sheet is collapsed ` () =
10594 coroutineRule.runBlockingTest {
10695 sut.onAttached(mockk())
10796
108- triggerLayoutChangesAndVerifyDispatchedActions(
109- givenNavigationStates = listOf (
110- NavigationState .FreeDrive
111- )
112- ) { s, action ->
113- assertEquals(" $s |top" , action.padding.top, PADDING_V_LAND , 0.001 )
114- assertNotEquals(" $s |bottom" , action.padding.bottom, PADDING_V_LAND , 0.001 )
115- assertEquals(" $s |left" , action.padding.left, PADDING_H_LAND , 0.001 )
116- assertEquals(" $s |right" , action.padding.right, PADDING_H_LAND , 0.001 )
117- }
97+ infoPanelBehavior.updateBottomSheetState(BottomSheetBehavior .STATE_COLLAPSED )
98+ binding.coordinatorLayout.triggerLayoutChange()
99+
100+ val action = store.actions.last() as CameraAction .UpdatePadding
101+ assertEquals(" left" , 500 + paddingH, action.padding.left, 0.001 )
102+ assertEquals(" top" , paddingV, action.padding.top, 0.001 )
103+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
104+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
118105 }
119106
120107 @Test
121108 @Config(qualifiers = " land" )
122- fun `landscape - should update left and bottom padding for all states except FreeDrive ` () =
109+ fun `landscape - should update camera paddings when bottom sheet is hidden ` () =
123110 coroutineRule.runBlockingTest {
124111 sut.onAttached(mockk())
125112
126- triggerLayoutChangesAndVerifyDispatchedActions(
127- givenNavigationStates = listOf (
128- NavigationState .DestinationPreview ,
129- NavigationState .RoutePreview ,
130- NavigationState .ActiveNavigation ,
131- NavigationState .Arrival ,
132- )
133- ) { s, action ->
134- assertEquals(" $s |top" , action.padding.top, PADDING_V_LAND , 0.001 )
135- assertNotEquals(" $s |bottom" , action.padding.bottom, PADDING_V_LAND , 0.001 )
136- assertNotEquals(" $s |left" , action.padding.left, PADDING_H_LAND , 0.001 )
137- assertEquals(" $s |right" , action.padding.right, PADDING_H_LAND , 0.001 )
138- }
139- }
140-
141- private suspend fun triggerLayoutChangesAndVerifyDispatchedActions (
142- givenNavigationStates : List <NavigationState >,
143- assertAction : (state: NavigationState , action: CameraAction .UpdatePadding ) -> Unit
144- ) {
145- givenNavigationStates.forEachIndexed { index, navState ->
146- store.updateState { it.copy(navigation = navState) }
113+ infoPanelBehavior.updateBottomSheetState(BottomSheetBehavior .STATE_HIDDEN )
147114 binding.coordinatorLayout.triggerLayoutChange()
148- assertAction(navState, store.actions[index] as CameraAction .UpdatePadding )
115+
116+ val action = store.actions.last() as CameraAction .UpdatePadding
117+ assertEquals(" left" , paddingH, action.padding.left, 0.001 )
118+ assertEquals(" top" , paddingV, action.padding.top, 0.001 )
119+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
120+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
149121 }
150- }
151122
152123 private suspend fun View.triggerLayoutChange () = coroutineScope {
153124 launch {
@@ -158,34 +129,13 @@ class CameraLayoutObserverTest {
158129 }
159130
160131 private suspend fun View.waitForLayoutChange () = suspendCancellableCoroutine<Unit > { cont ->
161- addOnLayoutChangeListener(object : OnLayoutChangeListener {
162- override fun onLayoutChange (
163- v : View ? ,
164- left : Int ,
165- top : Int ,
166- right : Int ,
167- bottom : Int ,
168- oldLeft : Int ,
169- oldTop : Int ,
170- oldRight : Int ,
171- oldBottom : Int
172- ) {
173- cont.resume(Unit )
174- removeOnLayoutChangeListener(this )
175- }
176- })
132+ doOnNextLayout { cont.resume(Unit ) }
177133 }
178134
179- private val PADDING_V_PORT : Double
135+ private val paddingV : Double
180136 get() = binding.root.resources
181137 .getDimensionPixelSize(R .dimen.mapbox_camera_overview_padding_v).toDouble()
182- private val PADDING_H_PORT : Double
138+ private val paddingH : Double
183139 get() = binding.root.resources
184140 .getDimensionPixelSize(R .dimen.mapbox_camera_overview_padding_h).toDouble()
185- private val PADDING_V_LAND : Double
186- get() = binding.root.resources
187- .getDimensionPixelSize(R .dimen.mapbox_camera_overview_padding_landscape_v).toDouble()
188- private val PADDING_H_LAND : Double
189- get() = binding.root.resources
190- .getDimensionPixelSize(R .dimen.mapbox_camera_overview_padding_landscape_h).toDouble()
191141}
0 commit comments