Changing in API to get livedata on a live of a given id

This commit is contained in:
Maxime NATUREL 2022-06-20 17:13:16 +02:00
parent 785ce03e67
commit 3cffedd353
10 changed files with 79 additions and 80 deletions

View file

@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.session.room.location
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.Optional
/**
* Manage all location sharing related features.
@ -62,8 +63,8 @@ interface LocationSharingService {
fun getRunningLiveLocationShareSummaries(): LiveData<List<LiveLocationShareAggregatedSummary>>
/**
* Returns a LiveData on the list of live location shares with the given eventIds.
* @param eventIds the list of event ids
* Returns a LiveData on the live location share summary with the given eventId.
* @param beaconInfoEventId event id of the initial beacon info state event
*/
fun getLiveLocationShareSummaries(eventIds: List<String>): LiveData<List<LiveLocationShareAggregatedSummary>>
fun getLiveLocationShareSummary(beaconInfoEventId: String): LiveData<Optional<LiveLocationShareAggregatedSummary>>
}

View file

@ -100,14 +100,3 @@ internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findRunningLiveI
.isNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
.isNotNull(LiveLocationShareAggregatedSummaryEntityFields.LAST_LOCATION_CONTENT)
}
internal fun LiveLocationShareAggregatedSummaryEntity.Companion.findLiveInRoom(
realm: Realm,
roomId: String,
eventIds: List<String>,
): RealmQuery<LiveLocationShareAggregatedSummaryEntity> {
return LiveLocationShareAggregatedSummaryEntity
.whereRoomId(realm, roomId = roomId)
.isNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
.`in`(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventIds.toTypedArray())
}

View file

@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.session.room.location
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import com.zhuinden.monarchy.Monarchy
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
@ -25,10 +26,12 @@ 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
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
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.query.findLiveInRoom
import org.matrix.android.sdk.internal.database.query.findRunningLiveInRoom
import org.matrix.android.sdk.internal.database.query.where
import org.matrix.android.sdk.internal.di.SessionDatabase
internal class DefaultLocationSharingService @AssistedInject constructor(
@ -90,10 +93,14 @@ internal class DefaultLocationSharingService @AssistedInject constructor(
)
}
override fun getLiveLocationShareSummaries(eventIds: List<String>): LiveData<List<LiveLocationShareAggregatedSummary>> {
return monarchy.findAllMappedWithChanges(
{ LiveLocationShareAggregatedSummaryEntity.findLiveInRoom(it, roomId = roomId, eventIds = eventIds) },
override fun getLiveLocationShareSummary(beaconInfoEventId: String): LiveData<Optional<LiveLocationShareAggregatedSummary>> {
return Transformations.map(
monarchy.findAllMappedWithChanges(
{ LiveLocationShareAggregatedSummaryEntity.where(it, roomId = roomId, eventId = beaconInfoEventId) },
liveLocationShareAggregatedSummaryMapper
)
) {
it.firstOrNull().toOptional()
}
}
}

View file

@ -16,24 +16,32 @@
package org.matrix.android.sdk.internal.session.room.location
import androidx.arch.core.util.Function
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import io.mockk.coEvery
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.slot
import io.mockk.unmockkAll
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Before
import org.junit.Test
import org.matrix.android.sdk.api.session.room.location.UpdateLiveLocationShareResult
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
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.givenIn
import org.matrix.android.sdk.test.fakes.givenIsNotEmpty
import org.matrix.android.sdk.test.fakes.givenIsNotNull
@ -47,7 +55,6 @@ private const val A_TIMEOUT = 15_000L
@ExperimentalCoroutinesApi
internal class DefaultLocationSharingServiceTest {
private val fakeRoomId = A_ROOM_ID
private val fakeMonarchy = FakeMonarchy()
private val sendStaticLocationTask = mockk<SendStaticLocationTask>()
private val sendLiveLocationTask = mockk<SendLiveLocationTask>()
@ -56,7 +63,7 @@ internal class DefaultLocationSharingServiceTest {
private val fakeLiveLocationShareAggregatedSummaryMapper = mockk<LiveLocationShareAggregatedSummaryMapper>()
private val defaultLocationSharingService = DefaultLocationSharingService(
roomId = fakeRoomId,
roomId = A_ROOM_ID,
monarchy = fakeMonarchy.instance,
sendStaticLocationTask = sendStaticLocationTask,
sendLiveLocationTask = sendLiveLocationTask,
@ -65,6 +72,11 @@ internal class DefaultLocationSharingServiceTest {
liveLocationShareAggregatedSummaryMapper = fakeLiveLocationShareAggregatedSummaryMapper
)
@Before
fun setUp() {
mockkStatic("androidx.lifecycle.Transformations")
}
@After
fun tearDown() {
unmockkAll()
@ -155,7 +167,7 @@ internal class DefaultLocationSharingServiceTest {
)
fakeMonarchy.givenWhere<LiveLocationShareAggregatedSummaryEntity>()
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, fakeRoomId)
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, A_ROOM_ID)
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.IS_ACTIVE, true)
.givenIsNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
.givenIsNotNull(LiveLocationShareAggregatedSummaryEntityFields.LAST_LOCATION_CONTENT)
@ -171,8 +183,7 @@ internal class DefaultLocationSharingServiceTest {
}
@Test
fun `given a list of event ids livedata on live summaries is correctly computed`() {
val eventIds = listOf("event_id_1", "event_id_2", "event_id_3")
fun `given an event id when getting livedata on corresponding live summary then it is correctly computed`() {
val entity = LiveLocationShareAggregatedSummaryEntity()
val summary = LiveLocationShareAggregatedSummary(
userId = "",
@ -182,17 +193,26 @@ internal class DefaultLocationSharingServiceTest {
)
fakeMonarchy.givenWhere<LiveLocationShareAggregatedSummaryEntity>()
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, fakeRoomId)
.givenIsNotEmpty(LiveLocationShareAggregatedSummaryEntityFields.USER_ID)
.givenIn(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, eventIds)
fakeMonarchy.givenFindAllMappedWithChangesReturns(
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.ROOM_ID, A_ROOM_ID)
.givenEqualTo(LiveLocationShareAggregatedSummaryEntityFields.EVENT_ID, AN_EVENT_ID)
val liveData = fakeMonarchy.givenFindAllMappedWithChangesReturns(
realmEntities = listOf(entity),
mappedResult = listOf(summary),
fakeLiveLocationShareAggregatedSummaryMapper
)
val mapper = slot<Function<List<LiveLocationShareAggregatedSummary>, Optional<LiveLocationShareAggregatedSummary>>>()
every {
Transformations.map(
liveData,
capture(mapper)
)
} answers {
val value = secondArg<Function<List<LiveLocationShareAggregatedSummary>, Optional<LiveLocationShareAggregatedSummary>>>().apply(listOf(summary))
MutableLiveData(value)
}
val result = defaultLocationSharingService.getLiveLocationShareSummaries(eventIds).value
val result = defaultLocationSharingService.getLiveLocationShareSummary(AN_EVENT_ID).value
result shouldBeEqualTo listOf(summary)
result shouldBeEqualTo summary.toOptional()
}
}

View file

@ -16,6 +16,7 @@
package org.matrix.android.sdk.test.fakes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.zhuinden.monarchy.Monarchy
import io.mockk.MockKVerificationScope
@ -60,10 +61,11 @@ internal class FakeMonarchy {
realmEntities: List<T>,
mappedResult: List<R>,
mapper: Monarchy.Mapper<R, T>
) {
): LiveData<List<R>> {
every { mapper.map(any()) } returns mockk()
val monarchyQuery = slot<Monarchy.Query<T>>()
val monarchyMapper = slot<Monarchy.Mapper<R, T>>()
val result = MutableLiveData(mappedResult)
every {
instance.findAllMappedWithChanges(capture(monarchyQuery), capture(monarchyMapper))
} answers {
@ -71,7 +73,8 @@ internal class FakeMonarchy {
realmEntities.forEach {
monarchyMapper.captured.map(it)
}
MutableLiveData(mappedResult)
}
result
}
return result
}
}

View file

@ -97,11 +97,3 @@ inline fun <reified T : RealmModel> RealmQuery<T>.givenIsNotNull(
every { isNotNull(fieldName) } returns this
return this
}
inline fun <reified T : RealmModel> RealmQuery<T>.givenIn(
fieldName: String,
values: List<String>
): RealmQuery<T> {
every { `in`(fieldName, values.toTypedArray()) } returns this
return this
}

View file

@ -19,20 +19,22 @@ package im.vector.app.features.location.live
import androidx.lifecycle.asFlow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.mapNotNull
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.getRoom
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import javax.inject.Inject
class GetLiveLocationShareSummariesUseCase @Inject constructor(
class GetLiveLocationShareSummaryUseCase @Inject constructor(
private val session: Session,
) {
fun execute(roomId: String, eventIds: List<String>): Flow<List<LiveLocationShareAggregatedSummary>> {
fun execute(roomId: String, eventId: String): Flow<LiveLocationShareAggregatedSummary> {
return session.getRoom(roomId)
?.locationSharingService()
?.getLiveLocationShareSummaries(eventIds)
?.getLiveLocationShareSummary(eventId)
?.asFlow()
?.mapNotNull { it.getOrNull() }
?: emptyFlow()
}
}

View file

@ -30,14 +30,16 @@ import org.junit.Before
import org.junit.Test
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.api.util.Optional
private const val A_ROOM_ID = "room_id"
private const val AN_EVENT_ID = "event_id"
class GetLiveLocationShareSummariesUseCaseTest {
class GetLiveLocationShareSummaryUseCaseTest {
private val fakeSession = FakeSession()
private val getLiveLocationShareSummariesUseCase = GetLiveLocationShareSummariesUseCase(
private val getLiveLocationShareSummaryUseCase = GetLiveLocationShareSummaryUseCase(
session = fakeSession
)
@ -52,35 +54,21 @@ class GetLiveLocationShareSummariesUseCaseTest {
}
@Test
fun `given a room id when calling use case then the current live is stopped with success`() = runTest {
val eventIds = listOf("event_id_1", "event_id_2", "event_id_3")
val summary1 = LiveLocationShareAggregatedSummary(
userId = "userId1",
fun `given a room id and event id when calling use case then live data on summary is returned`() = runTest {
val summary = LiveLocationShareAggregatedSummary(
userId = "userId",
isActive = true,
endOfLiveTimestampMillis = 123,
lastLocationDataContent = MessageBeaconLocationDataContent()
)
val summary2 = LiveLocationShareAggregatedSummary(
userId = "userId2",
isActive = true,
endOfLiveTimestampMillis = 1234,
lastLocationDataContent = MessageBeaconLocationDataContent()
)
val summary3 = LiveLocationShareAggregatedSummary(
userId = "userId3",
isActive = true,
endOfLiveTimestampMillis = 1234,
lastLocationDataContent = MessageBeaconLocationDataContent()
)
val summaries = listOf(summary1, summary2, summary3)
val liveData = fakeSession.roomService()
.getRoom(A_ROOM_ID)
.locationSharingService()
.givenLiveLocationShareSummaries(eventIds, summaries)
every { liveData.asFlow() } returns flowOf(summaries)
.givenLiveLocationShareSummaryReturns(AN_EVENT_ID, summary)
every { liveData.asFlow() } returns flowOf(Optional(summary))
val result = getLiveLocationShareSummariesUseCase.execute(A_ROOM_ID, eventIds).first()
val result = getLiveLocationShareSummaryUseCase.execute(A_ROOM_ID, AN_EVENT_ID).first()
result shouldBeEqualTo listOf(summary1, summary2, summary3)
result shouldBeEqualTo summary
}
}

View file

@ -17,7 +17,6 @@
package im.vector.app.features.location.live.map
import androidx.lifecycle.asFlow
import com.airbnb.mvrx.test.MvRxTestRule
import im.vector.app.features.location.LocationData
import im.vector.app.test.fakes.FakeSession
import io.mockk.coEvery
@ -25,15 +24,12 @@ import io.mockk.every
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.unmockkAll
import io.mockk.unmockkStatic
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.internal.assertEquals
import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationShareAggregatedSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageBeaconLocationDataContent
@ -85,7 +81,7 @@ class GetListOfUserLiveLocationUseCaseTest {
val liveData = fakeSession.roomService()
.getRoom(A_ROOM_ID)
.locationSharingService()
.givenRunningLiveLocationShareSummaries(summaries)
.givenRunningLiveLocationShareSummariesReturns(summaries)
every { liveData.asFlow() } returns flowOf(summaries)

View file

@ -24,10 +24,11 @@ import io.mockk.mockk
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
import org.matrix.android.sdk.api.util.Optional
class FakeLocationSharingService : LocationSharingService by mockk() {
fun givenRunningLiveLocationShareSummaries(
fun givenRunningLiveLocationShareSummariesReturns(
summaries: List<LiveLocationShareAggregatedSummary>
): LiveData<List<LiveLocationShareAggregatedSummary>> {
return MutableLiveData(summaries).also {
@ -35,12 +36,12 @@ class FakeLocationSharingService : LocationSharingService by mockk() {
}
}
fun givenLiveLocationShareSummaries(
eventIds: List<String>,
summaries: List<LiveLocationShareAggregatedSummary>
): LiveData<List<LiveLocationShareAggregatedSummary>> {
return MutableLiveData(summaries).also {
every { getLiveLocationShareSummaries(eventIds) } returns it
fun givenLiveLocationShareSummaryReturns(
eventId: String,
summary: LiveLocationShareAggregatedSummary
): LiveData<Optional<LiveLocationShareAggregatedSummary>> {
return MutableLiveData(Optional(summary)).also {
every { getLiveLocationShareSummary(eventId) } returns it
}
}