Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6f63cac authored by Ellen Poe's avatar Ellen Poe
Browse files

Merge branch 'ellenhp/additional_viewmodel_tests' into 'main'

Add tests for DirectionsViewModel and PlaceCardViewModel

See merge request e/os/cardinal!24
parents 819a5702 40158568
Loading
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
/*
 *     Cardinal Maps
 *     Copyright (C) 2025 Cardinal Maps Authors
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package earth.maps.cardinal.data

import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import earth.maps.cardinal.transit.PlanResponse

data class TransitPlanState(
    val planResponse: PlanResponse? = null,
    val isLoading: Boolean = false,
    val error: String? = null
)

class PlanStateRepository {
    private val _planState = MutableStateFlow(TransitPlanState())
    val planState: StateFlow<TransitPlanState> = _planState.asStateFlow()

    fun setLoading(isLoading: Boolean) {
        _planState.value = _planState.value.copy(isLoading = isLoading)
    }

    fun setPlanResponse(planResponse: PlanResponse?) {
        _planState.value = _planState.value.copy(planResponse = planResponse, isLoading = false, error = null)
    }

    fun setError(error: String?) {
        _planState.value = _planState.value.copy(isLoading = false, error = error)
    }

    fun clear() {
        _planState.value = TransitPlanState()
    }

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    internal fun setStateForTest(state: TransitPlanState) {
        _planState.value = state
    }
}
+57 −0
Original line number Diff line number Diff line
/*
 *     Cardinal Maps
 *     Copyright (C) 2025 Cardinal Maps Authors
 *
 *     This program is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 *
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 *
 *     You should have received a copy of the GNU General Public License
 *     along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

package earth.maps.cardinal.data

import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import uniffi.ferrostar.Route

data class RouteState(
    val route: Route? = null,
    val isLoading: Boolean = false,
    val error: String? = null
)

class RouteStateRepository {
    private val _routeState = MutableStateFlow(RouteState())
    val routeState: StateFlow<RouteState> = _routeState.asStateFlow()

    fun setLoading(isLoading: Boolean) {
        _routeState.value = _routeState.value.copy(isLoading = isLoading)
    }

    fun setRoute(route: Route?) {
        _routeState.value = _routeState.value.copy(route = route, isLoading = false, error = null)
    }

    fun setError(error: String?) {
        _routeState.value = _routeState.value.copy(isLoading = false, error = error)
    }

    fun clear() {
        _routeState.value = RouteState()
    }

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    internal fun setStateForTest(state: RouteState) {
        _routeState.value = state
    }
}
+3 −11
Original line number Diff line number Diff line
@@ -37,8 +37,6 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
object GeocodingModule {

    var geocodingService: OfflineGeocodingService? = null

    @Provides
    @Singleton
    fun provideGeocodingService(
@@ -46,7 +44,8 @@ object GeocodingModule {
        locationRepository: LocationRepository,
        @ApplicationContext context: Context
    ): GeocodingService {
        val onlineService = providePeliasGeocodingService(appPreferenceRepository, locationRepository)
        val onlineService =
            providePeliasGeocodingService(appPreferenceRepository, locationRepository)
        val offlineService = provideOfflineGeocodingService(context, locationRepository)
        return MultiplexedGeocodingService(
            appPreferenceRepository = appPreferenceRepository,
@@ -71,14 +70,7 @@ object GeocodingModule {
        @ApplicationContext context: Context,
        locationRepository: LocationRepository
    ): OfflineGeocodingService {
        val globalGeocodingService = geocodingService
        if (globalGeocodingService != null) {
            return globalGeocodingService
        } else {
            val newGeocoder = OfflineGeocodingService(context, locationRepository)
            geocodingService = newGeocoder
            return newGeocoder
        }
        return OfflineGeocodingService(context, locationRepository)
    }

    @Provides
+14 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import earth.maps.cardinal.data.PlanStateRepository
import earth.maps.cardinal.data.RouteStateRepository
import earth.maps.cardinal.data.room.DownloadedTileDao
import earth.maps.cardinal.data.room.OfflineAreaDao
import earth.maps.cardinal.data.room.OfflineAreaRepository
@@ -41,6 +43,18 @@ object RepositoryModule {
        return OfflineAreaRepository(offlineAreaDao)
    }

    @Provides
    @Singleton
    fun provideRouteStateRepository(): RouteStateRepository {
        return RouteStateRepository()
    }

    @Provides
    @Singleton
    fun providePlanStateRepository(): PlanStateRepository {
        return PlanStateRepository()
    }

    @Provides
    @Singleton
    fun provideTileDownloadManager(
+1 −1
Original line number Diff line number Diff line
@@ -612,8 +612,8 @@ private fun PlaceCardRoute(
    val placeJson = backStackEntry.arguments?.getString("place")
    val place = placeJson?.let { Gson().fromJson(it, Place::class.java) }
    place?.let { place ->
        viewModel.setPlace(place)
        LaunchedEffect(place) {
            viewModel.setPlace(place)
            // Clear any existing pins and add the new one to ensure only one pin is shown at a time
            state.mapPins.clear()
            state.mapPins.add(place)
Loading