Fixing unit tests in SDK
This commit is contained in:
parent
c7d3e1926f
commit
030e37655e
|
@ -58,7 +58,6 @@ internal class DefaultFilterAndStoreEventsTask @Inject constructor(
|
||||||
|
|
||||||
private suspend fun addMissingEventsInDB(roomId: String, events: List<Event>) {
|
private suspend fun addMissingEventsInDB(roomId: String, events: List<Event>) {
|
||||||
monarchy.awaitTransaction { realm ->
|
monarchy.awaitTransaction { realm ->
|
||||||
// TODO we should insert TimelineEventEntity as well, how to do that????
|
|
||||||
val eventIdsToCheck = events.mapNotNull { it.eventId }.filter { it.isNotEmpty() }
|
val eventIdsToCheck = events.mapNotNull { it.eventId }.filter { it.isNotEmpty() }
|
||||||
if (eventIdsToCheck.isNotEmpty()) {
|
if (eventIdsToCheck.isNotEmpty()) {
|
||||||
val existingIds = EventEntity.where(realm, eventIdsToCheck).findAll().toList().map { it.eventId }
|
val existingIds = EventEntity.where(realm, eventIdsToCheck).findAll().toList().map { it.eventId }
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023 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.event
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkStatic
|
||||||
|
import io.mockk.unmockkAll
|
||||||
|
import io.mockk.verify
|
||||||
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
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.api.session.events.model.RelationType
|
||||||
|
import org.matrix.android.sdk.api.session.events.model.isPollResponse
|
||||||
|
import org.matrix.android.sdk.api.session.room.send.SendState
|
||||||
|
import org.matrix.android.sdk.internal.database.mapper.toEntity
|
||||||
|
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.query.copyToRealmOrIgnore
|
||||||
|
import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse
|
||||||
|
import org.matrix.android.sdk.internal.session.room.relation.poll.FETCH_RELATED_EVENTS_LIMIT
|
||||||
|
import org.matrix.android.sdk.internal.session.room.relation.poll.FetchPollResponseEventsTask
|
||||||
|
import org.matrix.android.sdk.test.fakes.FakeClock
|
||||||
|
import org.matrix.android.sdk.test.fakes.FakeEventDecryptor
|
||||||
|
import org.matrix.android.sdk.test.fakes.FakeMonarchy
|
||||||
|
import org.matrix.android.sdk.test.fakes.givenFindAll
|
||||||
|
import org.matrix.android.sdk.test.fakes.givenIn
|
||||||
|
|
||||||
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
|
internal class DefaultFilterAndStoreEventsTaskTest {
|
||||||
|
|
||||||
|
private val fakeMonarchy = FakeMonarchy()
|
||||||
|
private val fakeClock = FakeClock()
|
||||||
|
private val fakeEventDecryptor = FakeEventDecryptor()
|
||||||
|
|
||||||
|
private val defaultFilterAndStoreEventsTask = DefaultFilterAndStoreEventsTask(
|
||||||
|
monarchy = fakeMonarchy.instance,
|
||||||
|
clock = fakeClock,
|
||||||
|
eventDecryptor = fakeEventDecryptor.instance,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
mockkStatic("org.matrix.android.sdk.api.session.events.model.EventKt")
|
||||||
|
mockkStatic("org.matrix.android.sdk.internal.database.mapper.EventMapperKt")
|
||||||
|
mockkStatic("org.matrix.android.sdk.internal.database.query.EventEntityQueriesKt")
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
unmockkAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `given a room and list of events when execute then filter in using given predicate and store them in local if needed`() = runTest {
|
||||||
|
// Given
|
||||||
|
val aRoomId = "roomId"
|
||||||
|
val anEventId1 = "eventId1"
|
||||||
|
val anEventId2 = "eventId2"
|
||||||
|
val anEventId3 = "eventId3"
|
||||||
|
val anEventId4 = "eventId4"
|
||||||
|
val event1 = givenAnEvent(eventId = anEventId1, isEncrypted = true, clearType = EventType.ENCRYPTED)
|
||||||
|
val event2 = givenAnEvent(eventId = anEventId2, isEncrypted = true, clearType = EventType.MESSAGE)
|
||||||
|
val event3 = givenAnEvent(eventId = anEventId3, isEncrypted = false, clearType = EventType.MESSAGE)
|
||||||
|
val event4 = givenAnEvent(eventId = anEventId4, isEncrypted = false, clearType = EventType.MESSAGE)
|
||||||
|
val events = listOf(event1, event2, event3, event4)
|
||||||
|
val filterPredicate = { event: Event -> event == event2 }
|
||||||
|
val params = givenTaskParams(roomId = aRoomId, events = events, predicate = filterPredicate)
|
||||||
|
fakeEventDecryptor.givenDecryptEventAndSaveResultSuccess(event1)
|
||||||
|
fakeEventDecryptor.givenDecryptEventAndSaveResultSuccess(event2)
|
||||||
|
fakeClock.givenEpoch(123)
|
||||||
|
givenExistingEventEntities(eventIdsToCheck = listOf(anEventId1, anEventId2), existingIds = listOf(anEventId1))
|
||||||
|
val eventEntityToSave = EventEntity(eventId = anEventId2)
|
||||||
|
every { event2.toEntity(any(), any(), any()) } returns eventEntityToSave
|
||||||
|
every { eventEntityToSave.copyToRealmOrIgnore(any(), any()) } returns eventEntityToSave
|
||||||
|
|
||||||
|
// When
|
||||||
|
defaultFilterAndStoreEventsTask.execute(params)
|
||||||
|
|
||||||
|
// Then
|
||||||
|
fakeEventDecryptor.verifyDecryptEventAndSaveResult(event1, timeline = "")
|
||||||
|
fakeEventDecryptor.verifyDecryptEventAndSaveResult(event2, timeline = "")
|
||||||
|
// Check we save in DB the event2 which is a non stored poll response
|
||||||
|
verify {
|
||||||
|
event2.toEntity(aRoomId, SendState.SYNCED, any())
|
||||||
|
eventEntityToSave.copyToRealmOrIgnore(fakeMonarchy.fakeRealm.instance, EventInsertType.PAGINATION)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenTaskParams(roomId: String, events: List<Event>, predicate: (Event) -> Boolean) = FilterAndStoreEventsTask.Params(
|
||||||
|
roomId = roomId,
|
||||||
|
events = events,
|
||||||
|
filterPredicate = predicate,
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun givenAnEvent(
|
||||||
|
eventId: String,
|
||||||
|
isEncrypted: Boolean,
|
||||||
|
clearType: String,
|
||||||
|
): Event {
|
||||||
|
val event = mockk<Event>(relaxed = true)
|
||||||
|
every { event.eventId } returns eventId
|
||||||
|
every { event.isEncrypted() } returns isEncrypted
|
||||||
|
every { event.getClearType() } returns clearType
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun givenExistingEventEntities(eventIdsToCheck: List<String>, existingIds: List<String>) {
|
||||||
|
val eventEntities = existingIds.map { EventEntity(eventId = it) }
|
||||||
|
fakeMonarchy.givenWhere<EventEntity>()
|
||||||
|
.givenIn(EventEntityFields.EVENT_ID, eventIdsToCheck)
|
||||||
|
.givenFindAll(eventEntities)
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,11 +16,12 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.session.room.relation.poll
|
package org.matrix.android.sdk.internal.session.room.relation.poll
|
||||||
|
|
||||||
|
import io.mockk.coJustRun
|
||||||
|
import io.mockk.coVerify
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
import io.mockk.mockk
|
import io.mockk.mockk
|
||||||
import io.mockk.mockkStatic
|
import io.mockk.mockkStatic
|
||||||
import io.mockk.unmockkAll
|
import io.mockk.unmockkAll
|
||||||
import io.mockk.verify
|
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
|
@ -29,41 +30,28 @@ import org.junit.Test
|
||||||
import org.matrix.android.sdk.api.session.events.model.Event
|
import org.matrix.android.sdk.api.session.events.model.Event
|
||||||
import org.matrix.android.sdk.api.session.events.model.RelationType
|
import org.matrix.android.sdk.api.session.events.model.RelationType
|
||||||
import org.matrix.android.sdk.api.session.events.model.isPollResponse
|
import org.matrix.android.sdk.api.session.events.model.isPollResponse
|
||||||
import org.matrix.android.sdk.api.session.room.send.SendState
|
import org.matrix.android.sdk.internal.session.room.event.FilterAndStoreEventsTask
|
||||||
import org.matrix.android.sdk.internal.database.mapper.toEntity
|
|
||||||
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.query.copyToRealmOrIgnore
|
|
||||||
import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse
|
import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse
|
||||||
import org.matrix.android.sdk.test.fakes.FakeClock
|
|
||||||
import org.matrix.android.sdk.test.fakes.FakeEventDecryptor
|
|
||||||
import org.matrix.android.sdk.test.fakes.FakeGlobalErrorReceiver
|
import org.matrix.android.sdk.test.fakes.FakeGlobalErrorReceiver
|
||||||
import org.matrix.android.sdk.test.fakes.FakeMonarchy
|
|
||||||
import org.matrix.android.sdk.test.fakes.FakeRoomApi
|
import org.matrix.android.sdk.test.fakes.FakeRoomApi
|
||||||
import org.matrix.android.sdk.test.fakes.givenFindAll
|
|
||||||
import org.matrix.android.sdk.test.fakes.givenIn
|
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
internal class DefaultFetchPollResponseEventsTaskTest {
|
internal class DefaultFetchPollResponseEventsTaskTest {
|
||||||
|
|
||||||
private val fakeRoomAPI = FakeRoomApi()
|
private val fakeRoomAPI = FakeRoomApi()
|
||||||
private val fakeGlobalErrorReceiver = FakeGlobalErrorReceiver()
|
private val fakeGlobalErrorReceiver = FakeGlobalErrorReceiver()
|
||||||
private val fakeMonarchy = FakeMonarchy()
|
private val filterAndStoreEventsTask = mockk<FilterAndStoreEventsTask>()
|
||||||
private val fakeClock = FakeClock()
|
|
||||||
private val fakeEventDecryptor = FakeEventDecryptor()
|
|
||||||
|
|
||||||
private val defaultFetchPollResponseEventsTask = DefaultFetchPollResponseEventsTask(
|
private val defaultFetchPollResponseEventsTask = DefaultFetchPollResponseEventsTask(
|
||||||
roomAPI = fakeRoomAPI.instance,
|
roomAPI = fakeRoomAPI.instance,
|
||||||
globalErrorReceiver = fakeGlobalErrorReceiver,
|
globalErrorReceiver = fakeGlobalErrorReceiver,
|
||||||
monarchy = fakeMonarchy.instance,
|
filterAndStoreEventsTask = filterAndStoreEventsTask,
|
||||||
clock = fakeClock,
|
|
||||||
eventDecryptor = fakeEventDecryptor.instance,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
mockkStatic("org.matrix.android.sdk.api.session.events.model.EventKt")
|
mockkStatic("org.matrix.android.sdk.api.session.events.model.EventKt")
|
||||||
|
|
||||||
mockkStatic("org.matrix.android.sdk.internal.database.mapper.EventMapperKt")
|
mockkStatic("org.matrix.android.sdk.internal.database.mapper.EventMapperKt")
|
||||||
mockkStatic("org.matrix.android.sdk.internal.database.query.EventEntityQueriesKt")
|
mockkStatic("org.matrix.android.sdk.internal.database.query.EventEntityQueriesKt")
|
||||||
}
|
}
|
||||||
|
@ -74,7 +62,7 @@ internal class DefaultFetchPollResponseEventsTaskTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `given a room and a poll when execute then fetch related events and store them in local if needed`() = runTest {
|
fun `given a room and a poll when execute then fetch related events and store them in local`() = runTest {
|
||||||
// Given
|
// Given
|
||||||
val aRoomId = "roomId"
|
val aRoomId = "roomId"
|
||||||
val aPollEventId = "eventId"
|
val aPollEventId = "eventId"
|
||||||
|
@ -94,13 +82,7 @@ internal class DefaultFetchPollResponseEventsTaskTest {
|
||||||
fakeRoomAPI.givenGetRelationsReturns(from = null, relationsResponse = firstResponse)
|
fakeRoomAPI.givenGetRelationsReturns(from = null, relationsResponse = firstResponse)
|
||||||
val secondResponse = givenARelationsResponse(events = secondEvents, nextBatch = null)
|
val secondResponse = givenARelationsResponse(events = secondEvents, nextBatch = null)
|
||||||
fakeRoomAPI.givenGetRelationsReturns(from = aNextBatchToken, relationsResponse = secondResponse)
|
fakeRoomAPI.givenGetRelationsReturns(from = aNextBatchToken, relationsResponse = secondResponse)
|
||||||
fakeEventDecryptor.givenDecryptEventAndSaveResultSuccess(event1)
|
coJustRun { filterAndStoreEventsTask.execute(any()) }
|
||||||
fakeEventDecryptor.givenDecryptEventAndSaveResultSuccess(event2)
|
|
||||||
fakeClock.givenEpoch(123)
|
|
||||||
givenExistingEventEntities(eventIdsToCheck = listOf(anEventId1, anEventId2), existingIds = listOf(anEventId1))
|
|
||||||
val eventEntityToSave = EventEntity(eventId = anEventId2)
|
|
||||||
every { event2.toEntity(any(), any(), any()) } returns eventEntityToSave
|
|
||||||
every { eventEntityToSave.copyToRealmOrIgnore(any(), any()) } returns eventEntityToSave
|
|
||||||
|
|
||||||
// When
|
// When
|
||||||
defaultFetchPollResponseEventsTask.execute(params)
|
defaultFetchPollResponseEventsTask.execute(params)
|
||||||
|
@ -111,21 +93,22 @@ internal class DefaultFetchPollResponseEventsTaskTest {
|
||||||
eventId = params.startPollEventId,
|
eventId = params.startPollEventId,
|
||||||
relationType = RelationType.REFERENCE,
|
relationType = RelationType.REFERENCE,
|
||||||
from = null,
|
from = null,
|
||||||
limit = FETCH_RELATED_EVENTS_LIMIT
|
limit = FETCH_RELATED_EVENTS_LIMIT,
|
||||||
)
|
)
|
||||||
fakeRoomAPI.verifyGetRelations(
|
fakeRoomAPI.verifyGetRelations(
|
||||||
roomId = params.roomId,
|
roomId = params.roomId,
|
||||||
eventId = params.startPollEventId,
|
eventId = params.startPollEventId,
|
||||||
relationType = RelationType.REFERENCE,
|
relationType = RelationType.REFERENCE,
|
||||||
from = aNextBatchToken,
|
from = aNextBatchToken,
|
||||||
limit = FETCH_RELATED_EVENTS_LIMIT
|
limit = FETCH_RELATED_EVENTS_LIMIT,
|
||||||
)
|
)
|
||||||
fakeEventDecryptor.verifyDecryptEventAndSaveResult(event1, timeline = "")
|
coVerify {
|
||||||
fakeEventDecryptor.verifyDecryptEventAndSaveResult(event2, timeline = "")
|
filterAndStoreEventsTask.execute(match {
|
||||||
// Check we save in DB the event2 which is a non stored poll response
|
it.roomId == aRoomId && it.events == firstEvents
|
||||||
verify {
|
})
|
||||||
event2.toEntity(aRoomId, SendState.SYNCED, any())
|
filterAndStoreEventsTask.execute(match {
|
||||||
eventEntityToSave.copyToRealmOrIgnore(fakeMonarchy.fakeRealm.instance, EventInsertType.PAGINATION)
|
it.roomId == aRoomId && it.events == secondEvents
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,11 +136,4 @@ internal class DefaultFetchPollResponseEventsTaskTest {
|
||||||
every { event.isEncrypted() } returns isEncrypted
|
every { event.isEncrypted() } returns isEncrypted
|
||||||
return event
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun givenExistingEventEntities(eventIdsToCheck: List<String>, existingIds: List<String>) {
|
|
||||||
val eventEntities = existingIds.map { EventEntity(eventId = it) }
|
|
||||||
fakeMonarchy.givenWhere<EventEntity>()
|
|
||||||
.givenIn(EventEntityFields.EVENT_ID, eventIdsToCheck)
|
|
||||||
.givenFindAll(eventEntities)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue