From 1eb011110c0e645820539ce0ce9c7762cd325cdf Mon Sep 17 00:00:00 2001 From: jackcurtis Date: Mon, 2 Dec 2024 15:32:55 -0500 Subject: [PATCH] add missing tests and fix some found issues --- .../{util => state}/GetGlobalDataTest.kt | 3 +- .../mbta_app/android/state/GetNearbyTest.kt | 71 +++++++++++++++++++ .../android/state/GetRailRouteShapesTest.kt | 62 ++++++++++++++++ .../{util => state}/GetScheduleTest.kt | 3 +- .../android/state/GetStopMapDataTest.kt | 37 ++++++++++ .../android/state/SubscribeToAlertsTest.kt | 44 ++++++++++++ .../SubscribeToPredictionsTest.kt | 3 +- .../mbta_app/android/state/getGlobalData.kt | 5 +- .../android/state/getRailRouteShapes.kt | 3 +- .../tid/mbta_app/android/state/getSchedule.kt | 3 +- .../mbta_app/android/state/getStopMapData.kt | 18 ++--- 11 files changed, 230 insertions(+), 22 deletions(-) rename androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/{util => state}/GetGlobalDataTest.kt (94%) create mode 100644 androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetNearbyTest.kt create mode 100644 androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetRailRouteShapesTest.kt rename androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/{util => state}/GetScheduleTest.kt (95%) create mode 100644 androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetStopMapDataTest.kt create mode 100644 androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToAlertsTest.kt rename androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/{util => state}/SubscribeToPredictionsTest.kt (97%) diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetGlobalDataTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt similarity index 94% rename from androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetGlobalDataTest.kt rename to androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt index 32983facc..a9c035c80 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetGlobalDataTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt @@ -1,7 +1,6 @@ -package com.mbta.tid.mbta_app.android.util +package com.mbta.tid.mbta_app.android.state import androidx.compose.ui.test.junit4.createComposeRule -import com.mbta.tid.mbta_app.android.state.getGlobalData import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder import com.mbta.tid.mbta_app.model.response.ApiResult import com.mbta.tid.mbta_app.model.response.GlobalResponse diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetNearbyTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetNearbyTest.kt new file mode 100644 index 000000000..e628c168f --- /dev/null +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetNearbyTest.kt @@ -0,0 +1,71 @@ +package com.mbta.tid.mbta_app.android.state + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.test.junit4.createComposeRule +import com.mbta.tid.mbta_app.model.Coordinate +import com.mbta.tid.mbta_app.model.NearbyStaticData +import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder +import com.mbta.tid.mbta_app.model.response.ApiResult +import com.mbta.tid.mbta_app.model.response.GlobalResponse +import com.mbta.tid.mbta_app.model.response.NearbyResponse +import com.mbta.tid.mbta_app.repositories.INearbyRepository +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class GetNearbyTest { + @get:Rule val composeTestRule = createComposeRule() + + @Test + fun testNearby() = runTest { + val builder1 = ObjectCollectionBuilder() + + val globalResponse = GlobalResponse(builder1) + + val builder2 = ObjectCollectionBuilder() + + val coordinate1 = Coordinate(0.0, 0.0) + val coordinate2 = Coordinate(1.0, 1.0) + + val nearbyRepository = + object : INearbyRepository { + override suspend fun getNearby( + globalResponse: GlobalResponse, + location: Coordinate + ): ApiResult { + if (location == coordinate1) { + return ApiResult.Ok( + NearbyStaticData(globalResponse, NearbyResponse(builder1)) + ) + } else { + return ApiResult.Ok( + NearbyStaticData(globalResponse, NearbyResponse(builder2)) + ) + } + } + } + + var coordinate by mutableStateOf(coordinate1) + var actualNearby: NearbyStaticData? = null + + composeTestRule.setContent { + actualNearby = + getNearby( + globalResponse = globalResponse, + location = coordinate1, + setLastLocation = { /* null-op */}, + nearbyRepository = nearbyRepository + ) + } + + composeTestRule.awaitIdle() + assertEquals(NearbyStaticData(globalResponse, NearbyResponse(builder1)), actualNearby) + + coordinate = coordinate2 + composeTestRule.awaitIdle() + assertEquals(NearbyStaticData(globalResponse, NearbyResponse(builder2)), actualNearby) + } +} diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetRailRouteShapesTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetRailRouteShapesTest.kt new file mode 100644 index 000000000..df2f196e7 --- /dev/null +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetRailRouteShapesTest.kt @@ -0,0 +1,62 @@ +package com.mbta.tid.mbta_app.android.state + +import androidx.compose.ui.test.junit4.createComposeRule +import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder +import com.mbta.tid.mbta_app.model.SegmentedRouteShape +import com.mbta.tid.mbta_app.model.response.ApiResult +import com.mbta.tid.mbta_app.model.response.MapFriendlyRouteResponse +import com.mbta.tid.mbta_app.repositories.IRailRouteShapeRepository +import kotlin.test.assertEquals +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class GetRailRouteShapesTest { + @get:Rule val composeTestRule = createComposeRule() + + @Test + fun testRailRouteShapes() = runTest { + val builder = ObjectCollectionBuilder() + val route = builder.route() + val routePattern = builder.routePattern(route) + val mapFriendlyRouteResponse = + MapFriendlyRouteResponse( + listOf( + MapFriendlyRouteResponse.RouteWithSegmentedShapes( + route.id, + listOf( + SegmentedRouteShape( + routePattern.id, + route.id, + 1, + listOf(), + builder.shape() + ) + ) + ) + ) + ) + val railRouteShapeRepository = + object : IRailRouteShapeRepository { + override val state: StateFlow + get() { + /* null-op */ + return MutableStateFlow(null) + } + + override suspend fun getRailRouteShapes(): ApiResult { + return ApiResult.Ok(mapFriendlyRouteResponse) + } + } + + var actualRailRouteShapes: MapFriendlyRouteResponse? = null + composeTestRule.setContent { + actualRailRouteShapes = getRailRouteShapes(railRouteShapeRepository) + } + + composeTestRule.awaitIdle() + assertEquals(mapFriendlyRouteResponse, actualRailRouteShapes) + } +} diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetScheduleTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt similarity index 95% rename from androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetScheduleTest.kt rename to androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt index ee4b02cd4..aaa848c6e 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/GetScheduleTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt @@ -1,10 +1,9 @@ -package com.mbta.tid.mbta_app.android.util +package com.mbta.tid.mbta_app.android.state import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.test.junit4.createComposeRule -import com.mbta.tid.mbta_app.android.state.getSchedule import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder import com.mbta.tid.mbta_app.model.response.ApiResult import com.mbta.tid.mbta_app.model.response.ScheduleResponse diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetStopMapDataTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetStopMapDataTest.kt new file mode 100644 index 000000000..60a8e0821 --- /dev/null +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetStopMapDataTest.kt @@ -0,0 +1,37 @@ +package com.mbta.tid.mbta_app.android.state + +import androidx.compose.ui.test.junit4.createComposeRule +import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder +import com.mbta.tid.mbta_app.model.response.ApiResult +import com.mbta.tid.mbta_app.model.response.StopMapResponse +import com.mbta.tid.mbta_app.repositories.IStopRepository +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class GetStopMapDataTest { + @get:Rule val composeTestRule = createComposeRule() + + @Test + fun testStopMapData() = runTest { + val builder = ObjectCollectionBuilder() + val stop = builder.stop() + val stopMapResponse = StopMapResponse(listOf(), mapOf(stop.id to stop)) + + val stopRepository = + object : IStopRepository { + override suspend fun getStopMapData(stopId: String): ApiResult { + return ApiResult.Ok(stopMapResponse) + } + } + + var actualStopMapResponse: StopMapResponse? = null + composeTestRule.setContent { + actualStopMapResponse = getStopMapData(stop.id, stopRepository) + } + + composeTestRule.awaitIdle() + assertEquals(stopMapResponse, actualStopMapResponse) + } +} diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToAlertsTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToAlertsTest.kt new file mode 100644 index 000000000..ad39bff00 --- /dev/null +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToAlertsTest.kt @@ -0,0 +1,44 @@ +package com.mbta.tid.mbta_app.android.state + +import androidx.compose.ui.test.junit4.createComposeRule +import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder +import com.mbta.tid.mbta_app.model.response.AlertsStreamDataResponse +import com.mbta.tid.mbta_app.model.response.ApiResult +import com.mbta.tid.mbta_app.repositories.IAlertsRepository +import kotlin.test.assertEquals +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import org.junit.Rule +import org.junit.Test + +class SubscribeToAlertsTest { + @get:Rule val composeRule = createComposeRule() + + @Test + fun testAlerts() = runTest { + val builder = ObjectCollectionBuilder() + builder.alert { + id = "1" + header = "Alert 1" + description = "Description 1" + } + val alertsStreamDataResponse = AlertsStreamDataResponse(builder) + + val alertsRepo = + object : IAlertsRepository { + override fun connect(onReceive: (ApiResult) -> Unit) { + launch { onReceive(ApiResult.Ok(alertsStreamDataResponse)) } + } + + override fun disconnect() { + { /* null-op */} + } + } + + var actualData: AlertsStreamDataResponse? = null + composeRule.setContent { actualData = subscribeToAlerts(alertsRepo) } + + composeRule.awaitIdle() + assertEquals(alertsStreamDataResponse, actualData) + } +} diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/SubscribeToPredictionsTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt similarity index 97% rename from androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/SubscribeToPredictionsTest.kt rename to androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt index 7144211dd..def67d8bf 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/util/SubscribeToPredictionsTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt @@ -1,10 +1,9 @@ -package com.mbta.tid.mbta_app.android.util +package com.mbta.tid.mbta_app.android.state import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.ui.test.junit4.createComposeRule -import com.mbta.tid.mbta_app.android.state.subscribeToPredictions import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder import com.mbta.tid.mbta_app.model.response.ApiResult import com.mbta.tid.mbta_app.model.response.PredictionsByStopJoinResponse diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getGlobalData.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getGlobalData.kt index f49c5c598..d90b99f32 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getGlobalData.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getGlobalData.kt @@ -10,12 +10,13 @@ import com.mbta.tid.mbta_app.repositories.IGlobalRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import org.koin.compose.koinInject class GlobalDataViewModel(private val globalRepository: IGlobalRepository) : ViewModel() { private val _globalResponse = MutableStateFlow(null) - var globalResponse: MutableStateFlow = _globalResponse + var globalResponse: StateFlow = _globalResponse init { CoroutineScope(Dispatchers.IO).launch { globalResponse.collect { getGlobalData() } } @@ -23,7 +24,7 @@ class GlobalDataViewModel(private val globalRepository: IGlobalRepository) : Vie suspend fun getGlobalData() { when (val data = globalRepository.getGlobalData()) { - is ApiResult.Ok -> globalResponse.emit(data.data) + is ApiResult.Ok -> _globalResponse.emit(data.data) is ApiResult.Error -> TODO("handle errors") } } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getRailRouteShapes.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getRailRouteShapes.kt index 5edd23b90..d675e36f7 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getRailRouteShapes.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getRailRouteShapes.kt @@ -12,6 +12,7 @@ import com.mbta.tid.mbta_app.repositories.IRailRouteShapeRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import org.koin.compose.koinInject @@ -20,7 +21,7 @@ class RailRouteShapesViewModel(private val railRouteShapeRepository: IRailRouteS ViewModel() { private val _railRouteShapes: MutableStateFlow = MutableStateFlow(null) - val railRouteShapes = _railRouteShapes + val railRouteShapes: StateFlow = _railRouteShapes init { CoroutineScope(Dispatchers.IO).launch { railRouteShapes.collect { getRailRouteShapes() } } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getSchedule.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getSchedule.kt index 249608761..b66e72d00 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getSchedule.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getSchedule.kt @@ -12,6 +12,7 @@ import com.mbta.tid.mbta_app.repositories.ISchedulesRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.datetime.Clock @@ -22,7 +23,7 @@ class ScheduleViewModel( private val schedulesRepository: ISchedulesRepository ) : ViewModel() { private val _schedule = MutableStateFlow(null) - val schedule = _schedule + val schedule: StateFlow = _schedule init { CoroutineScope(Dispatchers.IO).launch { schedule.collect { getSchedule(stopIds) } } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getStopMapData.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getStopMapData.kt index 60578bdb8..f2b9a8852 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getStopMapData.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/getStopMapData.kt @@ -1,7 +1,6 @@ package com.mbta.tid.mbta_app.android.state import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.remember @@ -12,13 +11,14 @@ import com.mbta.tid.mbta_app.model.response.StopMapResponse import com.mbta.tid.mbta_app.repositories.IStopRepository import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch import org.koin.compose.koinInject class StopMapViewModel(private val stopRepository: IStopRepository, stopId: String) : ViewModel() { - private val _stopMapResponse = MutableSharedFlow(replay = 0) - val stopMapResponse = _stopMapResponse + private val _stopMapResponse = MutableStateFlow(null) + val stopMapResponse: StateFlow = _stopMapResponse init { CoroutineScope(Dispatchers.IO).launch { stopMapResponse.collect { getStopMapData(stopId) } } @@ -34,16 +34,10 @@ class StopMapViewModel(private val stopRepository: IStopRepository, stopId: Stri @Composable fun getStopMapData( + stopId: String, stopRepository: IStopRepository = koinInject(), - stopId: String ): StopMapResponse? { - var viewModel: StopMapViewModel? = remember { null } - - DisposableEffect(stopId) { - viewModel = StopMapViewModel(stopRepository, stopId) - - onDispose { viewModel = null } - } + val viewModel: StopMapViewModel? = remember(stopId) { StopMapViewModel(stopRepository, stopId) } return viewModel?.stopMapResponse?.collectAsState(initial = null)?.value }