mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 11:59:12 +03:00
Adding task to redact live location share related events
This commit is contained in:
parent
c404454cd7
commit
c9273dd067
7 changed files with 308 additions and 18 deletions
|
@ -23,6 +23,14 @@ import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEnt
|
|||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.where(
|
||||
realm: Realm,
|
||||
eventId: String,
|
||||
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
|
||||
return realm.where<LiveLocationShareAggregatedSummaryEntity>()
|
||||
.equalTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventId)
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.where(
|
||||
realm: Realm,
|
||||
roomId: String,
|
||||
|
@ -72,6 +80,13 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get(
|
|||
return LiveLocationShareAggregatedSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.get(
|
||||
realm: Realm,
|
||||
eventId: String,
|
||||
): LiveLocationShareAggregatedSummaryEntity? {
|
||||
return LiveLocationShareAggregatedSummaryEntity.where(realm, eventId).findFirst()
|
||||
}
|
||||
|
||||
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveInRoomForUser(
|
||||
realm: Realm,
|
||||
roomId: String,
|
||||
|
|
|
@ -58,11 +58,13 @@ import org.matrix.android.sdk.internal.session.room.directory.SetRoomDirectoryVi
|
|||
import org.matrix.android.sdk.internal.session.room.location.CheckIfExistingActiveLiveTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultCheckIfExistingActiveLiveTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultGetActiveBeaconInfoForUserTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultRedactLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultSendLiveLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultSendStaticLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultStartLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.DefaultStopLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.GetActiveBeaconInfoForUserTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.RedactLiveLocationShareTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.SendLiveLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.SendStaticLocationTask
|
||||
import org.matrix.android.sdk.internal.session.room.location.StartLiveLocationShareTask
|
||||
|
@ -339,4 +341,7 @@ internal abstract class RoomModule {
|
|||
|
||||
@Binds
|
||||
abstract fun bindCheckIfExistingActiveLiveTask(task: DefaultCheckIfExistingActiveLiveTask): CheckIfExistingActiveLiveTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindRedactLiveLocationShareTask(task: DefaultRedactLiveLocationShareTask): RedactLiveLocationShareTask
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import io.realm.RealmConfiguration
|
||||
import org.matrix.android.sdk.internal.database.awaitTransaction
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.query.get
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.session.room.send.LocalEchoEventFactory
|
||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface RedactLiveLocationShareTask : Task<RedactLiveLocationShareTask.Params, Unit> {
|
||||
data class Params(
|
||||
val roomId: String,
|
||||
val beaconInfoEventId: String,
|
||||
val reason: String?
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultRedactLiveLocationShareTask @Inject constructor(
|
||||
@SessionDatabase private val realmConfiguration: RealmConfiguration,
|
||||
private val localEchoEventFactory: LocalEchoEventFactory,
|
||||
private val eventSenderProcessor: EventSenderProcessor,
|
||||
) : RedactLiveLocationShareTask {
|
||||
|
||||
override suspend fun execute(params: RedactLiveLocationShareTask.Params) {
|
||||
val relatedEventIds = getRelatedEventIdsOfLive(params.beaconInfoEventId)
|
||||
Timber.d("beacon with id ${params.beaconInfoEventId} has related event ids: ${relatedEventIds.joinToString(", ")}")
|
||||
|
||||
relatedEventIds.forEach { eventId ->
|
||||
redactEvent(
|
||||
eventId = eventId,
|
||||
roomId = params.roomId,
|
||||
reason = params.reason
|
||||
)
|
||||
}
|
||||
|
||||
redactEvent(
|
||||
eventId = params.beaconInfoEventId,
|
||||
roomId = params.roomId,
|
||||
reason = params.reason
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun getRelatedEventIdsOfLive(beaconInfoEventId: String): List<String> {
|
||||
return awaitTransaction(realmConfiguration) { realm ->
|
||||
val aggregatedSummaryEntity = LiveLocationShareAggregatedSummaryEntity.get(
|
||||
realm = realm,
|
||||
eventId = beaconInfoEventId
|
||||
)
|
||||
aggregatedSummaryEntity?.relatedEventIds?.toList() ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun redactEvent(eventId: String, roomId: String, reason: String?) {
|
||||
Timber.d("redacting event of id $eventId")
|
||||
val redactionEcho = localEchoEventFactory.createRedactEvent(roomId, eventId, reason)
|
||||
localEchoEventFactory.createLocalEcho(redactionEcho)
|
||||
eventSenderProcessor.postRedaction(redactionEcho, reason)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.internal.session.room.location
|
||||
|
||||
import io.mockk.unmockkAll
|
||||
import io.realm.RealmList
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.After
|
||||
import org.junit.Test
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntityFields
|
||||
import org.matrix.android.sdk.test.fakes.FakeEventSenderProcessor
|
||||
import org.matrix.android.sdk.test.fakes.FakeLocalEchoEventFactory
|
||||
import org.matrix.android.sdk.test.fakes.FakeRealm
|
||||
import org.matrix.android.sdk.test.fakes.FakeRealmConfiguration
|
||||
import org.matrix.android.sdk.test.fakes.givenEqualTo
|
||||
import org.matrix.android.sdk.test.fakes.givenFindFirst
|
||||
|
||||
private const val A_ROOM_ID = "room-id"
|
||||
private const val AN_EVENT_ID = "event-id"
|
||||
private const val AN_EVENT_ID_1 = "event-id-1"
|
||||
private const val AN_EVENT_ID_2 = "event-id-2"
|
||||
private const val AN_EVENT_ID_3 = "event-id-3"
|
||||
private const val A_REASON = "reason"
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class DefaultRedactLiveLocationShareTaskTest {
|
||||
|
||||
private val fakeRealmConfiguration = FakeRealmConfiguration()
|
||||
private val fakeLocalEchoEventFactory = FakeLocalEchoEventFactory()
|
||||
private val fakeEventSenderProcessor = FakeEventSenderProcessor()
|
||||
private val fakeRealm = FakeRealm()
|
||||
|
||||
private val defaultRedactLiveLocationShareTask = DefaultRedactLiveLocationShareTask(
|
||||
realmConfiguration = fakeRealmConfiguration.instance,
|
||||
localEchoEventFactory = fakeLocalEchoEventFactory.instance,
|
||||
eventSenderProcessor = fakeEventSenderProcessor
|
||||
)
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
unmockkAll()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `given parameters when calling the task then it is correctly executed`() = runTest {
|
||||
val params = RedactLiveLocationShareTask.Params(
|
||||
roomId = A_ROOM_ID,
|
||||
beaconInfoEventId = AN_EVENT_ID,
|
||||
reason = A_REASON
|
||||
)
|
||||
fakeRealmConfiguration.givenAwaitTransaction<List<String>>(fakeRealm.instance)
|
||||
val relatedEventIds = listOf(AN_EVENT_ID_1, AN_EVENT_ID_2, AN_EVENT_ID_3)
|
||||
val aggregatedSummaryEntity = LiveLocationShareAggregatedSummaryEntity(
|
||||
eventId = AN_EVENT_ID,
|
||||
relatedEventIds = RealmList(*relatedEventIds.toTypedArray()),
|
||||
)
|
||||
fakeRealm.givenWhere<LiveLocationShareAggregatedSummaryEntity>()
|
||||
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, AN_EVENT_ID)
|
||||
.givenFindFirst(aggregatedSummaryEntity)
|
||||
val redactedEvent = fakeLocalEchoEventFactory.givenCreateRedactEvent(
|
||||
eventId = AN_EVENT_ID,
|
||||
withLocalEcho = true
|
||||
)
|
||||
fakeEventSenderProcessor.givenPostRedaction(event = redactedEvent, reason = A_REASON)
|
||||
val redactedEvent1 = fakeLocalEchoEventFactory.givenCreateRedactEvent(
|
||||
eventId = AN_EVENT_ID_1,
|
||||
withLocalEcho = true
|
||||
)
|
||||
fakeEventSenderProcessor.givenPostRedaction(event = redactedEvent1, reason = A_REASON)
|
||||
val redactedEvent2 = fakeLocalEchoEventFactory.givenCreateRedactEvent(
|
||||
eventId = AN_EVENT_ID_2,
|
||||
withLocalEcho = true
|
||||
)
|
||||
fakeEventSenderProcessor.givenPostRedaction(event = redactedEvent2, reason = A_REASON)
|
||||
val redactedEvent3 = fakeLocalEchoEventFactory.givenCreateRedactEvent(
|
||||
eventId = AN_EVENT_ID_3,
|
||||
withLocalEcho = true
|
||||
)
|
||||
fakeEventSenderProcessor.givenPostRedaction(event = redactedEvent3, reason = A_REASON)
|
||||
|
||||
defaultRedactLiveLocationShareTask.execute(params)
|
||||
|
||||
fakeLocalEchoEventFactory.verifyCreateRedactEvent(
|
||||
roomId = A_ROOM_ID,
|
||||
eventId = AN_EVENT_ID,
|
||||
reason = A_REASON
|
||||
)
|
||||
fakeLocalEchoEventFactory.verifyCreateLocalEcho(redactedEvent)
|
||||
relatedEventIds.forEach { eventId ->
|
||||
fakeLocalEchoEventFactory.verifyCreateRedactEvent(
|
||||
roomId = A_ROOM_ID,
|
||||
eventId = eventId,
|
||||
reason = A_REASON
|
||||
)
|
||||
}
|
||||
fakeLocalEchoEventFactory.verifyCreateLocalEcho(redactedEvent1)
|
||||
fakeLocalEchoEventFactory.verifyCreateLocalEcho(redactedEvent2)
|
||||
fakeLocalEchoEventFactory.verifyCreateLocalEcho(redactedEvent3)
|
||||
}
|
||||
}
|
|
@ -27,4 +27,8 @@ internal class FakeEventSenderProcessor : EventSenderProcessor by mockk() {
|
|||
fun givenPostEventReturns(event: Event, cancelable: Cancelable) {
|
||||
every { postEvent(event) } returns cancelable
|
||||
}
|
||||
|
||||
fun givenPostRedaction(event: Event, reason: String?) {
|
||||
every { postRedaction(event, reason) } returns mockk()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,24 +46,6 @@ internal class FakeLocalEchoEventFactory {
|
|||
return event
|
||||
}
|
||||
|
||||
fun givenCreateLiveLocationEvent(withLocalEcho: Boolean): Event {
|
||||
val event = Event()
|
||||
every {
|
||||
instance.createLiveLocationEvent(
|
||||
beaconInfoEventId = any(),
|
||||
roomId = any(),
|
||||
latitude = any(),
|
||||
longitude = any(),
|
||||
uncertainty = any()
|
||||
)
|
||||
} returns event
|
||||
|
||||
if (withLocalEcho) {
|
||||
every { instance.createLocalEcho(event) } just runs
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
fun verifyCreateStaticLocationEvent(
|
||||
roomId: String,
|
||||
latitude: Double,
|
||||
|
@ -82,6 +64,24 @@ internal class FakeLocalEchoEventFactory {
|
|||
}
|
||||
}
|
||||
|
||||
fun givenCreateLiveLocationEvent(withLocalEcho: Boolean): Event {
|
||||
val event = Event()
|
||||
every {
|
||||
instance.createLiveLocationEvent(
|
||||
beaconInfoEventId = any(),
|
||||
roomId = any(),
|
||||
latitude = any(),
|
||||
longitude = any(),
|
||||
uncertainty = any()
|
||||
)
|
||||
} returns event
|
||||
|
||||
if (withLocalEcho) {
|
||||
every { instance.createLocalEcho(event) } just runs
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
fun verifyCreateLiveLocationEvent(
|
||||
roomId: String,
|
||||
beaconInfoEventId: String,
|
||||
|
@ -100,6 +100,36 @@ internal class FakeLocalEchoEventFactory {
|
|||
}
|
||||
}
|
||||
|
||||
fun givenCreateRedactEvent(eventId: String, withLocalEcho: Boolean): Event {
|
||||
val event = Event()
|
||||
every {
|
||||
instance.createRedactEvent(
|
||||
roomId = any(),
|
||||
eventId = eventId,
|
||||
reason = any()
|
||||
)
|
||||
} returns event
|
||||
|
||||
if (withLocalEcho) {
|
||||
every { instance.createLocalEcho(event) } just runs
|
||||
}
|
||||
return event
|
||||
}
|
||||
|
||||
fun verifyCreateRedactEvent(
|
||||
roomId: String,
|
||||
eventId: String,
|
||||
reason: String?
|
||||
) {
|
||||
verify {
|
||||
instance.createRedactEvent(
|
||||
roomId = roomId,
|
||||
eventId = eventId,
|
||||
reason = reason
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun verifyCreateLocalEcho(event: Event) {
|
||||
verify { instance.createLocalEcho(event) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* 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 org.matrix.android.sdk.test.fakes
|
||||
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.mockk
|
||||
import io.mockk.mockkStatic
|
||||
import io.mockk.slot
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmConfiguration
|
||||
import org.matrix.android.sdk.internal.database.awaitTransaction
|
||||
|
||||
internal class FakeRealmConfiguration {
|
||||
|
||||
init {
|
||||
mockkStatic("org.matrix.android.sdk.internal.database.AsyncTransactionKt")
|
||||
}
|
||||
|
||||
val instance = mockk<RealmConfiguration>()
|
||||
|
||||
fun <T> givenAwaitTransaction(realm: Realm) {
|
||||
val transaction = slot<suspend (Realm) -> T>()
|
||||
coEvery { awaitTransaction(instance, capture(transaction)) } coAnswers {
|
||||
secondArg<suspend (Realm) -> T>().invoke(realm)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue