Deleting summaries related to a redacted live location sharing
This commit is contained in:
parent
d3ad8d8deb
commit
f6415b0a5d
@ -23,6 +23,11 @@ import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEnt
|
|||||||
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields
|
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields
|
||||||
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
|
||||||
|
|
||||||
|
internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
|
||||||
|
return realm.where<EventAnnotationsSummaryEntity>()
|
||||||
|
.equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, roomId: String, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
|
internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, roomId: String, eventId: String): RealmQuery<EventAnnotationsSummaryEntity> {
|
||||||
return realm.where<EventAnnotationsSummaryEntity>()
|
return realm.where<EventAnnotationsSummaryEntity>()
|
||||||
.equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId)
|
.equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId)
|
||||||
@ -44,3 +49,7 @@ internal fun EventAnnotationsSummaryEntity.Companion.getOrCreate(realm: Realm, r
|
|||||||
return EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
|
return EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst()
|
||||||
?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId)
|
?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun EventAnnotationsSummaryEntity.Companion.get(realm: Realm, eventId: String): EventAnnotationsSummaryEntity? {
|
||||||
|
return EventAnnotationsSummaryEntity.where(realm, eventId).findFirst()
|
||||||
|
}
|
||||||
|
@ -88,6 +88,7 @@ import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationPro
|
|||||||
import org.matrix.android.sdk.internal.session.room.aggregation.poll.DefaultPollAggregationProcessor
|
import org.matrix.android.sdk.internal.session.room.aggregation.poll.DefaultPollAggregationProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollAggregationProcessor
|
import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollAggregationProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor
|
import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor
|
||||||
|
import org.matrix.android.sdk.internal.session.room.location.LiveLocationShareRedactionEventProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor
|
import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor
|
||||||
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessorCoroutine
|
import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessorCoroutine
|
||||||
@ -321,6 +322,10 @@ internal abstract class SessionModule {
|
|||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindEventRedactionProcessor(processor: RedactionEventProcessor): EventInsertLiveProcessor
|
abstract fun bindEventRedactionProcessor(processor: RedactionEventProcessor): EventInsertLiveProcessor
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun bindLiveLocationShareRedactionEventProcessor(processor: LiveLocationShareRedactionEventProcessor): EventInsertLiveProcessor
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun bindEventRelationsAggregationProcessor(processor: EventRelationsAggregationProcessor): EventInsertLiveProcessor
|
abstract fun bindEventRelationsAggregationProcessor(processor: EventRelationsAggregationProcessor): EventInsertLiveProcessor
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 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.Realm
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.LocalEcho
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||||
|
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.database.query.where
|
||||||
|
import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens to the database for the insertion of any redaction event.
|
||||||
|
* Delete specifically the aggregated summary related to a redacted live location share event.
|
||||||
|
*/
|
||||||
|
internal class LiveLocationShareRedactionEventProcessor @Inject constructor() : EventInsertLiveProcessor {
|
||||||
|
|
||||||
|
override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean {
|
||||||
|
return eventType == EventType.REDACTION && insertType != EventInsertType.LOCAL_ECHO
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun process(realm: Realm, event: Event) {
|
||||||
|
if (event.redacts.isNullOrBlank() || LocalEcho.isLocalEchoId(event.eventId.orEmpty())) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val redactedEvent = EventEntity.where(realm, eventId = event.redacts).findFirst()
|
||||||
|
?: return
|
||||||
|
|
||||||
|
if (redactedEvent.type in EventType.STATE_ROOM_BEACON_INFO) {
|
||||||
|
val liveSummary = LiveLocationShareAggregatedSummaryEntity.get(realm, eventId = redactedEvent.eventId)
|
||||||
|
|
||||||
|
if (liveSummary != null) {
|
||||||
|
Timber.d("deleting live summary with id: ${liveSummary.eventId}")
|
||||||
|
liveSummary.deleteFromRealm()
|
||||||
|
val annotationsSummary = EventAnnotationsSummaryEntity.get(realm, eventId = redactedEvent.eventId)
|
||||||
|
if (annotationsSummary != null) {
|
||||||
|
Timber.d("deleting annotation summary with id: ${annotationsSummary.eventId}")
|
||||||
|
annotationsSummary.deleteFromRealm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* 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.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.amshove.kluent.shouldBe
|
||||||
|
import org.junit.Test
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventAnnotationsSummaryEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventEntity
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.database.model.EventInsertType
|
||||||
|
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.FakeRealm
|
||||||
|
import org.matrix.android.sdk.test.fakes.givenDelete
|
||||||
|
import org.matrix.android.sdk.test.fakes.givenEqualTo
|
||||||
|
import org.matrix.android.sdk.test.fakes.givenFindFirst
|
||||||
|
|
||||||
|
private const val AN_EVENT_ID = "event-id"
|
||||||
|
private const val A_REDACTED_EVENT_ID = "redacted-event-id"
|
||||||
|
|
||||||
|
@ExperimentalCoroutinesApi
|
||||||
|
class LiveLocationShareRedactionEventProcessorTest {
|
||||||
|
|
||||||
|
private val liveLocationShareRedactionEventProcessor = LiveLocationShareRedactionEventProcessor()
|
||||||
|
private val fakeRealm = FakeRealm()
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given an event when checking if it should be processed then only event of type REDACTED is processed`() {
|
||||||
|
val eventId = AN_EVENT_ID
|
||||||
|
val eventType = EventType.REDACTION
|
||||||
|
val insertType = EventInsertType.INCREMENTAL_SYNC
|
||||||
|
|
||||||
|
val result = liveLocationShareRedactionEventProcessor.shouldProcess(
|
||||||
|
eventId = eventId,
|
||||||
|
eventType = eventType,
|
||||||
|
insertType = insertType
|
||||||
|
)
|
||||||
|
|
||||||
|
result shouldBe true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given an event when checking if it should be processed then local echo is not processed`() {
|
||||||
|
val eventId = AN_EVENT_ID
|
||||||
|
val eventType = EventType.REDACTION
|
||||||
|
val insertType = EventInsertType.LOCAL_ECHO
|
||||||
|
|
||||||
|
val result = liveLocationShareRedactionEventProcessor.shouldProcess(
|
||||||
|
eventId = eventId,
|
||||||
|
eventType = eventType,
|
||||||
|
insertType = insertType
|
||||||
|
)
|
||||||
|
|
||||||
|
result shouldBe false
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a redacted live location share event when processing it then related summaries are deleted from database`() = runTest {
|
||||||
|
val event = Event(eventId = AN_EVENT_ID, redacts = A_REDACTED_EVENT_ID)
|
||||||
|
val redactedEventEntity = EventEntity(eventId = A_REDACTED_EVENT_ID, type = EventType.STATE_ROOM_BEACON_INFO.first())
|
||||||
|
fakeRealm.givenWhere<EventEntity>()
|
||||||
|
.givenEqualTo(EventEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
|
||||||
|
.givenFindFirst(redactedEventEntity)
|
||||||
|
val liveSummary = mockk<LiveLocationShareAggregatedSummaryEntity>()
|
||||||
|
every { liveSummary.eventId } returns A_REDACTED_EVENT_ID
|
||||||
|
liveSummary.givenDelete()
|
||||||
|
fakeRealm.givenWhere<LiveLocationShareAggregatedSummaryEntity>()
|
||||||
|
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
|
||||||
|
.givenFindFirst(liveSummary)
|
||||||
|
val annotationsSummary = mockk<EventAnnotationsSummaryEntity>()
|
||||||
|
every { annotationsSummary.eventId } returns A_REDACTED_EVENT_ID
|
||||||
|
annotationsSummary.givenDelete()
|
||||||
|
fakeRealm.givenWhere<EventAnnotationsSummaryEntity>()
|
||||||
|
.givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_REDACTED_EVENT_ID)
|
||||||
|
.givenFindFirst(annotationsSummary)
|
||||||
|
|
||||||
|
liveLocationShareRedactionEventProcessor.process(fakeRealm.instance, event = event)
|
||||||
|
|
||||||
|
verify {
|
||||||
|
liveSummary.deleteFromRealm()
|
||||||
|
annotationsSummary.deleteFromRealm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -18,10 +18,13 @@ package org.matrix.android.sdk.test.fakes
|
|||||||
|
|
||||||
import io.mockk.MockKVerificationScope
|
import io.mockk.MockKVerificationScope
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
import io.mockk.just
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
|
import io.mockk.runs
|
||||||
import io.mockk.verify
|
import io.mockk.verify
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmModel
|
import io.realm.RealmModel
|
||||||
|
import io.realm.RealmObject
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
import io.realm.RealmResults
|
import io.realm.RealmResults
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
@ -97,3 +100,10 @@ inline fun <reified T : RealmModel> RealmQuery<T>.givenIsNotNull(
|
|||||||
every { isNotNull(fieldName) } returns this
|
every { isNotNull(fieldName) } returns this
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should be called on a mocked RealmObject and not on a real RealmObject so that the underlying final method is mocked.
|
||||||
|
*/
|
||||||
|
fun RealmObject.givenDelete() {
|
||||||
|
every { deleteFromRealm() } just runs
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user