From fcf93367f620cfc4df446704962a06b39f46bdcc Mon Sep 17 00:00:00 2001 From: Alexandre Spiess <92825698+Unsaved2@users.noreply.github.com> Date: Fri, 22 Nov 2024 00:39:28 +0100 Subject: [PATCH] Feature/path-activities (#213) * refactor: inject API key through DirectionsRepository constructor * test: update tests to accommodate API key in DirectionsRepository * refactor: modify factory to include API key injection * test: update tests to adapt for the API key in DirectionsViewModelTest * feature: add DirectionsViewModel in MainActivity * build: add MAPS_API_KEY to BuildConfig for DirectionsViewModel * feat: add path between activities * test: update tests in ActivitiesMapScreenTest to handle paths between Activities * test: add new legs and activity * format: format to ktfmtFormat * fix: filter out activities with invalid locations --- app/build.gradle.kts | 8 + .../dashboard/map/ActivitiesMapScreenTest.kt | 83 ++++++++-- .../com/github/se/travelpouch/MainActivity.kt | 9 +- .../activity/map/DirectionsRepository.kt | 5 +- .../map/DirectionsRepositoryInterface.kt | 1 - .../model/activity/map/DirectionsViewModel.kt | 28 ++-- .../ui/dashboard/map/ActivitiesMapScreen.kt | 144 ++++++++++++++++-- .../activity/map/DirectionsRepositoryTest.kt | 23 +-- .../activity/map/DirectionsViewModelTest.kt | 25 ++- 9 files changed, 258 insertions(+), 68 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0e4fd6a1..39dacd3c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -44,6 +44,14 @@ android { vectorDrawables { useSupportLibrary = true } + + // Declare the API key as a BuildConfig field + buildConfigField("String", "MAPS_API_KEY", "\"$mapsApiKey\"") + + // Enable BuildConfig functionality + buildFeatures { + buildConfig = true + } } buildTypes { diff --git a/app/src/androidTest/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreenTest.kt b/app/src/androidTest/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreenTest.kt index 34f4c946..c0a81132 100644 --- a/app/src/androidTest/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreenTest.kt +++ b/app/src/androidTest/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreenTest.kt @@ -7,13 +7,21 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import com.github.se.travelpouch.model.activity.Activity import com.github.se.travelpouch.model.activity.ActivityRepository import com.github.se.travelpouch.model.activity.ActivityViewModel +import com.github.se.travelpouch.model.activity.map.DirectionsRepositoryInterface +import com.github.se.travelpouch.model.activity.map.DirectionsResponse +import com.github.se.travelpouch.model.activity.map.DirectionsViewModel +import com.github.se.travelpouch.model.activity.map.Leg +import com.github.se.travelpouch.model.activity.map.OverviewPolyline +import com.github.se.travelpouch.model.activity.map.Route import com.github.se.travelpouch.model.travels.Location import com.github.se.travelpouch.ui.navigation.NavigationActions +import com.google.android.gms.maps.model.LatLng import com.google.firebase.Timestamp import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.Mockito.anyString import org.mockito.Mockito.mock import org.mockito.Mockito.verify import org.mockito.Mockito.`when` @@ -28,8 +36,10 @@ class ActivitiesMapScreenTest { private lateinit var mockActivityRepositoryFirebase: ActivityRepository private lateinit var mockActivityModelView: ActivityViewModel private lateinit var mockNavigationActions: NavigationActions + private lateinit var mockkDirectionsViewModel: DirectionsViewModel + private lateinit var mockkDirectionsRepository: DirectionsRepositoryInterface - val listOfActivities = + private val listOfActivities = listOf( Activity( uid = "1", @@ -44,7 +54,43 @@ class ActivitiesMapScreenTest { description = "Presentation to showcase the project to the client.", location = Location(40.0, -122.4194, Timestamp.now(), "Paris"), date = Timestamp(Timestamp.now().seconds + 3600, Timestamp.now().nanoseconds), - documentsNeeded = null)) + documentsNeeded = null), + Activity( + uid = "3", + title = "Workshop", + description = "Workshop on team building and skill development.", + location = Location(51.5074, -0.1278, Timestamp.now(), "London"), + date = Timestamp(Timestamp.now().seconds + 7200, Timestamp.now().nanoseconds), + documentsNeeded = mapOf("Workshop Material" to 1))) + + private val mockLeg = + Leg( + distanceText = "3.4 km", + distanceValue = 3400, + durationText = "15 mins", + durationValue = 900, + startAddress = "Start Address", + endAddress = "End Address", + startLocation = LatLng(37.7749, -122.4194), + endLocation = LatLng(34.0522, -118.2437), + overviewPolyline = OverviewPolyline("u{~vFvyys@fC_y@")) + + private val mockLeg2 = + Leg( + distanceText = "5.2 km", + distanceValue = 5200, + durationText = "25 mins", + durationValue = 1500, + startAddress = "End Address", + endAddress = "Next Address", + startLocation = LatLng(34.0522, -118.2437), + endLocation = LatLng(36.1699, -115.1398), + overviewPolyline = OverviewPolyline("a~bcFghij@dE_g@")) + + private val mockResponse = + DirectionsResponse( + routes = + listOf(Route(OverviewPolyline("u{~vFvyys@fC_y@"), legs = listOf(mockLeg, mockLeg2)))) @get:Rule val composeTestRule = createComposeRule() @@ -53,6 +99,23 @@ class ActivitiesMapScreenTest { mockNavigationActions = mock(NavigationActions::class.java) mockActivityRepositoryFirebase = mock(ActivityRepository::class.java) mockActivityModelView = ActivityViewModel(mockActivityRepositoryFirebase) + + mockkDirectionsRepository = mock(DirectionsRepositoryInterface::class.java) + mockkDirectionsViewModel = DirectionsViewModel(mockkDirectionsRepository) + + doAnswer { invocation -> + val onSuccess = invocation.getArgument(4) as (DirectionsResponse) -> Unit + onSuccess(mockResponse) + null + } + .whenever(mockkDirectionsRepository) + .getDirections( + origin = anyString(), + destination = anyString(), + mode = anyString(), + waypoints = anyOrNull(), + onSuccess = any(), + onFailure = any()) } @Test @@ -68,7 +131,9 @@ class ActivitiesMapScreenTest { mockActivityModelView.getAllActivities() - composeTestRule.setContent { ActivitiesMapScreen(mockActivityModelView, mockNavigationActions) } + composeTestRule.setContent { + ActivitiesMapScreen(mockActivityModelView, mockNavigationActions, mockkDirectionsViewModel) + } composeTestRule.onNodeWithTag("Map").assertExists() } @@ -79,26 +144,26 @@ class ActivitiesMapScreenTest { `when`(mockActivityRepositoryFirebase.getAllActivities(any(), any())).then { it.getArgument<(List) -> Unit>(0)(listOf()) } - composeTestRule.setContent { ActivitiesMapScreen(mockActivityModelView, mockNavigationActions) } + composeTestRule.setContent { + ActivitiesMapScreen(mockActivityModelView, mockNavigationActions, mockkDirectionsViewModel) + } composeTestRule.onNodeWithTag("Map").assertExists() } @Test fun testGoBackButton() { - // Configurer le contenu de la règle Compose composeTestRule.setContent { ActivitiesMapScreen( - activityViewModel = mockActivityModelView, navigationActions = mockNavigationActions) + activityViewModel = mockActivityModelView, + navigationActions = mockNavigationActions, + directionsViewModel = mockkDirectionsViewModel) } - // Attendre que l'interface utilisateur soit prête composeTestRule.waitForIdle() - // Simuler le clic sur le bouton "Go Back" composeTestRule.onNodeWithTag("GoBackButton").performClick() - // Vérifier que la méthode goBack() a été appelée verify(mockNavigationActions).goBack() } } diff --git a/app/src/main/java/com/github/se/travelpouch/MainActivity.kt b/app/src/main/java/com/github/se/travelpouch/MainActivity.kt index ead8bfbc..9ae53713 100644 --- a/app/src/main/java/com/github/se/travelpouch/MainActivity.kt +++ b/app/src/main/java/com/github/se/travelpouch/MainActivity.kt @@ -16,6 +16,7 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import androidx.navigation.compose.rememberNavController import com.github.se.travelpouch.model.activity.ActivityViewModel +import com.github.se.travelpouch.model.activity.map.DirectionsViewModel import com.github.se.travelpouch.model.authentication.AuthenticationService import com.github.se.travelpouch.model.dashboard.CalendarViewModel import com.github.se.travelpouch.model.documents.DocumentViewModel @@ -82,6 +83,12 @@ class MainActivity : ComponentActivity() { val calendarViewModel: CalendarViewModel = viewModel(factory = CalendarViewModel.Factory(activityModelView)) + val directionsViewModel: DirectionsViewModel = + viewModel( + factory = + DirectionsViewModel.provideFactory( + BuildConfig.MAPS_API_KEY) // Inject the API key for the DirectionsViewModel + ) NavHost(navController = navController, startDestination = Route.DEFAULT) { navigation( startDestination = Screen.AUTH, @@ -117,7 +124,7 @@ class MainActivity : ComponentActivity() { } composable(Screen.ACTIVITIES_MAP) { - ActivitiesMapScreen(activityModelView, navigationActions) + ActivitiesMapScreen(activityModelView, navigationActions, directionsViewModel) } composable(Screen.PARTICIPANT_LIST) { diff --git a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepository.kt b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepository.kt index c9d2c820..df2140d5 100644 --- a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepository.kt +++ b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepository.kt @@ -11,7 +11,8 @@ import okhttp3.Request import org.json.JSONObject /** Repository for fetching directions using the Google Maps Directions API. */ -class DirectionsRepository(client: OkHttpClient) : DirectionsRepositoryInterface { +class DirectionsRepository(client: OkHttpClient, private val apiKey: String) : + DirectionsRepositoryInterface { private val networkManager: NetworkManager = NetworkManager(client) @@ -120,7 +121,6 @@ class DirectionsRepository(client: OkHttpClient) : DirectionsRepositoryInterface * @param origin The starting point of the route, formatted as "latitude,longitude". * @param destination The ending point of the route, formatted as "latitude,longitude". * @param mode The travel mode ("driving", "walking", "bicycling", or "transit"). - * @param apiKey The API key used to authenticate the request. * @param waypoints A string of waypoints formatted as "latitude,longitude|latitude,longitude" * (optional). * @param onSuccess Callback that is called when the request is successful. @@ -131,7 +131,6 @@ class DirectionsRepository(client: OkHttpClient) : DirectionsRepositoryInterface origin: String, destination: String, mode: String, - apiKey: String, waypoints: String?, onSuccess: (DirectionsResponse) -> Unit, onFailure: (Exception) -> Unit diff --git a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryInterface.kt b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryInterface.kt index b7815ca8..e71b129c 100644 --- a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryInterface.kt +++ b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryInterface.kt @@ -19,7 +19,6 @@ interface DirectionsRepositoryInterface { origin: String, destination: String, mode: String, - apiKey: String, waypoints: String? = null, onSuccess: (DirectionsResponse) -> Unit, onFailure: (Exception) -> Unit diff --git a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModel.kt b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModel.kt index 3013ca40..a0252037 100644 --- a/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModel.kt +++ b/app/src/main/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModel.kt @@ -34,7 +34,11 @@ data class RouteDetails( } } -/** ViewModel for fetching and managing directions data from the Google Maps Directions API. */ +/** + * ViewModel for fetching directions between activities using the Google Maps Directions API. + * + * @param repository The repository to fetch directions from. + */ class DirectionsViewModel(private val repository: DirectionsRepositoryInterface) : ViewModel() { // StateFlow to hold the fetched route details for activities @@ -45,17 +49,26 @@ class DirectionsViewModel(private val repository: DirectionsRepositoryInterface) /** Factory class for creating DirectionsViewModel instances. */ // create factory companion object { - val Factory: ViewModelProvider.Factory = + fun provideFactory(apiKey: String): ViewModelProvider.Factory = object : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - return DirectionsViewModel(DirectionsRepository(OkHttpClient())) as T + return DirectionsViewModel( + DirectionsRepository( + client = OkHttpClient(), apiKey = apiKey // Inject API key dynamically + )) + as T } } } - /** Function to fetch directions between activities sequentially. */ - fun fetchDirectionsForActivities(activities: List, mode: String, apiKey: String) { + /** + * Fetches directions for a list of activities using the specified travel mode. + * + * @param activities The list of activities to create a route for. + * @param mode The travel mode ("driving", "walking", "bicycling", or "transit"). + */ + fun fetchDirectionsForActivities(activities: List, mode: String) { if (activities.size < 2) { Log.e("DirectionsViewModel", "Not enough activities to create a route") return @@ -84,7 +97,7 @@ class DirectionsViewModel(private val repository: DirectionsRepositoryInterface) } // Fetch directions using the extracted origin, destination, and waypoints - fetchDirections(origin, destination, mode, apiKey, waypoints) + fetchDirections(origin, destination, mode, waypoints) } /** @@ -93,13 +106,11 @@ class DirectionsViewModel(private val repository: DirectionsRepositoryInterface) * @param origin The starting point of the route as a LatLng object. * @param destination The ending point of the route as a LatLng object. * @param mode The travel mode ("driving", "walking", "bicycling", or "transit"). - * @param apiKey The API key for the Google Maps Directions API. */ fun fetchDirections( origin: LatLng, destination: LatLng, mode: String, - apiKey: String, waypoints: List? = null ) { @@ -113,7 +124,6 @@ class DirectionsViewModel(private val repository: DirectionsRepositoryInterface) origin = originStr, destination = destinationStr, mode = mode, - apiKey = apiKey, waypoints = waypointsStr, onSuccess = { directionsResponse -> // Use extractRouteDetails to extract the route details diff --git a/app/src/main/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreen.kt b/app/src/main/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreen.kt index 7f50598e..c5f1ae9e 100644 --- a/app/src/main/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreen.kt +++ b/app/src/main/java/com/github/se/travelpouch/ui/dashboard/map/ActivitiesMapScreen.kt @@ -1,5 +1,6 @@ package com.github.se.travelpouch.ui.dashboard.map +import android.util.Log import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size @@ -9,19 +10,31 @@ import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.unit.dp import com.github.se.travelpouch.model.activity.ActivityViewModel -import com.github.se.travelpouch.ui.home.SimpleMarker +import com.github.se.travelpouch.model.activity.map.DirectionsViewModel import com.github.se.travelpouch.ui.navigation.NavigationActions +import com.google.android.gms.maps.model.BitmapDescriptor +import com.google.android.gms.maps.model.BitmapDescriptorFactory +import com.google.android.gms.maps.model.ButtCap import com.google.android.gms.maps.model.CameraPosition +import com.google.android.gms.maps.model.JointType import com.google.android.gms.maps.model.LatLng import com.google.maps.android.compose.GoogleMap +import com.google.maps.android.compose.Marker +import com.google.maps.android.compose.Polyline import com.google.maps.android.compose.rememberCameraPositionState +import com.google.maps.android.compose.rememberMarkerState import java.text.SimpleDateFormat import java.util.Locale @@ -35,12 +48,19 @@ import java.util.Locale @Composable fun ActivitiesMapScreen( activityViewModel: ActivityViewModel, - navigationActions: NavigationActions + navigationActions: NavigationActions, + directionsViewModel: DirectionsViewModel ) { // Collect the list of activities from the ViewModel val listOfActivities by activityViewModel.activities.collectAsState() + // Filter out activities with invalid locations (latitude and longitude are both 0.0) + val validActivities = + listOfActivities.filter { activity -> + activity.location.latitude != 0.0 && activity.location.longitude != 0.0 + } + val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()) // Default location to use if activities are not yet loaded (e.g., Paris) @@ -51,8 +71,19 @@ fun ActivitiesMapScreen( position = CameraPosition.fromLatLngZoom(defaultLocation, 10f) } + // Collect the path points from the DirectionsViewModel + val routeDetails by directionsViewModel.activityRouteDetails.collectAsState() + + var selectedRouteIndex by remember { mutableIntStateOf(0) } // Track selected route index + + // Use DisposableEffect to monitor when the screen is composed/destroyed + LaunchedEffect(validActivities) { + // Fetch directions if the list of activities changes + directionsViewModel.fetchDirectionsForActivities(validActivities, "walking") + } + // Effect that runs whenever the list of activities changes - CameraUpdater(listOfActivities, cameraPositionState) + CameraUpdater(validActivities, cameraPositionState) Scaffold( modifier = Modifier.testTag("ActivityMapScreen"), @@ -65,18 +96,61 @@ fun ActivitiesMapScreen( modifier = Modifier.padding(paddingValues).testTag("Map"), cameraPositionState = cameraPositionState) { // Add a marker for each activity's location - listOfActivities.forEach { activity -> + validActivities.forEachIndexed { index, activity -> activity.location.let { location -> // Ensure location is not null - SimpleMarker( - position = LatLng(location.latitude, location.longitude), - title = activity.title, // The title of the activity - snippet = - dateFormat.format(activity.date.toDate()), // The date of the activity - ) + // Use the helper function to get the appropriate marker icon + val icon = getMarkerIcon(index, validActivities.size) + + // Display the marker with the customized icon + Marker( + state = + rememberMarkerState( + position = LatLng(location.latitude, location.longitude)), + title = activity.title, + snippet = dateFormat.format(activity.date.toDate()), + icon = icon) } } - } + // Draw the walking path using the leg paths + if (routeDetails != null && routeDetails!!.legsRoute.isNotEmpty()) { + Log.d("ActivitiesMapScreen", "Drawing leg polylines") + + // Iterate over each leg path and draw the segment with different styles + routeDetails!!.legsRoute.forEachIndexed { index, legPath -> + val prop = (index.toDouble() / routeDetails!!.legsRoute.size.toDouble()) - 0.5 + + // Use the helper function to get the gradient color + val color = + getGradientColor( + index = index, totalSegments = routeDetails!!.legsRoute.size) + + // Introduce a small offset by adjusting each point slightly based on index + val offsetLegPath = + legPath.map { point -> + LatLng(point.latitude + prop * 0.0002, point.longitude + prop * 0.00002) + } + + val zIndex = + if (index == selectedRouteIndex) { + (routeDetails!!.legsRoute.size + 1).toFloat() // Selected route in blue + } else { + (index + 1).toFloat() // Other routes in gray + } + + Polyline( + points = offsetLegPath, + clickable = true, + width = 20f, + color = color, + endCap = ButtCap(), + jointType = JointType.ROUND, + zIndex = zIndex, + onClick = { selectedRouteIndex = index } // Update selected route + ) + } + } + } // Add a floating action button for going back FloatingActionButton( onClick = { navigationActions.goBack() }, @@ -90,3 +164,51 @@ fun ActivitiesMapScreen( } }) } + +// Helper function to generate a consistent gradient color +fun getGradientColor( + index: Int, + totalSegments: Int, + colorStart: Color = Color(0xFF03A9F4).copy(alpha = 0.7f), // Soft Blue with consistent alpha + colorEnd: Color = Color(0xFF3F51B5).copy(alpha = 0.7f) // Soft Purple with the same alpha +): Color { + // Function to interpolate between two colors + fun interpolateColor(colorStart: Color, colorEnd: Color, fraction: Float): Color { + val red = (colorStart.red + (colorEnd.red - colorStart.red) * fraction) + val green = (colorStart.green + (colorEnd.green - colorStart.green) * fraction) + val blue = (colorStart.blue + (colorEnd.blue - colorStart.blue) * fraction) + return Color(red, green, blue, alpha = colorStart.alpha) // Keep alpha consistent + } + + // Calculate the gradient color based on the index + return if (totalSegments > 1) { + val fraction = index.toFloat() / (totalSegments - 1) + interpolateColor(colorStart, colorEnd, fraction) + } else { + colorStart + } +} + +/** + * Helper function to get the appropriate marker icon based on the activity's index. + * + * @param index The index of the activity in the list. + * @param totalActivities The total number of activities in the list. + * @return The appropriate BitmapDescriptor for the marker icon. + */ +fun getMarkerIcon(index: Int, totalActivities: Int): BitmapDescriptor { + return when { + // Use a custom icon for the first activity + index == 0 -> BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN) + + // Use a custom icon for the last activity + index == totalActivities - 1 -> + BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE) + // Replace with your icon resource + + // Use the default icon for all other activities + else -> + BitmapDescriptorFactory.defaultMarker( + BitmapDescriptorFactory.HUE_CYAN) // You can choose a different hue if you like + } +} diff --git a/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryTest.kt b/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryTest.kt index b6ec69d3..7c479abc 100644 --- a/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryTest.kt +++ b/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsRepositoryTest.kt @@ -21,13 +21,14 @@ class DirectionsRepositoryTest { private lateinit var mockClient: OkHttpClient private lateinit var mockCall: Call private lateinit var directionsRepository: DirectionsRepository + private val TEST_API_KEY = "test-api-key" @Before fun setUp() { // Mock OkHttpClient and Call mockClient = mock(OkHttpClient::class.java) mockCall = mock(Call::class.java) - directionsRepository = DirectionsRepository(mockClient) + directionsRepository = DirectionsRepository(mockClient, TEST_API_KEY) } @Test @@ -90,7 +91,6 @@ class DirectionsRepositoryTest { "origin", "destination", "driving", - "apiKey", "37.7749,-122.4194|34.0522,-118.2437", { response -> directionsResponse = response }, { exception -> failureException = exception }) @@ -142,13 +142,7 @@ class DirectionsRepositoryTest { var failureException: Exception? = null directionsRepository.getDirections( - "origin", - "destination", - "driving", - "apiKey", - null, - {}, - { exception -> failureException = exception }) + "origin", "destination", "driving", null, {}, { exception -> failureException = exception }) // Assert that an exception was thrown with the correct message assertTrue(failureException != null) @@ -177,7 +171,6 @@ class DirectionsRepositoryTest { "origin", "destination", "driving", - "apiKey", null, { response -> directionsResponse = response }, { exception -> failureException = exception }) @@ -208,13 +201,7 @@ class DirectionsRepositoryTest { var failureException: Exception? = null directionsRepository.getDirections( - "origin", - "destination", - "driving", - "apiKey", - null, - {}, - { exception -> failureException = exception }) + "origin", "destination", "driving", null, {}, { exception -> failureException = exception }) // Assert results assertTrue(failureException != null) @@ -247,7 +234,6 @@ class DirectionsRepositoryTest { "origin", "destination", "driving", - "apiKey", null, { response -> directionsResponse = response }, { exception -> failureException = exception }) @@ -286,7 +272,6 @@ class DirectionsRepositoryTest { "destination", "driving", "apiKey", - null, {}, { exception -> failureException = exception }) diff --git a/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModelTest.kt b/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModelTest.kt index 09584531..2020adec 100644 --- a/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModelTest.kt +++ b/app/src/test/java/com/github/se/travelpouch/model/activity/map/DirectionsViewModelTest.kt @@ -63,7 +63,7 @@ class DirectionsViewModelTest { routes = listOf(Route(OverviewPolyline("u{~vFvyys@fC_y@"), legs = listOf(mockLeg)))) doAnswer { invocation -> - val onSuccess = invocation.getArgument(5) as (DirectionsResponse) -> Unit + val onSuccess = invocation.getArgument(4) as (DirectionsResponse) -> Unit onSuccess(mockResponse) null } @@ -72,13 +72,12 @@ class DirectionsViewModelTest { origin = anyString(), destination = anyString(), mode = anyString(), - apiKey = anyString(), waypoints = anyOrNull(), onSuccess = any(), onFailure = any()) // Act - viewModel.fetchDirections(mockLatLng, mockLatLng, "driving", "mockApiKey") + viewModel.fetchDirections(mockLatLng, mockLatLng, "driving") // Advance the dispatcher to execute pending coroutines testDispatcher.scheduler.advanceUntilIdle() @@ -96,7 +95,7 @@ class DirectionsViewModelTest { val exception = Exception("Network error") doAnswer { invocation -> - val onFailure = invocation.getArgument<(Exception) -> Unit>(5) + val onFailure = invocation.getArgument<(Exception) -> Unit>(4) onFailure(exception) null } @@ -105,13 +104,12 @@ class DirectionsViewModelTest { origin = anyString(), destination = anyString(), mode = anyString(), - apiKey = anyString(), waypoints = anyString(), onSuccess = any(), onFailure = any()) // Act - viewModel.fetchDirections(mockLatLng, mockLatLng, "driving", "mockApiKey") + viewModel.fetchDirections(mockLatLng, mockLatLng, "driving") testDispatcher.scheduler.advanceUntilIdle() // Assert @@ -139,7 +137,7 @@ class DirectionsViewModelTest { DirectionsResponse( routes = listOf(Route(OverviewPolyline("INVALID_POLYLINE"), legs = listOf(mockLeg)))) doAnswer { invocation -> - val onSuccess = invocation.getArgument<(DirectionsResponse) -> Unit>(4) + val onSuccess = invocation.getArgument<(DirectionsResponse) -> Unit>(3) onSuccess(mockResponse) null } @@ -148,13 +146,12 @@ class DirectionsViewModelTest { origin = anyString(), destination = anyString(), mode = anyString(), - apiKey = anyString(), waypoints = anyString(), onSuccess = any(), onFailure = any()) // Act - viewModel.fetchDirections(mockLatLng, mockLatLng, "driving", "mockApiKey") + viewModel.fetchDirections(mockLatLng, mockLatLng, "driving") // Advance the dispatcher to execute pending coroutines testDispatcher.scheduler.advanceUntilIdle() @@ -188,7 +185,7 @@ class DirectionsViewModelTest { routes = listOf(Route(OverviewPolyline("INVALID_POLYLINE"), legs = listOf(malformedLeg)))) doAnswer { invocation -> - val onSuccess = invocation.getArgument<(DirectionsResponse) -> Unit>(4) + val onSuccess = invocation.getArgument<(DirectionsResponse) -> Unit>(3) onSuccess(mockResponse) null } @@ -197,13 +194,12 @@ class DirectionsViewModelTest { origin = anyString(), destination = anyString(), mode = anyString(), - apiKey = anyString(), waypoints = anyString(), onSuccess = any(), onFailure = any()) // Act - viewModel.fetchDirections(mockLatLng, mockLatLng, "driving", "mockApiKey") + viewModel.fetchDirections(mockLatLng, mockLatLng, "driving") // Advance the dispatcher to execute pending coroutines testDispatcher.scheduler.advanceUntilIdle() @@ -253,7 +249,7 @@ class DirectionsViewModelTest { routes = listOf(Route(OverviewPolyline("u{~vFvyys@fC_y@"), legs = listOf(mockLeg)))) doAnswer { invocation -> - val onSuccess = invocation.getArgument(5) as (DirectionsResponse) -> Unit + val onSuccess = invocation.getArgument(4) as (DirectionsResponse) -> Unit onSuccess(mockResponse) null } @@ -262,13 +258,12 @@ class DirectionsViewModelTest { origin = anyString(), destination = anyString(), mode = anyString(), - apiKey = anyString(), waypoints = anyOrNull(), onSuccess = any(), onFailure = any()) // Act - viewModel.fetchDirectionsForActivities(listOf(activity, activity2), "driving", "mockApiKey") + viewModel.fetchDirectionsForActivities(listOf(activity, activity2), "driving") // Advance the dispatcher to execute pending coroutines testDispatcher.scheduler.advanceUntilIdle()