Unit test for method to get live data of active lives

This commit is contained in:
Maxime NATUREL 2022-06-13 16:32:45 +02:00
parent 752434acb4
commit 7d4df8be09
5 changed files with 184 additions and 13 deletions

View File

@ -16,15 +16,17 @@
package org.matrix.android.sdk.internal.database.mapper
import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
import javax.inject.Inject
internal class LiveLocationShareAggregatedSummaryMapper @Inject constructor() {
internal class LiveLocationShareAggregatedSummaryMapper @Inject constructor() :
Monarchy.Mapper<LiveLocationShareAggregatedSummary, LiveLocationShareAggregatedSummaryEntity> {
fun map(entity: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary {
override fun map(entity: LiveLocationShareAggregatedSummaryEntity): LiveLocationShareAggregatedSummary {
return LiveLocationShareAggregatedSummary(
userId = entity.userId,
isActive = entity.isActive,

View File

@ -29,7 +29,6 @@ import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationS
import org.matrix.android.sdk.internal.database.query.findRunningLiveInRoom
import org.matrix.android.sdk.internal.di.SessionDatabase
// TODO add unit tests
internal class DefaultLocationSharingService @AssistedInject constructor(
@Assisted private val roomId: String,
@SessionDatabase private val monarchy: Monarchy,
@ -85,7 +84,7 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
override fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>> {
return monarchy.findAllMappedWithChanges(
{ LiveLocationShareAggregatedSummaryEntity.findRunningLiveInRoom(it, roomId = roomId) },
{ liveLocationShareAggregatedSummaryMapper.map(it) }
liveLocationShareAggregatedSummaryMapper
)
}
}

View File

@ -0,0 +1,85 @@
/*
* 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.mockk
import io.mockk.unmockkAll
import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Test
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.internal.database.mapper.LiveLocationShareAggregatedSummaryMapper
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.FakeMonarchy
import org.matrix.android.sdk.test.fakes.givenEqualTo
import org.matrix.android.sdk.test.fakes.givenIsNotEmpty
import org.matrix.android.sdk.test.fakes.givenIsNotNull
private const val A_ROOM_ID = "room_id"
internal class DefaultLocationSharingServiceTest {
private val fakeRoomId = A_ROOM_ID
private val fakeMonarchy = FakeMonarchy()
private val sendStaticLocationTask = mockk<SendStaticLocationTask>()
private val sendLiveLocationTask = mockk<SendLiveLocationTask>()
private val startLiveLocationShareTask = mockk<StartLiveLocationShareTask>()
private val stopLiveLocationShareTask = mockk<StopLiveLocationShareTask>()
private val fakeLiveLocationShareAggregatedSummaryMapper = mockk<LiveLocationShareAggregatedSummaryMapper>()
private val defaultLocationSharingService = DefaultLocationSharingService(
roomId = fakeRoomId,
monarchy = fakeMonarchy.instance,
sendStaticLocationTask = sendStaticLocationTask,
sendLiveLocationTask = sendLiveLocationTask,
startLiveLocationShareTask = startLiveLocationShareTask,
stopLiveLocationShareTask = stopLiveLocationShareTask,
liveLocationShareAggregatedSummaryMapper = fakeLiveLocationShareAggregatedSummaryMapper
)
@After
fun tearDown() {
unmockkAll()
}
@Test
fun `livedata of live summaries is correctly computed`() {
val entity = LiveLocationShareAggregatedSummaryEntity()
val summary = LiveLocationShareAggregatedSummary(
userId = "",
isActive = true,
endOfLiveTimestampMillis = 123,
lastLocationDataContent = null
)
fakeMonarchy.givenWhere<LiveLocationShareAggregatedSummaryEntity>()
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, fakeRoomId)
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true)
.givenIsNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
.givenIsNotNull(LiveLocationShareAggregatedSummaryEntityFields.LAST_LOCATION_CONTENT)
fakeMonarchy.givenFindAllMappedWithChangesReturns(
realmEntities = listOf(entity),
mappedResult = listOf(summary),
fakeLiveLocationShareAggregatedSummaryMapper
)
val result = defaultLocationSharingService.getRunningLiveLocationShareSummaries().value
result shouldBeEqualTo listOf(summary)
}
}

View File

@ -16,40 +16,62 @@
package org.matrix.android.sdk.test.fakes
import androidx.lifecycle.MutableLiveData
import com.zhuinden.monarchy.Monarchy
import io.mockk.MockKVerificationScope
import io.mockk.coEvery
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.verify
import io.mockk.slot
import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmQuery
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.util.awaitTransaction
internal class FakeMonarchy {
val instance = mockk<Monarchy>()
private val realm = mockk<Realm>(relaxed = true)
private val fakeRealm = FakeRealm()
init {
mockkStatic("org.matrix.android.sdk.internal.util.MonarchyKt")
coEvery {
instance.awaitTransaction(any<suspend (Realm) -> Any>())
} coAnswers {
secondArg<suspend (Realm) -> Any>().invoke(realm)
secondArg<suspend (Realm) -> Any>().invoke(fakeRealm.instance)
}
}
inline fun <reified T : RealmModel> givenWhereReturns(result: T?) {
val queryResult = mockk<RealmQuery<T>>(relaxed = true)
every { queryResult.findFirst() } returns result
every { realm.where<T>() } returns queryResult
inline fun <reified T : RealmModel> givenWhere(): RealmQuery<T> {
return fakeRealm.givenWhere()
}
inline fun <reified T : RealmModel> givenWhereReturns(result: T?): RealmQuery<T> {
return fakeRealm.givenWhere<T>()
.givenFindFirst(result)
}
inline fun <reified T : RealmModel> verifyInsertOrUpdate(crossinline verification: MockKVerificationScope.() -> T) {
verify { realm.insertOrUpdate(verification()) }
fakeRealm.verifyInsertOrUpdate(verification)
}
inline fun <reified R, reified T : RealmModel> givenFindAllMappedWithChangesReturns(
realmEntities: List<T>,
mappedResult: List<R>,
mapper: Monarchy.Mapper<R, T>
) {
every { mapper.map(any()) } returns mockk()
val monarchyQuery = slot<Monarchy.Query<T>>()
val monarchyMapper = slot<Monarchy.Mapper<R, T>>()
every {
instance.findAllMappedWithChanges(capture(monarchyQuery), capture(monarchyMapper))
} answers {
monarchyQuery.captured.createQuery(fakeRealm.instance)
realmEntities.forEach {
monarchyMapper.captured.map(it)
}
MutableLiveData(mappedResult)
}
}
}

View File

@ -16,8 +16,10 @@
package org.matrix.android.sdk.test.fakes
import io.mockk.MockKVerificationScope
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmQuery
@ -33,6 +35,67 @@ internal class FakeRealm {
every { instance.where<T>() } returns query
return query
}
inline fun <reified T : RealmModel> verifyInsertOrUpdate(crossinline verification: MockKVerificationScope.() -> T) {
verify { instance.insertOrUpdate(verification()) }
}
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenFindFirst(
result: T?
): RealmQuery<T> {
every { findFirst() } returns result
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenFindAll(
result: List<T>
): RealmQuery<T> {
val realmResults = mockk<RealmResults<T>>()
result.forEachIndexed { index, t ->
every { realmResults[index] } returns t
}
every { realmResults.size } returns result.size
every { findAll() } returns realmResults
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenEqualTo(
fieldName: String,
value: String
): RealmQuery<T> {
every { equalTo(fieldName, value) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenEqualTo(
fieldName: String,
value: Boolean
): RealmQuery<T> {
every { equalTo(fieldName, value) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenNotEqualTo(
fieldName: String,
value: String
): RealmQuery<T> {
every { notEqualTo(fieldName, value) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenIsNotEmpty(
fieldName: String
): RealmQuery<T> {
every { isNotEmpty(fieldName) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenIsNotNull(
fieldName: String
): RealmQuery<T> {
every { isNotNull(fieldName) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenFindFirst(