Timeline: add some fakes and fixtures

This commit is contained in:
ganfra 2022-07-13 17:28:27 +02:00
parent a800a837cc
commit 202504fea9
9 changed files with 310 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright (c) 2022 New Vector Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.session.room.timeline package org.matrix.android.sdk.internal.session.room.timeline
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.zhuinden.monarchy.Monarchy import com.zhuinden.monarchy.Monarchy
@ -32,9 +32,8 @@ import org.matrix.android.sdk.internal.database.helper.addTimelineEvent
import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.mapper.toEntity
import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.ChunkEntity
import org.matrix.android.sdk.internal.database.model.SessionRealmModule import org.matrix.android.sdk.internal.database.model.SessionRealmModule
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
import org.matrix.android.sdk.internal.util.time.DefaultClock import org.matrix.android.sdk.internal.util.time.DefaultClock
import org.matrix.android.sdk.session.room.timeline.RoomDataHelper.createFakeMessageEvent import org.matrix.android.sdk.internal.session.room.timeline.RoomDataHelper.createFakeMessageEvent
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
internal class ChunkEntityTest : InstrumentedTest { internal class ChunkEntityTest : InstrumentedTest {

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright (c) 2022 New Vector Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.session.room.timeline package org.matrix.android.sdk.internal.session.room.timeline
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.Event

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* 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.timeline
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.zhuinden.monarchy.Monarchy
import io.realm.Realm
import io.realm.RealmConfiguration
import io.realm.kotlin.executeTransactionAwait
import kotlinx.coroutines.runBlocking
import org.amshove.kluent.shouldBe
import org.amshove.kluent.shouldBeEqualTo
import org.amshove.kluent.shouldNotBe
import org.junit.After
import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.internal.database.model.ChunkEntity
import org.matrix.android.sdk.internal.database.model.ChunkEntityFields
import org.matrix.android.sdk.internal.database.model.SessionRealmModule
import org.matrix.android.sdk.internal.session.room.timeline.fakes.FakeLightweightSettingsStorage
import org.matrix.android.sdk.internal.session.room.timeline.fakes.FakeStreamEventsManager
import org.matrix.android.sdk.internal.session.room.timeline.fakes.FakeTokenChunkEvent
import org.matrix.android.sdk.internal.session.room.timeline.fixtures.aListOfTextMessageEvents
import org.matrix.android.sdk.internal.util.time.DefaultClock
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.JVM)
class TokenChunkEventPersistorTest : InstrumentedTest {
private lateinit var monarchy: Monarchy
private lateinit var realm: Realm
private val clock = DefaultClock()
private val userId = "@userId:server.com"
private val lightweightSettingsStorage = FakeLightweightSettingsStorage()
private val streamEventsManager = FakeStreamEventsManager().apply {
givenDispatchPaginatedEventReceived()
}
@Before
fun setup() {
Realm.init(context())
val testConfig = RealmConfiguration.Builder()
.inMemory()
.name("TokenChunkEventPersistorTest")
.modules(SessionRealmModule())
.build()
monarchy = Monarchy.Builder().setRealmConfiguration(testConfig).build()
realm = Realm.getInstance(monarchy.realmConfiguration)
}
@After
fun tearDown() {
realm.close()
}
@Test
fun given_new_chunk_events_should_all_be_added_and_unique() = runBlocking {
val roomId = "room-id"
val tokenChunkEventPersistor =
TokenChunkEventPersistor(monarchy, userId, lightweightSettingsStorage, liveEventManager = { streamEventsManager.instance }, clock)
val fakeTokenChunkEvent = FakeTokenChunkEvent(
start = "start",
end = "end",
events = aListOfTextMessageEvents(10, roomId = roomId)
)
val result = tokenChunkEventPersistor.insertInDb(fakeTokenChunkEvent, roomId, direction = PaginationDirection.BACKWARDS)
result shouldBeEqualTo TokenChunkEventPersistor.Result.SUCCESS
realm.refresh()
val chunkEntity = realm.where(ChunkEntity::class.java)
.equalTo(ChunkEntityFields.NEXT_TOKEN, "start")
.equalTo(ChunkEntityFields.PREV_TOKEN, "end")
.findFirst()!!
chunkEntity.nextChunk shouldBe null
chunkEntity.prevChunk shouldBe null
chunkEntity.timelineEvents.size shouldBeEqualTo 10
Unit
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright (c) 2022 New Vector Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,10 +14,11 @@
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.session.room.timeline package org.matrix.android.sdk.internal.session.room.timeline.fakes
import org.matrix.android.sdk.internal.session.room.timeline.GetContextOfEventTask import org.matrix.android.sdk.internal.session.room.timeline.GetContextOfEventTask
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
import org.matrix.android.sdk.internal.session.room.timeline.RoomDataHelper
import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEventPersistor import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEventPersistor
import kotlin.random.Random import kotlin.random.Random
@ -30,6 +31,10 @@ internal class FakeGetContextOfEventTask constructor(private val tokenChunkEvent
Random.nextLong().toString(), Random.nextLong().toString(),
fakeEvents fakeEvents
) )
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, PaginationDirection.BACKWARDS) return tokenChunkEventPersistor.insertInDb(
receivedChunk = tokenChunkEvent,
roomId = params.roomId,
direction = PaginationDirection.BACKWARDS
)
} }
} }

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* 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.timeline.fakes
import org.matrix.android.sdk.api.settings.LightweightSettingsStorage
internal class FakeLightweightSettingsStorage : LightweightSettingsStorage {
private var threadMessageEnabled = false
override fun setThreadMessagesEnabled(enabled: Boolean) {
threadMessageEnabled = enabled
}
override fun areThreadMessagesEnabled(): Boolean {
return threadMessageEnabled
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright (c) 2022 New Vector Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -14,9 +14,10 @@
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.session.room.timeline package org.matrix.android.sdk.internal.session.room.timeline.fakes
import org.matrix.android.sdk.internal.session.room.timeline.PaginationTask import org.matrix.android.sdk.internal.session.room.timeline.PaginationTask
import org.matrix.android.sdk.internal.session.room.timeline.RoomDataHelper
import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEventPersistor import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEventPersistor
import javax.inject.Inject import javax.inject.Inject
import kotlin.random.Random import kotlin.random.Random
@ -26,6 +27,10 @@ internal class FakePaginationTask @Inject constructor(private val tokenChunkEven
override suspend fun execute(params: PaginationTask.Params): TokenChunkEventPersistor.Result { override suspend fun execute(params: PaginationTask.Params): TokenChunkEventPersistor.Result {
val fakeEvents = RoomDataHelper.createFakeListOfEvents(30) val fakeEvents = RoomDataHelper.createFakeListOfEvents(30)
val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong().toString(), fakeEvents) val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong().toString(), fakeEvents)
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, params.direction) return tokenChunkEventPersistor.insertInDb(
receivedChunk = tokenChunkEvent,
roomId = params.roomId,
direction = params.direction
)
} }
} }

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* 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.timeline.fakes
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.runs
import org.matrix.android.sdk.internal.session.StreamEventsManager
internal class FakeStreamEventsManager {
val instance = mockk<StreamEventsManager>()
fun givenDispatchPaginatedEventReceived() {
every { instance.dispatchPaginatedEventReceived(any(), any()) } just runs
}
}

View File

@ -1,11 +1,11 @@
/* /*
* Copyright 2020 The Matrix.org Foundation C.I.C. * Copyright (c) 2022 New Vector Ltd
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package org.matrix.android.sdk.session.room.timeline package org.matrix.android.sdk.internal.session.room.timeline.fakes
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.internal.session.room.timeline.TokenChunkEvent import org.matrix.android.sdk.internal.session.room.timeline.TokenChunkEvent

View File

@ -0,0 +1,125 @@
/*
* Copyright (c) 2022 New Vector Ltd
*
* 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.timeline.fixtures
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.toContent
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.session.room.model.RoomNameContent
import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
import org.matrix.android.sdk.api.session.room.model.message.MessageType
internal fun aTextMessageEvent(
roomId: String = "room-id",
eventId: String = "event-id",
senderId: String = "sender-id",
body: String = "body"
): Event = Event(
type = EventType.MESSAGE,
eventId = eventId,
content = MessageTextContent(
msgType = MessageType.MSGTYPE_TEXT,
body = body
).toContent(),
prevContent = null,
originServerTs = 0,
senderId = senderId,
stateKey = null,
roomId = roomId,
unsignedData = null,
redacts = null
)
internal fun aRoomCreateEvent(
roomId: String = "room-id",
eventId: String = "event-id",
senderId: String = "sender-id",
): Event = Event(
type = EventType.STATE_ROOM_CREATE,
eventId = eventId,
content = RoomCreateContent(
creator = senderId
).toContent(),
prevContent = null,
originServerTs = 0,
senderId = senderId,
stateKey = "",
roomId = roomId,
unsignedData = null,
redacts = null
)
internal fun aRoomMemberEvent(
roomId: String = "room-id",
eventId: String = "event-id",
senderId: String = "sender-id",
membership: Membership = Membership.JOIN,
displayName: String = "Alice",
): Event = Event(
type = EventType.STATE_ROOM_MEMBER,
eventId = eventId,
content = RoomMemberContent(
membership = membership,
displayName = displayName
).toContent(),
prevContent = null,
originServerTs = 0,
senderId = senderId,
stateKey = senderId,
roomId = roomId,
unsignedData = null,
redacts = null
)
internal fun aRoomNameEvent(
roomId: String = "room-id",
eventId: String = "event-id",
senderId: String = "sender-id",
roomName: String = "Alice and Bob Room"
): Event = Event(
type = EventType.STATE_ROOM_NAME,
eventId = eventId,
content = RoomNameContent(
name = roomName
).toContent(),
prevContent = null,
originServerTs = 0,
senderId = senderId,
stateKey = "",
roomId = roomId,
unsignedData = null,
redacts = null
)
internal fun aListOfTextMessageEvents(
size: Int = 10,
roomId: String = "room-id",
eventIdPrefix: String = "event-id",
senderId: String = "sender-id",
bodyPrefix: String = "body"
) = (0 until size).map {
aTextMessageEvent(
roomId = roomId,
eventId = "{$eventIdPrefix}_{$it}",
senderId = senderId,
body = "{$bodyPrefix}_{$it}",
)
}