From 6386c1603f402dfc2dc4010b603e6efd83a5104e Mon Sep 17 00:00:00 2001 From: Maxime NATUREL Date: Wed, 8 Jun 2022 16:56:29 +0200 Subject: [PATCH] Adding tests on beacon info aggregation --- ...cationShareAggregatedSummaryEntityQuery.kt | 1 + .../LiveLocationAggregationProcessorTest.kt | 120 ++++++++++++++++++ .../poll/PollAggregationProcessorTest.kt | 15 +-- .../android/sdk/test/fakes/FakeRealm.kt | 53 +++++++- .../sdk/test/fakes/FakeWorkManagerProvider.kt | 10 ++ 5 files changed, 185 insertions(+), 14 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt index 7dfeb6884a..6bcd737474 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/LiveLocationShareAggregatedSummaryEntityQuery.kt @@ -84,6 +84,7 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findActiveLiveIn .equalTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true) .notEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, ignoredEventId) .findAll() + .toList() } /** diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt index 6a52a03880..1638e4b4b4 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessorTest.kt @@ -16,26 +16,37 @@ package org.matrix.android.sdk.internal.session.room.aggregation.livelocation +import androidx.work.OneTimeWorkRequest +import io.mockk.verify import org.amshove.kluent.shouldBeEqualTo import org.junit.Test import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.UnsignedData import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconInfoContent import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent +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.FakeClock import org.matrix.android.sdk.test.fakes.FakeRealm import org.matrix.android.sdk.test.fakes.FakeWorkManagerProvider +import org.matrix.android.sdk.test.fakes.givenEqualTo +import org.matrix.android.sdk.test.fakes.givenFindAll +import org.matrix.android.sdk.test.fakes.givenFindFirst +import org.matrix.android.sdk.test.fakes.givenNotEqualTo private const val A_SESSION_ID = "session_id" private const val A_SENDER_ID = "sender_id" private const val AN_EVENT_ID = "event_id" private const val A_ROOM_ID = "room_id" +private const val A_TIMESTAMP = 1654689143L +private const val A_TIMEOUT_MILLIS = 15 * 60 * 1000L internal class LiveLocationAggregationProcessorTest { private val fakeWorkManagerProvider = FakeWorkManagerProvider() private val fakeClock = FakeClock() private val fakeRealm = FakeRealm() + private val fakeQuery = fakeRealm.givenWhere() private val liveLocationAggregationProcessor = LiveLocationAggregationProcessor( sessionId = A_SESSION_ID, @@ -133,6 +144,85 @@ internal class LiveLocationAggregationProcessorTest { resultNotLiveEmptyEventId shouldBeEqualTo false } + @Test + fun `given beacon info and existing entity when beacon content is correct and active then it is aggregated`() { + val event = Event( + senderId = A_SENDER_ID, + eventId = AN_EVENT_ID + ) + val beaconInfo = MessageBeaconInfoContent( + isLive = true, + unstableTimestampMillis = A_TIMESTAMP, + timeout = A_TIMEOUT_MILLIS + ) + fakeClock.givenEpoch(A_TIMESTAMP + 5000) + val aggregatedEntity = mockLiveLocationShareAggregatedSummaryEntityForEvent() + val previousEntities = mockPreviousLiveLocationShareAggregatedSummaryEntities() + + val result = liveLocationAggregationProcessor.handleBeaconInfo( + realm = fakeRealm.instance, + event = event, + content = beaconInfo, + roomId = A_ROOM_ID, + isLocalEcho = false + ) + + result shouldBeEqualTo true + aggregatedEntity.eventId shouldBeEqualTo AN_EVENT_ID + aggregatedEntity.roomId shouldBeEqualTo A_ROOM_ID + aggregatedEntity.userId shouldBeEqualTo A_SENDER_ID + aggregatedEntity.isActive shouldBeEqualTo true + aggregatedEntity.endOfLiveTimestampMillis shouldBeEqualTo A_TIMESTAMP + A_TIMEOUT_MILLIS + aggregatedEntity.lastLocationContent shouldBeEqualTo null + previousEntities.forEach { entity -> + entity.isActive shouldBeEqualTo false + } + val workManager = fakeWorkManagerProvider.instance.workManager + verify { workManager.enqueueUniqueWork(any(), any(), any()) } + } + + @Test + fun `given beacon info and existing entity when beacon content is correct and inactive then it is aggregated`() { + val unsignedData = UnsignedData( + age = 123, + replacesState = AN_EVENT_ID + ) + val event = Event( + senderId = A_SENDER_ID, + eventId = "", + unsignedData = unsignedData + ) + val beaconInfo = MessageBeaconInfoContent( + isLive = false, + unstableTimestampMillis = A_TIMESTAMP, + timeout = A_TIMEOUT_MILLIS + ) + fakeClock.givenEpoch(A_TIMESTAMP + 5000) + val aggregatedEntity = mockLiveLocationShareAggregatedSummaryEntityForEvent() + val previousEntities = mockPreviousLiveLocationShareAggregatedSummaryEntities() + + val result = liveLocationAggregationProcessor.handleBeaconInfo( + realm = fakeRealm.instance, + event = event, + content = beaconInfo, + roomId = A_ROOM_ID, + isLocalEcho = false + ) + + result shouldBeEqualTo true + aggregatedEntity.eventId shouldBeEqualTo AN_EVENT_ID + aggregatedEntity.roomId shouldBeEqualTo A_ROOM_ID + aggregatedEntity.userId shouldBeEqualTo A_SENDER_ID + aggregatedEntity.isActive shouldBeEqualTo false + aggregatedEntity.endOfLiveTimestampMillis shouldBeEqualTo A_TIMESTAMP + A_TIMEOUT_MILLIS + aggregatedEntity.lastLocationContent shouldBeEqualTo null + previousEntities.forEach { entity -> + entity.isActive shouldBeEqualTo false + } + val workManager = fakeWorkManagerProvider.instance.workManager + verify { workManager.cancelUniqueWork(any()) } + } + @Test fun `given beacon location data when it is local echo then it is ignored`() { val event = Event(senderId = A_SENDER_ID) @@ -202,4 +292,34 @@ internal class LiveLocationAggregationProcessorTest { resultNoSenderId shouldBeEqualTo false resultEmptySenderId shouldBeEqualTo false } + + private fun mockLiveLocationShareAggregatedSummaryEntityForEvent(): LiveLocationShareAggregatedSummaryEntity { + val result = LiveLocationShareAggregatedSummaryEntity( + eventId = AN_EVENT_ID, + roomId = A_ROOM_ID + ) + fakeQuery + .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, AN_EVENT_ID) + .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, A_ROOM_ID) + .givenFindFirst(result) + return result + } + + private fun mockPreviousLiveLocationShareAggregatedSummaryEntities(): List { + val results = listOf( + LiveLocationShareAggregatedSummaryEntity( + eventId = "", + roomId = A_ROOM_ID, + userId = A_SENDER_ID, + isActive = true + ) + ) + fakeQuery + .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, A_ROOM_ID) + .givenNotEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, AN_EVENT_ID) + .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.USER_ID, A_SENDER_ID) + .givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true) + .givenFindAll(results) + return results + } } diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt index 837bbeea26..3044ca5d43 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/room/aggregation/poll/PollAggregationProcessorTest.kt @@ -19,8 +19,6 @@ package org.matrix.android.sdk.internal.session.room.aggregation.poll import io.mockk.every import io.mockk.mockk import io.realm.RealmList -import io.realm.RealmModel -import io.realm.RealmQuery import org.amshove.kluent.shouldBeFalse import org.amshove.kluent.shouldBeTrue import org.junit.Before @@ -46,6 +44,8 @@ import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsT import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_TIMELINE_EVENT import org.matrix.android.sdk.internal.session.room.aggregation.poll.PollEventsTestData.A_USER_ID_1 import org.matrix.android.sdk.test.fakes.FakeRealm +import org.matrix.android.sdk.test.fakes.givenEqualTo +import org.matrix.android.sdk.test.fakes.givenFindFirst class PollAggregationProcessorTest { @@ -135,14 +135,11 @@ class PollAggregationProcessorTest { pollAggregationProcessor.handlePollEndEvent(session, powerLevelsHelper, realm.instance, event).shouldBeFalse() } - private inline fun RealmQuery.givenEqualTo(fieldName: String, value: String, result: RealmQuery) { - every { equalTo(fieldName, value) } returns result - } - private fun mockEventAnnotationsSummaryEntity() { - val queryResult = realm.givenWhereReturns(result = EventAnnotationsSummaryEntity()) - queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.ROOM_ID, A_POLL_REPLACE_EVENT.roomId!!, queryResult) - queryResult.givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_POLL_REPLACE_EVENT.eventId!!, queryResult) + realm.givenWhere() + .givenFindFirst(EventAnnotationsSummaryEntity()) + .givenEqualTo(EventAnnotationsSummaryEntityFields.ROOM_ID, A_POLL_REPLACE_EVENT.roomId!!) + .givenEqualTo(EventAnnotationsSummaryEntityFields.EVENT_ID, A_POLL_REPLACE_EVENT.eventId!!) } private fun mockRoom( diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt index c07f8e1873..1697921a8d 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRealm.kt @@ -21,16 +21,59 @@ import io.mockk.mockk import io.realm.Realm import io.realm.RealmModel import io.realm.RealmQuery +import io.realm.RealmResults import io.realm.kotlin.where internal class FakeRealm { val instance = mockk(relaxed = true) - inline fun givenWhereReturns(result: T?): RealmQuery { - val queryResult = mockk>() - every { queryResult.findFirst() } returns result - every { instance.where() } returns queryResult - return queryResult + inline fun givenWhere(): RealmQuery { + val query = mockk>() + every { instance.where() } returns query + return query } } + +inline fun RealmQuery.givenFindFirst( + result: T? +): RealmQuery { + every { findFirst() } returns result + return this +} + +inline fun RealmQuery.givenFindAll( + result: List +): RealmQuery { + val realmResults = mockk>() + result.forEachIndexed { index, t -> + every { realmResults[index] } returns t + } + every { realmResults.size } returns result.size + every { findAll() } returns realmResults + return this +} + +inline fun RealmQuery.givenEqualTo( + fieldName: String, + value: String +): RealmQuery { + every { equalTo(fieldName, value) } returns this + return this +} + +inline fun RealmQuery.givenEqualTo( + fieldName: String, + value: Boolean +): RealmQuery { + every { equalTo(fieldName, value) } returns this + return this +} + +inline fun RealmQuery.givenNotEqualTo( + fieldName: String, + value: String +): RealmQuery { + every { notEqualTo(fieldName, value) } returns this + return this +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt index 9ba072d35c..b6b435f531 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeWorkManagerProvider.kt @@ -16,10 +16,20 @@ package org.matrix.android.sdk.test.fakes +import androidx.work.OneTimeWorkRequest +import androidx.work.WorkManager +import io.mockk.every import io.mockk.mockk import org.matrix.android.sdk.internal.di.WorkManagerProvider internal class FakeWorkManagerProvider { val instance = mockk() + + init { + val workManager = mockk() + every { workManager.enqueueUniqueWork(any(), any(), any()) } returns mockk() + every { workManager.cancelUniqueWork(any()) } returns mockk() + every { instance.workManager } returns workManager + } }