From 391bf842b4b266f3fabd9fd4ea840e3957d1563e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Tue, 5 Jul 2022 16:28:44 +0200 Subject: [PATCH] Calling usecase to redact live location share event --- .../sdk/api/session/events/model/Event.kt | 2 + .../room/location/LocationSharingService.kt | 1 - .../session/room/timeline/TimelineEvent.kt | 5 ++ .../home/room/detail/TimelineViewModel.kt | 11 ++++- .../RedactLiveLocationShareEventUseCase.kt | 30 ++++++++++++ ...RedactLiveLocationShareEventUseCaseTest.kt | 49 +++++++++++++++++++ .../test/fakes/FakeLocationSharingService.kt | 11 +++++ 7 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 vector/src/main/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCase.kt create mode 100644 vector/src/test/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCaseTest.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index 554dc2ec9d..59dc6c434d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -371,6 +371,8 @@ fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START || getClear fun Event.isSticker(): Boolean = getClearType() == EventType.STICKER +fun Event.isLiveLocation(): Boolean = getClearType() in EventType.STATE_ROOM_BEACON_INFO + fun Event.getRelationContent(): RelationDefaultContent? { return if (isEncrypted()) { content.toModel()?.relatesTo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt index 50a87fbdc2..cd8acbcccc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/location/LocationSharingService.kt @@ -16,7 +16,6 @@ package org.matrix.android.sdk.api.session.room.location -import androidx.annotation.MainThread import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary import org.matrix.android.sdk.api.util.Cancelable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt index 9d8c8a13bd..d391abf1e6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.RelationType import org.matrix.android.sdk.api.session.events.model.getRelationContent import org.matrix.android.sdk.api.session.events.model.isEdition +import org.matrix.android.sdk.api.session.events.model.isLiveLocation import org.matrix.android.sdk.api.session.events.model.isPoll import org.matrix.android.sdk.api.session.events.model.isReply import org.matrix.android.sdk.api.session.events.model.isSticker @@ -165,6 +166,10 @@ fun TimelineEvent.isSticker(): Boolean { return root.isSticker() } +fun TimelineEvent.isLiveLocation(): Boolean { + return root.isLiveLocation() +} + /** * Returns whether or not the event is a root thread event. */ diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index e305ccbec1..1a68371222 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -48,6 +48,7 @@ import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.createdirect.DirectRoomHelper import im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy import im.vector.app.features.crypto.verification.SupportedVerificationMethodsProvider +import im.vector.app.features.home.room.detail.location.RedactLiveLocationShareEventUseCase import im.vector.app.features.home.room.detail.sticker.StickerPickerActionHandler import im.vector.app.features.home.room.detail.timeline.factory.TimelineFactory import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever @@ -105,6 +106,7 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.read.ReadService import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent +import org.matrix.android.sdk.api.session.room.timeline.isLiveLocation import org.matrix.android.sdk.api.session.sync.SyncRequestState import org.matrix.android.sdk.api.session.threads.ThreadNotificationBadgeState import org.matrix.android.sdk.api.session.threads.ThreadNotificationState @@ -135,6 +137,7 @@ class TimelineViewModel @AssistedInject constructor( private val notificationDrawerManager: NotificationDrawerManager, private val locationSharingServiceConnection: LocationSharingServiceConnection, private val stopLiveLocationShareUseCase: StopLiveLocationShareUseCase, + private val redactLiveLocationShareEventUseCase: RedactLiveLocationShareEventUseCase, timelineFactory: TimelineFactory, appStateHandler: AppStateHandler, ) : VectorViewModel(initialState), @@ -770,7 +773,13 @@ class TimelineViewModel @AssistedInject constructor( private fun handleRedactEvent(action: RoomDetailAction.RedactAction) { val event = room.getTimelineEvent(action.targetEventId) ?: return - room.sendService().redactEvent(event.root, action.reason) + if (event.isLiveLocation()) { + viewModelScope.launch { + redactLiveLocationShareEventUseCase.execute(event.root, room, action.reason) + } + } else { + room.sendService().redactEvent(event.root, action.reason) + } } private fun handleUndoReact(action: RoomDetailAction.UndoReaction) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCase.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCase.kt new file mode 100644 index 0000000000..ba91000b40 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCase.kt @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.location + +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.room.Room +import javax.inject.Inject + +class RedactLiveLocationShareEventUseCase @Inject constructor() { + + suspend fun execute(event: Event, room: Room, reason: String?) { + event.eventId + ?.takeUnless { it.isEmpty() } + ?.let { room.locationSharingService().redactLiveLocationShare(it, reason) } + } +} diff --git a/vector/src/test/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCaseTest.kt new file mode 100644 index 0000000000..89b619fe3c --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/home/room/detail/location/RedactLiveLocationShareEventUseCaseTest.kt @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.location + +import im.vector.app.test.fakes.FakeRoom +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.matrix.android.sdk.api.session.events.model.Event + +private const val AN_EVENT_ID = "event-id" +private const val A_REASON = "reason" + +class RedactLiveLocationShareEventUseCaseTest { + + private val fakeRoom = FakeRoom() + + private val redactLiveLocationShareEventUseCase = RedactLiveLocationShareEventUseCase() + + @Test + fun `given an event with valid id when calling use case then event is redacted in the room`() = runTest { + val event = Event(eventId = AN_EVENT_ID) + fakeRoom.locationSharingService().givenRedactLiveLocationShare(beaconInfoEventId = AN_EVENT_ID, reason = A_REASON) + + redactLiveLocationShareEventUseCase.execute(event = event, room = fakeRoom, reason = A_REASON) + + fakeRoom.locationSharingService().verifyRedactLiveLocationShare(beaconInfoEventId = AN_EVENT_ID, reason = A_REASON) + } + + @Test + fun `given an event with empty id when calling use case then nothing is done`() = runTest { + val event = Event(eventId = "") + + redactLiveLocationShareEventUseCase.execute(event = event, room = fakeRoom, reason = A_REASON) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeLocationSharingService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeLocationSharingService.kt index cebd45b2bb..accb3be877 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeLocationSharingService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeLocationSharingService.kt @@ -19,8 +19,11 @@ package im.vector.app.test.fakes import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.every +import io.mockk.just import io.mockk.mockk +import io.mockk.runs import org.matrix.android.sdk.api.session.room.location.LocationSharingService import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary @@ -48,4 +51,12 @@ class FakeLocationSharingService : LocationSharingService by mockk() { fun givenStopLiveLocationShareReturns(result: UpdateLiveLocationShareResult) { coEvery { stopLiveLocationShare() } returns result } + + fun givenRedactLiveLocationShare(beaconInfoEventId: String, reason: String?) { + coEvery { redactLiveLocationShare(beaconInfoEventId, reason) } just runs + } + + fun verifyRedactLiveLocationShare(beaconInfoEventId: String, reason: String?) { + coVerify { redactLiveLocationShare(beaconInfoEventId, reason) } + } }