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,66 @@ 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
5762 }
58- mapView = View (context)
63+ mapView = View (context). apply { bottom = 1000 }
5964 store = TestStore ()
60- sut = CameraLayoutObserver (store, mapView, binding)
65+ val navContext = NavigationViewContext (
66+ context,
67+ TestLifecycleOwner (),
68+ NavigationViewModel (),
69+ ) { store }
70+ infoPanelBehavior = navContext.behavior.infoPanelBehavior
71+ sut = CameraLayoutObserver (navContext, mapView, binding)
6172 }
6273
6374 @Test
6475 @Config(qualifiers = " port" )
65- fun `portrait - should update bottom padding for DestinationPreview, FreeDrive and RoutePreview state ` () =
76+ fun `portrait - should update camera paddings ` () =
6677 coroutineRule.runBlockingTest {
6778 sut.onAttached(mockk())
6879
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())
80+ binding.coordinatorLayout.triggerLayoutChange()
8881
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- }
82+ val action = store.actions.last() as CameraAction .UpdatePadding
83+ assertEquals(" left" , paddingH, action.padding.left, 0.001 )
84+ assertEquals(" top" , 100 + paddingV, action.padding.top, 0.001 )
85+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
86+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
10087 }
10188
10289 @Test
10390 @Config(qualifiers = " land" )
104- fun `landscape - should update bottom padding for FreeDrive state ` () =
91+ fun `landscape - should update camera paddings when bottom sheet is collapsed ` () =
10592 coroutineRule.runBlockingTest {
10693 sut.onAttached(mockk())
10794
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- }
95+ infoPanelBehavior.updateBottomSheetState(BottomSheetBehavior .STATE_COLLAPSED )
96+ binding.coordinatorLayout.triggerLayoutChange()
97+
98+ val action = store.actions.last() as CameraAction .UpdatePadding
99+ assertEquals(" left" , 500 + paddingH, action.padding.left, 0.001 )
100+ assertEquals(" top" , paddingV, action.padding.top, 0.001 )
101+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
102+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
118103 }
119104
120105 @Test
121106 @Config(qualifiers = " land" )
122- fun `landscape - should update left and bottom padding for all states except FreeDrive ` () =
107+ fun `landscape - should update camera paddings when bottom sheet is hidden ` () =
123108 coroutineRule.runBlockingTest {
124109 sut.onAttached(mockk())
125110
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) }
111+ infoPanelBehavior.updateBottomSheetState(BottomSheetBehavior .STATE_HIDDEN )
147112 binding.coordinatorLayout.triggerLayoutChange()
148- assertAction(navState, store.actions[index] as CameraAction .UpdatePadding )
113+
114+ val action = store.actions.last() as CameraAction .UpdatePadding
115+ assertEquals(" left" , paddingH, action.padding.left, 0.001 )
116+ assertEquals(" top" , paddingV, action.padding.top, 0.001 )
117+ assertEquals(" right" , paddingH, action.padding.right, 0.001 )
118+ assertEquals(" bottom" , 100 + paddingV, action.padding.bottom, 0.001 )
149119 }
150- }
151120
152121 private suspend fun View.triggerLayoutChange () = coroutineScope {
153122 launch {
@@ -158,34 +127,13 @@ class CameraLayoutObserverTest {
158127 }
159128
160129 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- })
130+ doOnNextLayout { cont.resume(Unit ) }
177131 }
178132
179- private val PADDING_V_PORT : Double
133+ private val paddingV : Double
180134 get() = binding.root.resources
181135 .getDimensionPixelSize(R .dimen.mapbox_camera_overview_padding_v).toDouble()
182- private val PADDING_H_PORT : Double
136+ private val paddingH : Double
183137 get() = binding.root.resources
184138 .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()
191139}
0 commit comments