From 0c9883c67ab7ef247b045db1d9508c0cb713937c Mon Sep 17 00:00:00 2001 From: Kayla Brady <31781298+KaylaBrady@users.noreply.github.com> Date: Tue, 14 Jan 2025 10:13:29 -0500 Subject: [PATCH] fix(StopDetailsPage): Distinct errorKeys from API requests on NearbyTransitPage (#641) * fix(android.StopDetailsPage): Separate errorKeys from NearbyTransitView fetchces * fix(subscribeToPredictions): periodically check predictions stale * cleanup: merge conflict linting * fix(MockErrorBannerStateRepository): Default argument interop * fix(MockGlobalRepository): Default argument interop enabled --- .../android/state/GetGlobalDataTest.kt | 21 ++++++++++- .../mbta_app/android/state/GetScheduleTest.kt | 24 +++++++++++-- .../state/SubscribeToPredictionsTest.kt | 36 +++++++++++++++++++ .../mbta/tid/mbta_app/android/ContentView.kt | 2 +- .../nearbyTransit/NearbyTransitView.kt | 4 +-- .../mbta_app/android/pages/StopDetailsPage.kt | 4 +-- .../android/search/SearchBarOverlay.kt | 2 +- .../mbta_app/android/state/getGlobalData.kt | 9 ++--- .../tid/mbta_app/android/state/getSchedule.kt | 9 ++--- .../android/state/subscribeToPredictions.kt | 31 ++++++++++------ .../android/stopDetails/StopDetailsView.kt | 2 +- .../ErrorBannerStateRepository.kt | 18 ++++++++-- .../mbta_app/repositories/GlobalRepository.kt | 24 +++++++++---- .../repositories/SchedulesRepository.kt | 14 ++++++-- 14 files changed, 160 insertions(+), 40 deletions(-) diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt index 5b2a49661..5eb8e6bde 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetGlobalDataTest.kt @@ -1,10 +1,13 @@ package com.mbta.tid.mbta_app.android.state import androidx.compose.ui.test.junit4.createComposeRule +import com.mbta.tid.mbta_app.model.ErrorBannerState 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.repositories.IGlobalRepository +import com.mbta.tid.mbta_app.repositories.MockErrorBannerStateRepository +import com.mbta.tid.mbta_app.repositories.MockGlobalRepository import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -39,7 +42,7 @@ class GetGlobalDataTest { } var actualData: GlobalResponse? = globalData - composeTestRule.setContent { actualData = getGlobalData(globalRepo) } + composeTestRule.setContent { actualData = getGlobalData("errorKey", globalRepo) } composeTestRule.awaitIdle() assertNull(actualData) @@ -49,4 +52,20 @@ class GetGlobalDataTest { composeTestRule.waitUntil { globalData == actualData } assertEquals(globalData, actualData) } + + @Test + fun testApiError() = runTest { + val globalRepo = MockGlobalRepository(ApiResult.Error(500, "oops")) + + val errorRepo = MockErrorBannerStateRepository() + + composeTestRule.setContent { getGlobalData("errorKey", globalRepo, errorRepo) } + + composeTestRule.waitUntil { + when (val errorState = errorRepo.state.value) { + is ErrorBannerState.DataError -> errorState.messages == setOf("errorKey") + else -> false + } + } + } } diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt index 920265462..cc9828a6a 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/GetScheduleTest.kt @@ -4,10 +4,12 @@ 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.ErrorBannerState 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 import com.mbta.tid.mbta_app.repositories.ISchedulesRepository +import com.mbta.tid.mbta_app.repositories.MockErrorBannerStateRepository import com.mbta.tid.mbta_app.repositories.MockScheduleRepository import kotlin.test.assertNotNull import kotlinx.coroutines.test.runTest @@ -53,7 +55,7 @@ class GetScheduleTest { var stopIds by mutableStateOf(stops1) var actualSchedules: ScheduleResponse? = expectedSchedules1 composeTestRule.setContent { - actualSchedules = getSchedule(stopIds = stopIds, schedulesRepo) + actualSchedules = getSchedule(stopIds = stopIds, "errorKey", schedulesRepo) } composeTestRule.awaitIdle() @@ -73,10 +75,28 @@ class GetScheduleTest { var actualSchedules: ScheduleResponse? = null composeTestRule.setContent { - actualSchedules = getSchedule(stopIds = emptyList(), schedulesRepo) + actualSchedules = getSchedule(stopIds = emptyList(), "errorKey", schedulesRepo) } composeTestRule.waitUntil { actualSchedules != null } assertNotNull(actualSchedules) } + + @Test + fun testErrorCase() { + val schedulesRepo = MockScheduleRepository(ApiResult.Error(500, "oops")) + + val errorRepo = MockErrorBannerStateRepository() + + composeTestRule.setContent { + getSchedule(stopIds = listOf("stop1"), "errorKey", schedulesRepo, errorRepo) + } + + composeTestRule.waitUntil { + when (val errorState = errorRepo.state.value) { + is ErrorBannerState.DataError -> errorState.messages == setOf("errorKey") + else -> false + } + } + } } diff --git a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt index d1020bb63..fbfe71a00 100644 --- a/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt +++ b/androidApp/src/androidTest/java/com/mbta/tid/mbta_app/android/state/SubscribeToPredictionsTest.kt @@ -20,7 +20,9 @@ import com.mbta.tid.mbta_app.repositories.MockPredictionsRepository import com.mbta.tid.mbta_app.repositories.MockSettingsRepository import kotlin.test.assertNotNull import kotlin.test.assertTrue +import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.test.runTest +import kotlinx.datetime.Clock import org.junit.Assert.assertEquals import org.junit.Rule import org.junit.Test @@ -165,4 +167,38 @@ class SubscribeToPredictionsTest { assertNotNull(predictions) assertTrue(connected) } + + @Test + fun testCheckPredictionsStaleCalled() = runTest { + val objects = ObjectCollectionBuilder() + objects.prediction() + val predictionsOnJoin = PredictionsByStopJoinResponse(objects) + val predictionsRepo = MockPredictionsRepository({}, {}, {}, null, predictionsOnJoin) + + predictionsRepo.lastUpdated = Clock.System.now() + + var stopIds = mutableStateOf(listOf("place-a")) + + var checkPredictionsStaleCount = 0 + val mockErrorRepo = + MockErrorBannerStateRepository( + onCheckPredictionsStale = { checkPredictionsStaleCount += 1 } + ) + + composeTestRule.setContent { + var stopIds by remember { stopIds } + subscribeToPredictions( + stopIds, + predictionsRepo, + ErrorBannerViewModel( + false, + mockErrorRepo, + MockSettingsRepository(), + ), + 1.seconds + ) + } + + composeTestRule.waitUntil(timeoutMillis = 3000) { checkPredictionsStaleCount >= 2 } + } } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/ContentView.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/ContentView.kt index 005b52ef7..6b71b3a34 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/ContentView.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/ContentView.kt @@ -44,7 +44,7 @@ fun ContentView( ) { val navController = rememberNavController() val alertData: AlertsStreamDataResponse? = subscribeToAlerts() - val globalResponse = getGlobalData() + val globalResponse = getGlobalData("ContentView.getGlobalData") val hideMaps by viewModel.hideMaps.collectAsState() val pendingOnboarding = viewModel.pendingOnboarding.collectAsState().value val locationDataManager = rememberLocationDataManager() diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/nearbyTransit/NearbyTransitView.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/nearbyTransit/NearbyTransitView.kt index e3faa284b..5d3cf641b 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/nearbyTransit/NearbyTransitView.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/nearbyTransit/NearbyTransitView.kt @@ -66,15 +66,15 @@ fun NearbyTransitView( } val now = timer(updateInterval = 5.seconds) val stopIds = remember(nearbyVM.nearby) { nearbyVM.nearby?.stopIds()?.toList() } - val schedules = getSchedule(stopIds) + val schedules = getSchedule(stopIds, "NearbyTransitView.getSchedule") val predictionsVM = subscribeToPredictions(stopIds, errorBannerViewModel = errorBannerViewModel) val predictions by predictionsVM.predictionsFlow.collectAsState(initial = null) + LaunchedEffect(targetLocation == null) { if (targetLocation == null) { predictionsVM.reset() } } - val (pinnedRoutes, togglePinnedRoute) = managePinnedRoutes() val nearbyWithRealtimeInfo = diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/pages/StopDetailsPage.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/pages/StopDetailsPage.kt index f52cf5a06..06a6bfef2 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/pages/StopDetailsPage.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/pages/StopDetailsPage.kt @@ -36,7 +36,7 @@ fun StopDetailsPage( updateDepartures: (StopDetailsDepartures?) -> Unit, errorBannerViewModel: ErrorBannerViewModel ) { - val globalResponse = getGlobalData() + val globalResponse = getGlobalData("StopDetailsPage.getGlobalData") val predictionsVM = subscribeToPredictions( @@ -47,7 +47,7 @@ fun StopDetailsPage( val now = timer(updateInterval = 5.seconds) - val schedulesResponse = getSchedule(stopIds = listOf(stop.id)) + val schedulesResponse = getSchedule(stopIds = listOf(stop.id), "StopDetailsPage.getSchedule") val (pinnedRoutes, togglePinnedRoute) = managePinnedRoutes() diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/search/SearchBarOverlay.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/search/SearchBarOverlay.kt index 86946d673..a4707ed9a 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/search/SearchBarOverlay.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/search/SearchBarOverlay.kt @@ -59,7 +59,7 @@ fun SearchBarOverlay( } var expanded by rememberSaveable { mutableStateOf(false) } var searchInputState by rememberSaveable { mutableStateOf("") } - val globalResponse = getGlobalData() + val globalResponse = getGlobalData("SearchBar.getGlobalData") val searchResultsVm = getSearchResultsVm(globalResponse = globalResponse) val searchResults = searchResultsVm.searchResults.collectAsState(initial = null).value 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 7a97aba7c..bf328ce77 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 @@ -24,14 +24,14 @@ class GlobalDataViewModel( private val _globalResponse = MutableStateFlow(null) var globalResponse: StateFlow = _globalResponse - fun getGlobalData() { + fun getGlobalData(errorKey: String) { CoroutineScope(Dispatchers.IO).launch { fetchApi( errorBannerRepo = errorBannerRepository, - errorKey = "GlobalDataViewModel.getGlobalData", + errorKey = errorKey, getData = { globalRepository.getGlobalData() }, onSuccess = { _globalResponse.emit(it) }, - onRefreshAfterError = { getGlobalData() } + onRefreshAfterError = { getGlobalData(errorKey) } ) } } @@ -48,12 +48,13 @@ class GlobalDataViewModel( @Composable fun getGlobalData( + errorKey: String, globalRepository: IGlobalRepository = koinInject(), errorBannerRepository: IErrorBannerStateRepository = koinInject() ): GlobalResponse? { val viewModel: GlobalDataViewModel = viewModel(factory = GlobalDataViewModel.Factory(globalRepository, errorBannerRepository)) - LaunchedEffect(key1 = null) { viewModel.getGlobalData() } + LaunchedEffect(key1 = null) { viewModel.getGlobalData(errorKey) } return viewModel.globalResponse.collectAsState(initial = null).value } 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 aad838677..22b922b42 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 @@ -25,15 +25,15 @@ class ScheduleViewModel( private val _schedule = MutableStateFlow(null) val schedule: StateFlow = _schedule - fun getSchedule(stopIds: List) { + fun getSchedule(stopIds: List, errorKey: String) { if (stopIds.isNotEmpty()) { CoroutineScope(Dispatchers.IO).launch { fetchApi( errorBannerRepo = errorBannerRepository, - errorKey = "ScheduleViewModel.getSchedule", + errorKey = errorKey, getData = { schedulesRepository.getSchedule(stopIds, Clock.System.now()) }, onSuccess = { _schedule.value = it }, - onRefreshAfterError = { getSchedule(stopIds) } + onRefreshAfterError = { getSchedule(stopIds, errorKey) } ) } } else { @@ -54,13 +54,14 @@ class ScheduleViewModel( @Composable fun getSchedule( stopIds: List?, + errorKey: String, schedulesRepository: ISchedulesRepository = koinInject(), errorBannerRepository: IErrorBannerStateRepository = koinInject(), ): ScheduleResponse? { var viewModel: ScheduleViewModel = viewModel(factory = ScheduleViewModel.Factory(schedulesRepository, errorBannerRepository)) - LaunchedEffect(key1 = stopIds) { viewModel.getSchedule(stopIds ?: emptyList()) } + LaunchedEffect(key1 = stopIds) { viewModel.getSchedule(stopIds ?: emptyList(), errorKey) } return viewModel?.schedule?.collectAsState(initial = null)?.value } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/subscribeToPredictions.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/subscribeToPredictions.kt index 48c1eb40b..21c70cc20 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/subscribeToPredictions.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/state/subscribeToPredictions.kt @@ -2,15 +2,18 @@ package com.mbta.tid.mbta_app.android.state import android.util.Log import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.compose.LifecycleResumeEffect import androidx.lifecycle.viewmodel.compose.viewModel import com.mbta.tid.mbta_app.android.component.ErrorBannerViewModel +import com.mbta.tid.mbta_app.android.util.timer import com.mbta.tid.mbta_app.model.response.ApiResult import com.mbta.tid.mbta_app.model.response.PredictionsByStopJoinResponse import com.mbta.tid.mbta_app.model.response.PredictionsByStopMessageResponse import com.mbta.tid.mbta_app.repositories.IPredictionsRepository +import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -94,15 +97,17 @@ class PredictionsViewModel( } fun checkPredictionsStale() { - predictionsRepository.lastUpdated?.let { lastPredictions -> - errorBannerViewModel.errorRepository.checkPredictionsStale( - predictionsLastUpdated = lastPredictions, - predictionQuantity = predictions.value?.predictionQuantity() ?: 0, - action = { - disconnect() - connect(currentStopIds) - } - ) + CoroutineScope(Dispatchers.IO).launch { + predictionsRepository.lastUpdated?.let { lastPredictions -> + errorBannerViewModel.errorRepository.checkPredictionsStale( + predictionsLastUpdated = lastPredictions, + predictionQuantity = predictions.value?.predictionQuantity() ?: 0, + action = { + disconnect() + connect(currentStopIds) + } + ) + } } } @@ -120,13 +125,16 @@ class PredictionsViewModel( fun subscribeToPredictions( stopIds: List?, predictionsRepository: IPredictionsRepository = koinInject(), - errorBannerViewModel: ErrorBannerViewModel + errorBannerViewModel: ErrorBannerViewModel, + checkPredictionsStaleInterval: Duration = 5.seconds ): PredictionsViewModel { val viewModel: PredictionsViewModel = viewModel( factory = PredictionsViewModel.Factory(predictionsRepository, errorBannerViewModel) ) + val timer = timer(checkPredictionsStaleInterval) + LifecycleResumeEffect(key1 = stopIds) { CoroutineScope(Dispatchers.IO).launch { viewModel.checkPredictionsStale() @@ -135,5 +143,8 @@ fun subscribeToPredictions( onPauseOrDispose { viewModel.disconnect() } } + + LaunchedEffect(key1 = timer) { viewModel.checkPredictionsStale() } + return viewModel } diff --git a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/stopDetails/StopDetailsView.kt b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/stopDetails/StopDetailsView.kt index 85063b551..65eb6988d 100644 --- a/androidApp/src/main/java/com/mbta/tid/mbta_app/android/stopDetails/StopDetailsView.kt +++ b/androidApp/src/main/java/com/mbta/tid/mbta_app/android/stopDetails/StopDetailsView.kt @@ -33,7 +33,7 @@ fun StopDetailsView( updateStopFilter: (StopDetailsFilter?) -> Unit, errorBannerViewModel: ErrorBannerViewModel ) { - val globalResponse = getGlobalData() + val globalResponse = getGlobalData("SopDetailsView.getGlobalData") val now = timer(updateInterval = 5.seconds) diff --git a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/ErrorBannerStateRepository.kt b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/ErrorBannerStateRepository.kt index c816d5062..daa7eb035 100644 --- a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/ErrorBannerStateRepository.kt +++ b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/ErrorBannerStateRepository.kt @@ -1,5 +1,6 @@ package com.mbta.tid.mbta_app.repositories +import co.touchlab.skie.configuration.annotations.DefaultArgumentInterop import com.mbta.tid.mbta_app.model.ErrorBannerState import com.mbta.tid.mbta_app.network.INetworkConnectivityMonitor import kotlin.time.Duration.Companion.minutes @@ -52,7 +53,7 @@ abstract class IErrorBannerStateRepository(initialState: ErrorBannerState? = nul } } - fun checkPredictionsStale( + open fun checkPredictionsStale( predictionsLastUpdated: Instant, predictionQuantity: Int, action: () -> Unit @@ -90,15 +91,28 @@ abstract class IErrorBannerStateRepository(initialState: ErrorBannerState? = nul class ErrorBannerStateRepository : IErrorBannerStateRepository(), KoinComponent -class MockErrorBannerStateRepository( +class MockErrorBannerStateRepository +@DefaultArgumentInterop.Enabled +constructor( state: ErrorBannerState? = null, onSubscribeToNetworkChanges: (() -> Unit)? = null, + onCheckPredictionsStale: (() -> Unit)? = null ) : IErrorBannerStateRepository(state) { private val onSubscribeToNetworkChanges = onSubscribeToNetworkChanges + private val onCheckPredictionsStale = onCheckPredictionsStale + val mutableFlow get() = flow override fun subscribeToNetworkStatusChanges() { onSubscribeToNetworkChanges?.invoke() } + + override fun checkPredictionsStale( + predictionsLastUpdated: Instant, + predictionQuantity: Int, + action: () -> Unit + ) { + onCheckPredictionsStale?.invoke() + } } diff --git a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/GlobalRepository.kt b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/GlobalRepository.kt index 96e675be4..5b95fb249 100644 --- a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/GlobalRepository.kt +++ b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/GlobalRepository.kt @@ -39,16 +39,26 @@ class GlobalRepository( class MockGlobalRepository @DefaultArgumentInterop.Enabled -constructor( - val response: GlobalResponse = - GlobalResponse(emptyMap(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), emptyMap()), - val onGet: () -> Unit = {} -) : IGlobalRepository { - override val state = MutableStateFlow(response) +constructor(val result: ApiResult, val onGet: () -> Unit = {}) : IGlobalRepository { + + @DefaultArgumentInterop.Enabled + constructor( + response: GlobalResponse = + GlobalResponse(emptyMap(), emptyMap(), emptyMap(), emptyMap(), emptyMap(), emptyMap()), + onGet: () -> Unit = {} + ) : this(ApiResult.Ok(response), onGet) + + override val state = + MutableStateFlow( + when (result) { + is ApiResult.Error -> null + is ApiResult.Ok -> result.data + } + ) override suspend fun getGlobalData(): ApiResult { onGet() - return ApiResult.Ok(response) + return result } } diff --git a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/SchedulesRepository.kt b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/SchedulesRepository.kt index fa0f09b95..a6d8211ea 100644 --- a/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/SchedulesRepository.kt +++ b/shared/src/commonMain/kotlin/com/mbta/tid/mbta_app/repositories/SchedulesRepository.kt @@ -1,5 +1,6 @@ package com.mbta.tid.mbta_app.repositories +import co.touchlab.skie.configuration.annotations.DefaultArgumentInterop import com.mbta.tid.mbta_app.model.response.ApiResult import com.mbta.tid.mbta_app.model.response.ScheduleResponse import com.mbta.tid.mbta_app.network.MobileBackendClient @@ -43,9 +44,16 @@ class SchedulesRepository : ISchedulesRepository, KoinComponent { } class MockScheduleRepository( - private val scheduleResponse: ScheduleResponse = ScheduleResponse(listOf(), mapOf()), + private val response: ApiResult, private val callback: (stopIds: List) -> Unit = {} ) : ISchedulesRepository { + + @DefaultArgumentInterop.Enabled + constructor( + scheduleResponse: ScheduleResponse = ScheduleResponse(listOf(), mapOf()), + callback: (stopIds: List) -> Unit = {} + ) : this(ApiResult.Ok(scheduleResponse), callback) + constructor() : this( scheduleResponse = ScheduleResponse(schedules = listOf(), trips = mapOf()), @@ -57,12 +65,12 @@ class MockScheduleRepository( now: Instant ): ApiResult { callback(stopIds) - return ApiResult.Ok(scheduleResponse) + return response } override suspend fun getSchedule(stopIds: List): ApiResult { callback(stopIds) - return ApiResult.Ok(scheduleResponse) + return response } }