Skip to content

Commit

Permalink
add missing tests and fix some found issues
Browse files Browse the repository at this point in the history
  • Loading branch information
JackVCurtis committed Dec 2, 2024
1 parent db8b1fa commit 1eb0111
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<NearbyStaticData> {
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)
}
}
Original file line number Diff line number Diff line change
@@ -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<MapFriendlyRouteResponse?>
get() {
/* null-op */
return MutableStateFlow<MapFriendlyRouteResponse?>(null)
}

override suspend fun getRailRouteShapes(): ApiResult<MapFriendlyRouteResponse> {
return ApiResult.Ok(mapFriendlyRouteResponse)
}
}

var actualRailRouteShapes: MapFriendlyRouteResponse? = null
composeTestRule.setContent {
actualRailRouteShapes = getRailRouteShapes(railRouteShapeRepository)
}

composeTestRule.awaitIdle()
assertEquals(mapFriendlyRouteResponse, actualRailRouteShapes)
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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<StopMapResponse> {
return ApiResult.Ok(stopMapResponse)
}
}

var actualStopMapResponse: StopMapResponse? = null
composeTestRule.setContent {
actualStopMapResponse = getStopMapData(stop.id, stopRepository)
}

composeTestRule.awaitIdle()
assertEquals(stopMapResponse, actualStopMapResponse)
}
}
Original file line number Diff line number Diff line change
@@ -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<AlertsStreamDataResponse>) -> 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)
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ 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<GlobalResponse?>(null)
var globalResponse: MutableStateFlow<GlobalResponse?> = _globalResponse
var globalResponse: StateFlow<GlobalResponse?> = _globalResponse

init {
CoroutineScope(Dispatchers.IO).launch { globalResponse.collect { getGlobalData() } }
}

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")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -20,7 +21,7 @@ class RailRouteShapesViewModel(private val railRouteShapeRepository: IRailRouteS
ViewModel() {
private val _railRouteShapes: MutableStateFlow<MapFriendlyRouteResponse?> =
MutableStateFlow(null)
val railRouteShapes = _railRouteShapes
val railRouteShapes: StateFlow<MapFriendlyRouteResponse?> = _railRouteShapes

init {
CoroutineScope(Dispatchers.IO).launch { railRouteShapes.collect { getRailRouteShapes() } }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -22,7 +23,7 @@ class ScheduleViewModel(
private val schedulesRepository: ISchedulesRepository
) : ViewModel() {
private val _schedule = MutableStateFlow<ScheduleResponse?>(null)
val schedule = _schedule
val schedule: StateFlow<ScheduleResponse?> = _schedule

init {
CoroutineScope(Dispatchers.IO).launch { schedule.collect { getSchedule(stopIds) } }
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<StopMapResponse?>(replay = 0)
val stopMapResponse = _stopMapResponse
private val _stopMapResponse = MutableStateFlow<StopMapResponse?>(null)
val stopMapResponse: StateFlow<StopMapResponse?> = _stopMapResponse

init {
CoroutineScope(Dispatchers.IO).launch { stopMapResponse.collect { getStopMapData(stopId) } }
Expand All @@ -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
}

0 comments on commit 1eb0111

Please sign in to comment.