mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
Tests: fix timeline tests + some small others
This commit is contained in:
parent
1d9da6c7d3
commit
ccdeeeab4c
@ -20,6 +20,7 @@ import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.test.internal.runner.junit4.statement.UiThreadStatement
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
@ -45,6 +46,7 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
|
||||
import org.matrix.android.sdk.api.session.sync.SyncState
|
||||
import timber.log.Timber
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
@ -119,22 +121,21 @@ class CommonTestHelper(context: Context) {
|
||||
* @param session the session to sync
|
||||
*/
|
||||
fun clearCacheAndSync(session: Session, timeout: Long = TestConstants.timeOutMillis) {
|
||||
val lock = CountDownLatch(1)
|
||||
coroutineScope.launch {
|
||||
waitWithLatch(timeout) { latch ->
|
||||
session.clearCache()
|
||||
val syncLiveData = session.getSyncStateLive()
|
||||
val syncObserver = object : Observer<SyncState> {
|
||||
override fun onChanged(t: SyncState?) {
|
||||
if (session.hasAlreadySynced()) {
|
||||
lock.countDown()
|
||||
Timber.v("Clear cache and synced")
|
||||
syncLiveData.removeObserver(this)
|
||||
latch.countDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
syncLiveData.observeForever(syncObserver)
|
||||
session.startSync(true)
|
||||
}
|
||||
await(lock, timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,9 +146,10 @@ class CommonTestHelper(context: Context) {
|
||||
* @param nbOfMessages the number of time the message will be sent
|
||||
*/
|
||||
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
|
||||
val timeline = room.createTimeline(null, TimelineSettings(10))
|
||||
val sentEvents = ArrayList<TimelineEvent>(nbOfMessages)
|
||||
waitWithLatch(timeout ) { latch ->
|
||||
val timeline = room.createTimeline(null, TimelineSettings(10))
|
||||
timeline.start()
|
||||
waitWithLatch(timeout + 1_000L * nbOfMessages) { latch ->
|
||||
val timelineListener = object : Timeline.Listener {
|
||||
override fun onTimelineFailure(throwable: Throwable) {
|
||||
}
|
||||
@ -162,6 +164,7 @@ class CommonTestHelper(context: Context) {
|
||||
.filter { it.root.getClearType() == EventType.MESSAGE }
|
||||
.filter { it.root.getClearContent().toModel<MessageContent>()?.body?.startsWith(message) == true }
|
||||
|
||||
Timber.v("New synced message size: ${newMessages.size}")
|
||||
if (newMessages.size == nbOfMessages) {
|
||||
sentEvents.addAll(newMessages)
|
||||
// Remove listener now, if not at the next update sendEvents could change
|
||||
@ -170,13 +173,8 @@ class CommonTestHelper(context: Context) {
|
||||
}
|
||||
}
|
||||
}
|
||||
timeline.start()
|
||||
timeline.addListener(timelineListener)
|
||||
for (i in 0 until nbOfMessages) {
|
||||
room.sendTextMessage(message + " #" + (i + 1))
|
||||
// Sleep a bit otherwise database will be flowed and sync won't be live (we might end up with gap then...)
|
||||
delay(50)
|
||||
}
|
||||
sendTextMessagesBatched(room, message, nbOfMessages)
|
||||
}
|
||||
timeline.dispose()
|
||||
// Check that all events has been created
|
||||
@ -184,6 +182,21 @@ class CommonTestHelper(context: Context) {
|
||||
return sentEvents
|
||||
}
|
||||
|
||||
/**
|
||||
* Will send nb of messages provided by count parameter but waits a bit every 10 messages to avoid gap in sync
|
||||
*/
|
||||
private fun sendTextMessagesBatched(room: Room, message: String, count: Int) {
|
||||
(1 until count + 1)
|
||||
.map { "$message #$it" }
|
||||
.chunked(10)
|
||||
.forEach { batchedMessages ->
|
||||
batchedMessages.forEach { formattedMessage ->
|
||||
room.sendTextMessage(formattedMessage)
|
||||
}
|
||||
Thread.sleep(1_000L)
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE METHODS *****************************************************************************
|
||||
|
||||
/**
|
||||
@ -357,9 +370,9 @@ class CommonTestHelper(context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
fun waitWithLatch(timeout: Long? = TestConstants.timeOutMillis, block: suspend (CountDownLatch) -> Unit) {
|
||||
fun waitWithLatch(timeout: Long? = TestConstants.timeOutMillis, dispatcher: CoroutineDispatcher = Dispatchers.Main, block: suspend (CountDownLatch) -> Unit) {
|
||||
val latch = CountDownLatch(1)
|
||||
coroutineScope.launch {
|
||||
coroutineScope.launch(dispatcher) {
|
||||
block(latch)
|
||||
}
|
||||
await(latch, timeout)
|
||||
|
@ -32,6 +32,7 @@ import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent
|
||||
import org.matrix.android.sdk.api.session.securestorage.KeySigner
|
||||
import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec
|
||||
import org.matrix.android.sdk.api.session.securestorage.SecretStorageKeyContent
|
||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError
|
||||
import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService
|
||||
import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
@ -90,7 +91,7 @@ class QuadSTests : InstrumentedTest {
|
||||
testHelper.waitWithLatch { latch ->
|
||||
quadS.setDefaultKey(TEST_KEY_ID)
|
||||
val liveDefAccountData =
|
||||
aliceSession.accountDataService().getLiveUserAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
aliceSession.accountDataService().getLiveUserAccountDataEvent(DefaultSharedSecretStorageService.DEFAULT_KEY_ID)
|
||||
val accountDefDataObserver = Observer<Optional<UserAccountDataEvent>?> { t ->
|
||||
if (t?.getOrNull()?.type == DefaultSharedSecretStorageService.DEFAULT_KEY_ID) {
|
||||
defaultKeyAccountData = t.getOrNull()!!
|
||||
@ -233,14 +234,18 @@ class QuadSTests : InstrumentedTest {
|
||||
}
|
||||
|
||||
testHelper.runBlockingTest {
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
RawBytesKeySpec.fromPassphrase(
|
||||
"A bad passphrase",
|
||||
key1Info.content?.passphrase?.salt ?: "",
|
||||
key1Info.content?.passphrase?.iterations ?: 0,
|
||||
null)
|
||||
)
|
||||
try {
|
||||
aliceSession.sharedSecretStorageService.getSecret("my.secret",
|
||||
keyId1,
|
||||
RawBytesKeySpec.fromPassphrase(
|
||||
"A bad passphrase",
|
||||
key1Info.content?.passphrase?.salt ?: "",
|
||||
key1Info.content?.passphrase?.iterations ?: 0,
|
||||
null)
|
||||
)
|
||||
} catch (throwable: Throwable) {
|
||||
assert(throwable is SharedSecretStorageError.BadMac)
|
||||
}
|
||||
}
|
||||
|
||||
// Now try with correct key
|
||||
|
@ -84,24 +84,12 @@ class SearchMessagesTest : InstrumentedTest {
|
||||
val aliceSession = cryptoTestData.firstSession
|
||||
val aliceRoomId = cryptoTestData.roomId
|
||||
val roomFromAlicePOV = aliceSession.getRoom(aliceRoomId)!!
|
||||
val aliceTimeline = roomFromAlicePOV.createTimeline(null, TimelineSettings(10))
|
||||
aliceTimeline.start()
|
||||
|
||||
val lock = CountDownLatch(1)
|
||||
|
||||
val eventListener = commonTestHelper.createEventListener(lock) { snapshot ->
|
||||
snapshot.count { it.root.content.toModel<MessageContent>()?.body?.startsWith(MESSAGE).orFalse() } == 2
|
||||
}
|
||||
|
||||
aliceTimeline.addListener(eventListener)
|
||||
|
||||
commonTestHelper.sendTextMessage(
|
||||
roomFromAlicePOV,
|
||||
MESSAGE,
|
||||
2)
|
||||
|
||||
commonTestHelper.await(lock)
|
||||
|
||||
val data = commonTestHelper.runBlockingTest {
|
||||
block.invoke(cryptoTestData)
|
||||
}
|
||||
@ -114,7 +102,6 @@ class SearchMessagesTest : InstrumentedTest {
|
||||
}.orFalse()
|
||||
)
|
||||
|
||||
aliceTimeline.removeAllListeners()
|
||||
cryptoTestData.cleanUp(commonTestHelper)
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
val session = commonTestHelper.createAccount("John", SessionTestParams(true))
|
||||
val spaceName = "My Space"
|
||||
val topic = "A public space for test"
|
||||
var spaceId: String = ""
|
||||
var spaceId = ""
|
||||
commonTestHelper.waitWithLatch {
|
||||
spaceId = session.spaceService().createSpace(spaceName, topic, null, true)
|
||||
it.countDown()
|
||||
@ -67,7 +67,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
|
||||
val syncedSpace = session.spaceService().getSpace(spaceId)
|
||||
|
||||
var roomId: String = ""
|
||||
var roomId = ""
|
||||
commonTestHelper.waitWithLatch {
|
||||
roomId = session.createRoom(CreateRoomParams().apply { name = "General" })
|
||||
it.countDown()
|
||||
@ -314,6 +314,11 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
session.spaceService().setSpaceParent(spaceBInfo.spaceId, spaceAInfo.spaceId, true, viaServers)
|
||||
}
|
||||
|
||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||
Triple("C2", true, true)
|
||||
))
|
||||
|
||||
commonTestHelper.waitWithLatch { latch ->
|
||||
|
||||
val flatAChildren = session.getFlattenRoomSummaryChildrenOfLive(spaceAInfo.spaceId)
|
||||
@ -329,11 +334,6 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
}
|
||||
}
|
||||
|
||||
val spaceCInfo = createPublicSpace(session, "SpaceC", listOf(
|
||||
Triple("C1", true /*auto-join*/, true/*canonical*/),
|
||||
Triple("C2", true, true)
|
||||
))
|
||||
|
||||
// add C as subspace of B
|
||||
val spaceB = session.spaceService().getSpace(spaceBInfo.spaceId)
|
||||
spaceB!!.addChildren(spaceCInfo.spaceId, viaServers, null, true)
|
||||
@ -408,7 +408,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
): TestSpaceCreationResult {
|
||||
var spaceId = ""
|
||||
var roomIds: List<String> = emptyList()
|
||||
commonTestHelper.waitWithLatch {
|
||||
commonTestHelper.waitWithLatch { latch ->
|
||||
spaceId = session.spaceService().createSpace(spaceName, "My Private Space", null, false)
|
||||
val syncedSpace = session.spaceService().getSpace(spaceId)
|
||||
val viaServers = listOf(session.sessionParams.homeServerHost ?: "")
|
||||
@ -433,6 +433,7 @@ class SpaceHierarchyTest : InstrumentedTest {
|
||||
session.spaceService().setSpaceParent(roomId, spaceId, canonical, viaServers)
|
||||
}
|
||||
}
|
||||
latch.countDown()
|
||||
}
|
||||
return TestSpaceCreationResult(spaceId, roomIds)
|
||||
}
|
||||
|
@ -25,13 +25,18 @@ import javax.inject.Inject
|
||||
internal class SyncTokenStore @Inject constructor(@SessionDatabase private val monarchy: Monarchy) {
|
||||
|
||||
fun getLastToken(): String? {
|
||||
return Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
val token = Realm.getInstance(monarchy.realmConfiguration).use {
|
||||
// Makes sure realm is up-to-date as it's used for querying internally on non looper thread.
|
||||
it.refresh()
|
||||
it.where(SyncEntity::class.java).findFirst()?.nextBatch
|
||||
}
|
||||
return token
|
||||
}
|
||||
|
||||
fun saveToken(realm: Realm, token: String?) {
|
||||
val sync = SyncEntity(token)
|
||||
realm.insertOrUpdate(sync)
|
||||
if(realm.isInTransaction) {
|
||||
val sync = SyncEntity(token)
|
||||
realm.insertOrUpdate(sync)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -193,6 +193,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle
|
||||
aggregator: SyncResponsePostTreatmentAggregator): RoomEntity {
|
||||
Timber.v("Handle join sync for room $roomId")
|
||||
|
||||
|
||||
val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed)
|
||||
?._roomSyncEphemeral
|
||||
?.events
|
||||
|
Loading…
Reference in New Issue
Block a user