mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Move the custom tile server URL config to the Element wellknown content (#7416)
* Move the custom tile server URL config to the Element wellknown content * Iteration: use whole `MapTilerConfig` in the remote config
This commit is contained in:
committed by
GitHub
parent
ddbc6a2a33
commit
22195a47f2
+5
-4
@@ -50,6 +50,7 @@ import io.element.android.libraries.core.data.tryOrNull
|
||||
import io.element.android.libraries.designsystem.text.toDp
|
||||
import io.element.android.libraries.designsystem.theme.components.BottomSheetScaffold
|
||||
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
|
||||
import io.element.android.libraries.wellknown.api.MapTilerConfig
|
||||
import org.maplibre.compose.camera.CameraState
|
||||
import org.maplibre.compose.camera.rememberCameraState
|
||||
import org.maplibre.compose.map.MapOptions
|
||||
@@ -66,7 +67,7 @@ import kotlin.math.roundToInt
|
||||
* - Updating camera position padding based on sheet height
|
||||
* - Rendering the MaplibreMap with proper ornament positioning
|
||||
*
|
||||
* @param customMapStyleUrl Optional custom style URL for the map
|
||||
* @param customMapTilerConfig Optional custom style URL for the map
|
||||
* @param modifier Modifier for the root layout
|
||||
* @param scaffoldState State for the bottom sheet scaffold
|
||||
* @param cameraState The camera state for the map
|
||||
@@ -83,7 +84,7 @@ import kotlin.math.roundToInt
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MapBottomSheetScaffold(
|
||||
customMapStyleUrl: AsyncData<String?>,
|
||||
customMapTilerConfig: AsyncData<MapTilerConfig?>,
|
||||
modifier: Modifier = Modifier,
|
||||
scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(
|
||||
bottomSheetState = rememberBottomSheetState(
|
||||
@@ -137,11 +138,11 @@ fun MapBottomSheetScaffold(
|
||||
val ornamentOptions = mapOptions.ornamentOptions.copy(padding = sheetPadding)
|
||||
val mapOptions = mapOptions.copy(ornamentOptions = ornamentOptions)
|
||||
Box {
|
||||
when (customMapStyleUrl) {
|
||||
when (customMapTilerConfig) {
|
||||
is AsyncData.Success -> {
|
||||
MaplibreMap(
|
||||
options = mapOptions,
|
||||
baseStyle = BaseStyle.Uri(rememberTileStyleUrl(customMapStyleUrl.data)),
|
||||
baseStyle = BaseStyle.Uri(rememberTileStyleUrl(customMapTilerConfig.data)),
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
cameraState = cameraState,
|
||||
content = mapContent,
|
||||
|
||||
+5
-3
@@ -22,6 +22,7 @@ import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import im.vector.app.features.analytics.plan.Composer
|
||||
import io.element.android.features.enterprise.api.remoteconfig.RemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.api.live.ActiveLiveLocationShareManager
|
||||
import io.element.android.features.location.impl.common.LocationConstraintsCheck
|
||||
import io.element.android.features.location.impl.common.MapDefaults
|
||||
@@ -72,6 +73,7 @@ class ShareLocationPresenter(
|
||||
private val liveLocationShareManager: ActiveLiveLocationShareManager,
|
||||
private val liveLocationStore: LiveLocationStore,
|
||||
private val userLocationStateFactory: UserLocationState.Factory,
|
||||
private val remoteEnterpriseConfigProvider: RemoteEnterpriseConfigProvider,
|
||||
) : Presenter<ShareLocationState> {
|
||||
@AssistedFactory
|
||||
fun interface Factory {
|
||||
@@ -92,9 +94,9 @@ class ShareLocationPresenter(
|
||||
var pendingLiveLocationShare by remember { mutableStateOf(false) }
|
||||
val startLiveLocationAction = remember { mutableStateOf<AsyncAction<Unit>>(AsyncAction.Uninitialized) }
|
||||
val currentUser by client.userProfile.collectAsState()
|
||||
val customMapStyleUrl by produceState(AsyncData.Loading()) {
|
||||
val customMapConfig by produceState(AsyncData.Loading()) {
|
||||
// Ignore errors
|
||||
value = AsyncData.Success(client.getMapStyleUrl().getOrNull())
|
||||
value = AsyncData.Success(remoteEnterpriseConfigProvider.get(client.sessionId).dataOrNull()?.mapTilerConfig)
|
||||
}
|
||||
val sendLiveLocationPermissions by room.permissionsAsState(SendLiveLocationPermissions.DEFAULT) { perms ->
|
||||
perms.sendLiveLocationPermissions()
|
||||
@@ -199,7 +201,7 @@ class ShareLocationPresenter(
|
||||
}
|
||||
|
||||
return ShareLocationState(
|
||||
customMapStyleUrl = customMapStyleUrl,
|
||||
customMapTilerConfig = customMapConfig,
|
||||
currentUser = currentUser,
|
||||
dialogState = dialogState,
|
||||
trackUserLocation = trackUserPosition,
|
||||
|
||||
+2
-1
@@ -13,10 +13,11 @@ import io.element.android.features.location.impl.common.userlocation.UserLocatio
|
||||
import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.wellknown.api.MapTilerConfig
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class ShareLocationState(
|
||||
val customMapStyleUrl: AsyncData<String?>,
|
||||
val customMapTilerConfig: AsyncData<MapTilerConfig?>,
|
||||
val currentUser: MatrixUser,
|
||||
val dialogState: Dialog,
|
||||
val trackUserLocation: Boolean,
|
||||
|
||||
+5
-4
@@ -15,6 +15,7 @@ import io.element.android.libraries.architecture.AsyncAction
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.wellknown.api.MapTilerConfig
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
@@ -70,13 +71,13 @@ class ShareLocationStateProvider : PreviewParameterProvider<ShareLocationState>
|
||||
canShareLiveLocation = true,
|
||||
),
|
||||
aShareLocationState(
|
||||
customMapStyleUrl = AsyncData.Loading(),
|
||||
customMapTilerConfig = AsyncData.Loading(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun aShareLocationState(
|
||||
customMapStyleUrl: AsyncData<String?> = AsyncData.Success(null),
|
||||
customMapTilerConfig: AsyncData<MapTilerConfig?> = AsyncData.Success(null),
|
||||
currentUser: MatrixUser = MatrixUser(UserId("@user:matrix.org")),
|
||||
dialogState: ShareLocationState.Dialog = ShareLocationState.Dialog.None,
|
||||
trackUserPosition: Boolean = false,
|
||||
@@ -87,7 +88,7 @@ fun aShareLocationState(
|
||||
eventSink: (ShareLocationEvent) -> Unit = {},
|
||||
): ShareLocationState {
|
||||
return ShareLocationState(
|
||||
customMapStyleUrl = customMapStyleUrl,
|
||||
customMapTilerConfig = customMapTilerConfig,
|
||||
currentUser = currentUser,
|
||||
dialogState = dialogState,
|
||||
trackUserLocation = trackUserPosition,
|
||||
@@ -95,6 +96,6 @@ fun aShareLocationState(
|
||||
canShareLiveLocation = canShareLiveLocation,
|
||||
appName = appName,
|
||||
startLiveLocationAction = startLiveLocationAction,
|
||||
eventSink = eventSink
|
||||
eventSink = eventSink,
|
||||
)
|
||||
}
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ fun ShareLocationView(
|
||||
}
|
||||
|
||||
MapBottomSheetScaffold(
|
||||
customMapStyleUrl = state.customMapStyleUrl,
|
||||
customMapTilerConfig = state.customMapTilerConfig,
|
||||
cameraState = cameraState,
|
||||
modifier = modifier,
|
||||
scaffoldState = scaffoldState,
|
||||
|
||||
+7
-5
@@ -22,6 +22,7 @@ import androidx.compose.runtime.setValue
|
||||
import dev.zacsweers.metro.Assisted
|
||||
import dev.zacsweers.metro.AssistedFactory
|
||||
import dev.zacsweers.metro.AssistedInject
|
||||
import io.element.android.features.enterprise.api.remoteconfig.RemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
import io.element.android.features.location.api.live.ActiveLiveLocationShareManager
|
||||
@@ -46,7 +47,7 @@ import io.element.android.libraries.dateformatter.api.DateFormatter
|
||||
import io.element.android.libraries.dateformatter.api.DateFormatterMode
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.getBestName
|
||||
import io.element.android.libraries.matrix.api.room.joinedRoomMembers
|
||||
@@ -64,10 +65,11 @@ import kotlinx.coroutines.launch
|
||||
private val buildMeta: BuildMeta,
|
||||
private val dateFormatter: DateFormatter,
|
||||
private val stringProvider: StringProvider,
|
||||
private val client: MatrixClient,
|
||||
private val sessionId: SessionId,
|
||||
private val joinedRoom: JoinedRoom,
|
||||
private val liveLocationShareManager: ActiveLiveLocationShareManager,
|
||||
private val userLocationStateFactory: UserLocationState.Factory,
|
||||
private val remoteEnterpriseConfigProvider: RemoteEnterpriseConfigProvider,
|
||||
) : Presenter<ShowLocationState> {
|
||||
@AssistedFactory fun interface Factory {
|
||||
fun create(mode: ShowLocationMode): ShowLocationPresenter
|
||||
@@ -85,9 +87,9 @@ import kotlinx.coroutines.launch
|
||||
mutableStateOf(LocationConstraintsDialogState.None)
|
||||
}
|
||||
|
||||
val customMapStyleUrl by produceState(AsyncData.Loading()) {
|
||||
val customMapTilerConfig by produceState(AsyncData.Loading()) {
|
||||
// Ignore errors
|
||||
value = AsyncData.Success(client.getMapStyleUrl().getOrNull())
|
||||
value = AsyncData.Success(remoteEnterpriseConfigProvider.get(sessionId).dataOrNull()?.mapTilerConfig)
|
||||
}
|
||||
|
||||
fun checkLocationConstraints() {
|
||||
@@ -220,7 +222,7 @@ import kotlinx.coroutines.launch
|
||||
userLocationStateFactory.create(hasLocationPermission = permissionsState.isAnyGranted)
|
||||
}
|
||||
return ShowLocationState(
|
||||
customMapStyleUrl = customMapStyleUrl,
|
||||
customMapTilerConfig = customMapTilerConfig,
|
||||
dialogState = dialogState,
|
||||
locationShares = locationShares,
|
||||
focusedLocation = focusedLocation,
|
||||
|
||||
+2
-1
@@ -17,10 +17,11 @@ import io.element.android.libraries.designsystem.components.PinVariant
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.wellknown.api.MapTilerConfig
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
data class ShowLocationState(
|
||||
val customMapStyleUrl: AsyncData<String?>,
|
||||
val customMapTilerConfig: AsyncData<MapTilerConfig?>,
|
||||
val isLive: Boolean,
|
||||
val dialogState: LocationConstraintsDialogState,
|
||||
val locationShares: ImmutableList<LocationShareItem>,
|
||||
|
||||
+4
-3
@@ -18,6 +18,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.preview.USER_NAME_ALICE
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.wellknown.api.MapTilerConfig
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> {
|
||||
@@ -36,14 +37,14 @@ class ShowLocationStateProvider : PreviewParameterProvider<ShowLocationState> {
|
||||
constraintsDialogState = LocationConstraintsDialogState.LocationServiceDisabled,
|
||||
),
|
||||
aShowLocationState(isTrackMyLocation = true),
|
||||
aShowLocationState(customMapStyleUrl = AsyncData.Loading()),
|
||||
aShowLocationState(customMapTilerConfig = AsyncData.Loading()),
|
||||
)
|
||||
}
|
||||
|
||||
private const val APP_NAME = "ApplicationName"
|
||||
|
||||
fun aShowLocationState(
|
||||
customMapStyleUrl: AsyncData<String?> = AsyncData.Success(null),
|
||||
customMapTilerConfig: AsyncData<MapTilerConfig?> = AsyncData.Success(null),
|
||||
isLive: Boolean = false,
|
||||
constraintsDialogState: LocationConstraintsDialogState = LocationConstraintsDialogState.None,
|
||||
locationShares: List<LocationShareItem> = listOf(aLocationShareItem(isLive = isLive)),
|
||||
@@ -55,7 +56,7 @@ fun aShowLocationState(
|
||||
eventSink: (ShowLocationEvent) -> Unit = {},
|
||||
): ShowLocationState {
|
||||
return ShowLocationState(
|
||||
customMapStyleUrl = customMapStyleUrl,
|
||||
customMapTilerConfig = customMapTilerConfig,
|
||||
dialogState = constraintsDialogState,
|
||||
locationShares = locationShares.toImmutableList(),
|
||||
focusedLocation = focusedLocation,
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ fun ShowLocationView(
|
||||
}
|
||||
}
|
||||
MapBottomSheetScaffold(
|
||||
customMapStyleUrl = state.customMapStyleUrl,
|
||||
customMapTilerConfig = state.customMapTilerConfig,
|
||||
sheetDragHandle = if (state.isSheetDraggable) {
|
||||
{ BottomSheetDefaults.DragHandle() }
|
||||
} else {
|
||||
|
||||
+2
@@ -11,6 +11,7 @@ package io.element.android.features.location.impl.share
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.test.remoteconfig.FakeRemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.impl.common.FakeUserLocationStateFactory
|
||||
import io.element.android.features.location.impl.common.actions.FakeLocationActions
|
||||
import io.element.android.features.location.impl.common.permissions.FakePermissionsPresenter
|
||||
@@ -58,6 +59,7 @@ class DefaultShareLocationEntryPointTest {
|
||||
sessionId = room.sessionId,
|
||||
),
|
||||
userLocationStateFactory = FakeUserLocationStateFactory(),
|
||||
remoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(),
|
||||
)
|
||||
},
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
|
||||
+17
-12
@@ -19,6 +19,8 @@ import app.cash.turbine.ReceiveTurbine
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import im.vector.app.features.analytics.plan.Composer
|
||||
import io.element.android.features.enterprise.api.remoteconfig.RemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.enterprise.test.remoteconfig.FakeRemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.impl.aPermissionsState
|
||||
import io.element.android.features.location.impl.common.FakeUserLocationStateFactory
|
||||
@@ -30,6 +32,8 @@ import io.element.android.features.location.impl.common.ui.LocationConstraintsDi
|
||||
import io.element.android.features.location.impl.live.LiveLocationStore
|
||||
import io.element.android.features.location.test.FakeActiveLiveLocationShareManager
|
||||
import io.element.android.features.messages.test.FakeMessageComposerContext
|
||||
import io.element.android.features.wellknown.test.aMapTilerConfig
|
||||
import io.element.android.features.wellknown.test.anElementWellKnown
|
||||
import io.element.android.libraries.dateformatter.test.FakeDurationFormatter
|
||||
import io.element.android.libraries.matrix.api.core.EventId
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
@@ -51,6 +55,7 @@ import io.element.android.libraries.matrix.test.room.powerlevels.FakeRoomPermiss
|
||||
import io.element.android.libraries.matrix.test.timeline.FakeTimeline
|
||||
import io.element.android.libraries.preferences.api.store.PreferenceDataStoreFactory
|
||||
import io.element.android.libraries.preferences.test.FakePreferenceDataStoreFactory
|
||||
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.lambda.assert
|
||||
@@ -60,7 +65,6 @@ import io.element.android.tests.testutils.test
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Rule
|
||||
@@ -77,20 +81,18 @@ class ShareLocationPresenterTest {
|
||||
private val fakeMessageComposerContext = FakeMessageComposerContext()
|
||||
private val fakeLocationActions = FakeLocationActions()
|
||||
private val fakeBuildMeta = aBuildMeta(applicationName = "app name")
|
||||
private val fakeMatrixClient = FakeMatrixClient(
|
||||
sessionId = A_USER_ID,
|
||||
getMapStyleUrlResult = { Result.success(null) },
|
||||
)
|
||||
private val fakeMatrixClient = FakeMatrixClient(sessionId = A_USER_ID)
|
||||
|
||||
private val durationFormatter = FakeDurationFormatter()
|
||||
|
||||
private fun TestScope.createShareLocationPresenter(
|
||||
private fun createShareLocationPresenter(
|
||||
joinedRoom: JoinedRoom = FakeJoinedRoom(),
|
||||
timelineMode: Timeline.Mode = Timeline.Mode.Live,
|
||||
locationActions: FakeLocationActions = fakeLocationActions,
|
||||
liveLocationShareManager: FakeActiveLiveLocationShareManager = FakeActiveLiveLocationShareManager(),
|
||||
liveLocationStore: LiveLocationStore = createLiveLocationStore(sessionId = joinedRoom.sessionId),
|
||||
client: FakeMatrixClient = fakeMatrixClient,
|
||||
remoteEnterpriseConfigProvider: RemoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(),
|
||||
): ShareLocationPresenter = ShareLocationPresenter(
|
||||
permissionsPresenterFactory = { fakePermissionsPresenter },
|
||||
room = joinedRoom,
|
||||
@@ -104,6 +106,7 @@ class ShareLocationPresenterTest {
|
||||
liveLocationShareManager = liveLocationShareManager,
|
||||
liveLocationStore = liveLocationStore,
|
||||
userLocationStateFactory = FakeUserLocationStateFactory(),
|
||||
remoteEnterpriseConfigProvider = remoteEnterpriseConfigProvider,
|
||||
)
|
||||
|
||||
@Test
|
||||
@@ -118,7 +121,7 @@ class ShareLocationPresenterTest {
|
||||
val shareLocationPresenter = createShareLocationPresenter()
|
||||
shareLocationPresenter.test {
|
||||
val state = awaitFirstItem()
|
||||
assertThat(state.customMapStyleUrl.isLoading()).isFalse()
|
||||
assertThat(state.customMapTilerConfig.isLoading()).isFalse()
|
||||
assertThat(state.trackUserLocation).isTrue()
|
||||
assertThat(state.dialogState).isEqualTo(ShareLocationState.Dialog.Constraints(LocationConstraintsDialogState.None))
|
||||
}
|
||||
@@ -126,18 +129,20 @@ class ShareLocationPresenterTest {
|
||||
|
||||
@Test
|
||||
fun `present - non-null customMapStyleUrl`() = runTest {
|
||||
val mapTilerConfig = aMapTilerConfig(apiKey = "A KEY")
|
||||
val shareLocationPresenter = createShareLocationPresenter(
|
||||
client = FakeMatrixClient(
|
||||
sessionId = A_USER_ID,
|
||||
getMapStyleUrlResult = { Result.success("aUrl") },
|
||||
),
|
||||
remoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(
|
||||
getResult = { WellknownRetrieverResult.Success(anElementWellKnown(mapTilerConfig = mapTilerConfig)) }
|
||||
)
|
||||
)
|
||||
shareLocationPresenter.test {
|
||||
skipItems(1)
|
||||
val state = awaitItem()
|
||||
assertThat(state.customMapStyleUrl.isLoading()).isTrue()
|
||||
assertThat(state.customMapTilerConfig.isLoading()).isTrue()
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.customMapStyleUrl.dataOrNull()).isEqualTo("aUrl")
|
||||
assertThat(finalState.customMapTilerConfig.dataOrNull()).isEqualTo(mapTilerConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -709,7 +714,7 @@ class ShareLocationPresenterTest {
|
||||
}
|
||||
|
||||
private suspend fun <T> ReceiveTurbine<T>.awaitFirstItem(): T {
|
||||
skipItems(2)
|
||||
skipItems(1)
|
||||
return awaitItem()
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -11,6 +11,7 @@ package io.element.android.features.location.impl.show
|
||||
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
|
||||
import com.bumble.appyx.core.modality.BuildContext
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.test.remoteconfig.FakeRemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationEntryPoint
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
@@ -20,7 +21,7 @@ import io.element.android.features.location.impl.common.permissions.FakePermissi
|
||||
import io.element.android.features.location.test.FakeActiveLiveLocationShareManager
|
||||
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||
@@ -41,8 +42,8 @@ class DefaultShowLocationEntryPointTest {
|
||||
ShowLocationNode(
|
||||
buildContext = buildContext,
|
||||
plugins = plugins,
|
||||
presenterFactory = object : ShowLocationPresenter.Factory {
|
||||
override fun create(mode: ShowLocationMode) = ShowLocationPresenter(
|
||||
presenterFactory = { mode ->
|
||||
ShowLocationPresenter(
|
||||
mode = mode,
|
||||
permissionsPresenterFactory = { FakePermissionsPresenter() },
|
||||
locationActions = FakeLocationActions(),
|
||||
@@ -50,9 +51,10 @@ class DefaultShowLocationEntryPointTest {
|
||||
dateFormatter = FakeDateFormatter(),
|
||||
stringProvider = FakeStringProvider(),
|
||||
joinedRoom = joinedRoom,
|
||||
client = FakeMatrixClient(),
|
||||
sessionId = A_SESSION_ID,
|
||||
liveLocationShareManager = FakeActiveLiveLocationShareManager(),
|
||||
userLocationStateFactory = FakeUserLocationStateFactory(),
|
||||
remoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(),
|
||||
)
|
||||
},
|
||||
analyticsService = FakeAnalyticsService(),
|
||||
|
||||
+36
-11
@@ -12,6 +12,7 @@ import app.cash.molecule.RecompositionMode
|
||||
import app.cash.molecule.moleculeFlow
|
||||
import app.cash.turbine.test
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.enterprise.test.remoteconfig.FakeRemoteEnterpriseConfigProvider
|
||||
import io.element.android.features.location.api.Location
|
||||
import io.element.android.features.location.api.ShowLocationMode
|
||||
import io.element.android.features.location.impl.aPermissionsState
|
||||
@@ -22,17 +23,20 @@ import io.element.android.features.location.impl.common.permissions.PermissionsE
|
||||
import io.element.android.features.location.impl.common.permissions.PermissionsState
|
||||
import io.element.android.features.location.impl.common.ui.LocationConstraintsDialogState
|
||||
import io.element.android.features.location.test.FakeActiveLiveLocationShareManager
|
||||
import io.element.android.features.wellknown.test.aMapTilerConfig
|
||||
import io.element.android.features.wellknown.test.anElementWellKnown
|
||||
import io.element.android.libraries.dateformatter.test.FakeDateFormatter
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.SessionId
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.JoinedRoom
|
||||
import io.element.android.libraries.matrix.api.room.location.AssetType
|
||||
import io.element.android.libraries.matrix.api.room.location.LiveLocationShare
|
||||
import io.element.android.libraries.matrix.test.A_SESSION_ID
|
||||
import io.element.android.libraries.matrix.test.A_USER_ID
|
||||
import io.element.android.libraries.matrix.test.FakeMatrixClient
|
||||
import io.element.android.libraries.matrix.test.core.aBuildMeta
|
||||
import io.element.android.libraries.matrix.test.room.FakeJoinedRoom
|
||||
import io.element.android.libraries.matrix.test.room.location.aLiveLocationShare
|
||||
import io.element.android.libraries.wellknown.api.WellknownRetrieverResult
|
||||
import io.element.android.services.toolbox.test.strings.FakeStringProvider
|
||||
import io.element.android.tests.testutils.WarmUpRule
|
||||
import io.element.android.tests.testutils.test
|
||||
@@ -65,8 +69,9 @@ class ShowLocationPresenterTest {
|
||||
),
|
||||
locationActions: FakeLocationActions = fakeLocationActions,
|
||||
joinedRoom: JoinedRoom = FakeJoinedRoom(),
|
||||
client: MatrixClient = FakeMatrixClient(),
|
||||
sessionId: SessionId = A_SESSION_ID,
|
||||
liveLocationShareManager: FakeActiveLiveLocationShareManager = FakeActiveLiveLocationShareManager(),
|
||||
remoteEnterpriseConfigProvider: FakeRemoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(),
|
||||
) = ShowLocationPresenter(
|
||||
mode = mode,
|
||||
permissionsPresenterFactory = { fakePermissionsPresenter },
|
||||
@@ -75,24 +80,26 @@ class ShowLocationPresenterTest {
|
||||
dateFormatter = fakeDateFormatter,
|
||||
stringProvider = FakeStringProvider(),
|
||||
joinedRoom = joinedRoom,
|
||||
client = client,
|
||||
sessionId = sessionId,
|
||||
liveLocationShareManager = liveLocationShareManager,
|
||||
userLocationStateFactory = FakeUserLocationStateFactory(),
|
||||
remoteEnterpriseConfigProvider = remoteEnterpriseConfigProvider,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `present - non-null customMapStyleUrl`() = runTest {
|
||||
val mapTilerConfig = aMapTilerConfig(apiKey = "A KEY")
|
||||
val shareLocationPresenter = createShowLocationPresenter(
|
||||
client = FakeMatrixClient(
|
||||
sessionId = A_USER_ID,
|
||||
getMapStyleUrlResult = { Result.success("aUrl") },
|
||||
sessionId = A_SESSION_ID,
|
||||
remoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(
|
||||
getResult = { WellknownRetrieverResult.Success(anElementWellKnown(mapTilerConfig = mapTilerConfig)) }
|
||||
)
|
||||
)
|
||||
shareLocationPresenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.customMapStyleUrl.isLoading()).isTrue()
|
||||
assertThat(state.customMapTilerConfig.isLoading()).isTrue()
|
||||
val finalState = awaitItem()
|
||||
assertThat(finalState.customMapStyleUrl.dataOrNull()).isEqualTo("aUrl")
|
||||
assertThat(finalState.customMapTilerConfig.dataOrNull()).isEqualTo(mapTilerConfig)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +122,8 @@ class ShowLocationPresenterTest {
|
||||
initialState.eventSink(ShowLocationEvent.Share(location))
|
||||
|
||||
assertThat(fakeLocationActions.sharedLocation).isEqualTo(location)
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,10 +132,12 @@ class ShowLocationPresenterTest {
|
||||
fakePermissionsPresenter.givenState(aPermissionsState(permissions = PermissionsState.Permissions.AllGranted))
|
||||
|
||||
val presenter = createShowLocationPresenter(
|
||||
client = FakeMatrixClient(
|
||||
getMapStyleUrlResult = { Result.success(null) }
|
||||
sessionId = A_SESSION_ID,
|
||||
remoteEnterpriseConfigProvider = FakeRemoteEnterpriseConfigProvider(
|
||||
getResult = { WellknownRetrieverResult.Success(anElementWellKnown(mapTilerConfig = aMapTilerConfig())) }
|
||||
)
|
||||
)
|
||||
|
||||
presenter.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.isTrackMyLocation).isFalse()
|
||||
@@ -281,6 +292,8 @@ class ShowLocationPresenterTest {
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.appName).isEqualTo("app name")
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,6 +347,8 @@ class ShowLocationPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.locationShares).isEmpty()
|
||||
assertThat(initialState.isSheetDraggable).isFalse()
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -408,6 +423,9 @@ class ShowLocationPresenterTest {
|
||||
val initialState = awaitItem()
|
||||
assertThat(initialState.locationShares).isEmpty()
|
||||
|
||||
// Wait until we receive the custom map style URL result
|
||||
skipItems(1)
|
||||
|
||||
// Emit a new live share
|
||||
liveSharesFlow.value = listOf(
|
||||
aLiveLocationShare(userId = userId)
|
||||
@@ -447,6 +465,8 @@ class ShowLocationPresenterTest {
|
||||
assertThat(item.avatarData.id).isEqualTo(senderId.value)
|
||||
assertThat(item.avatarData.name).isEqualTo(senderName)
|
||||
assertThat(item.avatarData.url).isEqualTo(avatarUrl)
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,6 +476,7 @@ class ShowLocationPresenterTest {
|
||||
presenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.isSheetDraggable).isFalse()
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -465,6 +486,8 @@ class ShowLocationPresenterTest {
|
||||
presenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.hideUserLocationPuck).isFalse()
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -476,6 +499,8 @@ class ShowLocationPresenterTest {
|
||||
presenter.test {
|
||||
val state = awaitItem()
|
||||
assertThat(state.hideUserLocationPuck).isFalse()
|
||||
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user