diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt index e0c1c0f534..fb0c6853de 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/auth/AuthenticatorTest.kt @@ -6,7 +6,6 @@ import android.support.test.runner.AndroidJUnit4 import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.InstrumentedTest import im.vector.matrix.android.OkReplayRuleChainNoActivity -import im.vector.matrix.android.api.MatrixOptions import im.vector.matrix.android.api.auth.Authenticator import im.vector.matrix.android.internal.auth.AuthModule import im.vector.matrix.android.internal.di.MatrixModule @@ -26,7 +25,7 @@ internal class AuthenticatorTest : InstrumentedTest, KoinTest { init { Monarchy.init(context()) - val matrixModule = MatrixModule(MatrixOptions(context())).definition + val matrixModule = MatrixModule(context()).definition val networkModule = NetworkModule().definition val authModule = AuthModule().definition loadKoinModules(listOf(matrixModule, networkModule, authModule)) diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt index 137ec790e1..181f0c1ed9 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/ChunkEntityTest.kt @@ -4,11 +4,7 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.InstrumentedTest import im.vector.matrix.android.api.session.events.model.Event import im.vector.matrix.android.api.session.events.model.EventType -import im.vector.matrix.android.internal.database.helper.add -import im.vector.matrix.android.internal.database.helper.addAll -import im.vector.matrix.android.internal.database.helper.isUnlinked -import im.vector.matrix.android.internal.database.helper.lastStateIndex -import im.vector.matrix.android.internal.database.helper.merge +import im.vector.matrix.android.internal.database.helper.* import im.vector.matrix.android.internal.database.model.ChunkEntity import im.vector.matrix.android.internal.session.room.timeline.PaginationDirection import io.realm.Realm @@ -39,7 +35,7 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk: ChunkEntity = realm.createObject() val fakeEvent = createFakeEvent(false) - chunk.add(fakeEvent, PaginationDirection.FORWARDS) + chunk.add("roomId", fakeEvent, PaginationDirection.FORWARDS) chunk.events.size shouldEqual 1 } } @@ -49,8 +45,8 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk: ChunkEntity = realm.createObject() val fakeEvent = createFakeEvent(false) - chunk.add(fakeEvent, PaginationDirection.FORWARDS) - chunk.add(fakeEvent, PaginationDirection.FORWARDS) + chunk.add("roomId", fakeEvent, PaginationDirection.FORWARDS) + chunk.add("roomId", fakeEvent, PaginationDirection.FORWARDS) chunk.events.size shouldEqual 1 } } @@ -60,7 +56,7 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk: ChunkEntity = realm.createObject() val fakeEvent = createFakeEvent(true) - chunk.add(fakeEvent, PaginationDirection.FORWARDS) + chunk.add("roomId", fakeEvent, PaginationDirection.FORWARDS) chunk.lastStateIndex(PaginationDirection.FORWARDS) shouldEqual 1 } } @@ -70,7 +66,7 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk: ChunkEntity = realm.createObject() val fakeEvent = createFakeEvent(false) - chunk.add(fakeEvent, PaginationDirection.FORWARDS) + chunk.add("roomId", fakeEvent, PaginationDirection.FORWARDS) chunk.lastStateIndex(PaginationDirection.FORWARDS) shouldEqual 0 } } @@ -81,7 +77,7 @@ internal class ChunkEntityTest : InstrumentedTest { val chunk: ChunkEntity = realm.createObject() val fakeEvents = createFakeListOfEvents(30) val numberOfStateEvents = fakeEvents.filter { it.isStateEvent() }.size - chunk.addAll(fakeEvents, PaginationDirection.FORWARDS) + chunk.addAll("roomId", fakeEvents, PaginationDirection.FORWARDS) chunk.lastStateIndex(PaginationDirection.FORWARDS) shouldEqual numberOfStateEvents } } @@ -94,7 +90,7 @@ internal class ChunkEntityTest : InstrumentedTest { val numberOfStateEvents = fakeEvents.filter { it.isStateEvent() }.size val lastIsState = fakeEvents.last().isStateEvent() val expectedStateIndex = if (lastIsState) -numberOfStateEvents + 1 else -numberOfStateEvents - chunk.addAll(fakeEvents, PaginationDirection.BACKWARDS) + chunk.addAll("roomId", fakeEvents, PaginationDirection.BACKWARDS) chunk.lastStateIndex(PaginationDirection.BACKWARDS) shouldEqual expectedStateIndex } } @@ -104,20 +100,37 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk1: ChunkEntity = realm.createObject() val chunk2: ChunkEntity = realm.createObject() - chunk1.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS) - chunk2.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS) + chunk1.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS) + chunk2.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS) chunk1.merge(chunk2, PaginationDirection.BACKWARDS) chunk1.events.size shouldEqual 60 } } + @Test + fun merge_shouldAddOnlyDifferentEvents_whenMergingBackward() { + monarchy.runTransactionSync { realm -> + val chunk1: ChunkEntity = realm.createObject() + val chunk2: ChunkEntity = realm.createObject() + val eventsForChunk1 = createFakeListOfEvents(30) + val eventsForChunk2 = eventsForChunk1 + createFakeListOfEvents(10) + chunk1.isLast = true + chunk2.isLast = false + chunk1.addAll("roomId", eventsForChunk1, PaginationDirection.FORWARDS) + chunk2.addAll("roomId", eventsForChunk2, PaginationDirection.BACKWARDS) + chunk1.merge(chunk2, PaginationDirection.BACKWARDS) + chunk1.events.size shouldEqual 40 + chunk1.isLast.shouldBeTrue() + } + } + @Test fun merge_shouldEventsBeLinked_whenMergingLinkedWithUnlinked() { monarchy.runTransactionSync { realm -> val chunk1: ChunkEntity = realm.createObject() val chunk2: ChunkEntity = realm.createObject() - chunk1.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) - chunk2.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = false) + chunk1.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk2.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = false) chunk1.merge(chunk2, PaginationDirection.BACKWARDS) chunk1.isUnlinked().shouldBeFalse() } @@ -128,8 +141,8 @@ internal class ChunkEntityTest : InstrumentedTest { monarchy.runTransactionSync { realm -> val chunk1: ChunkEntity = realm.createObject() val chunk2: ChunkEntity = realm.createObject() - chunk1.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) - chunk2.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk1.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk2.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) chunk1.merge(chunk2, PaginationDirection.BACKWARDS) chunk1.isUnlinked().shouldBeTrue() } @@ -142,8 +155,8 @@ internal class ChunkEntityTest : InstrumentedTest { val chunk2: ChunkEntity = realm.createObject() val prevToken = "prev_token" chunk1.prevToken = prevToken - chunk1.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) - chunk2.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk1.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk2.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) chunk1.merge(chunk2, PaginationDirection.FORWARDS) chunk1.prevToken shouldEqual prevToken } @@ -156,8 +169,8 @@ internal class ChunkEntityTest : InstrumentedTest { val chunk2: ChunkEntity = realm.createObject() val nextToken = "next_token" chunk1.nextToken = nextToken - chunk1.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) - chunk2.addAll(createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk1.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) + chunk2.addAll("roomId", createFakeListOfEvents(30), PaginationDirection.BACKWARDS, isUnlinked = true) chunk1.merge(chunk2, PaginationDirection.BACKWARDS) chunk1.nextToken shouldEqual nextToken } diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/RoomDataHelper.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/RoomDataHelper.kt index 2385d79405..c7279bf2d7 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/RoomDataHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/RoomDataHelper.kt @@ -34,7 +34,7 @@ object RoomDataHelper { prevToken = Random.nextLong(System.currentTimeMillis()).toString() isLast = true } - chunkEntity.addAll(eventList, PaginationDirection.FORWARDS) + chunkEntity.addAll("roomId", eventList, PaginationDirection.FORWARDS) roomEntity.addOrUpdate(chunkEntity) } } diff --git a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt index fc8731abf0..38b465d8d8 100644 --- a/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt +++ b/matrix-sdk-android/src/androidTest/java/im/vector/matrix/android/session/room/timeline/TimelineHolderTest.kt @@ -6,10 +6,11 @@ import com.zhuinden.monarchy.Monarchy import im.vector.matrix.android.InstrumentedTest import im.vector.matrix.android.LiveDataTestObserver import im.vector.matrix.android.api.thread.MainThreadExecutor -import im.vector.matrix.android.internal.task.TaskExecutor +import im.vector.matrix.android.internal.session.room.members.RoomMemberExtractor import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineHolder import im.vector.matrix.android.internal.session.room.timeline.TimelineBoundaryCallback import im.vector.matrix.android.internal.session.room.timeline.TokenChunkEventPersistor +import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.util.PagingRequestHelper import im.vector.matrix.android.testCoroutineDispatchers import io.realm.Realm @@ -43,7 +44,7 @@ internal class TimelineHolderTest : InstrumentedTest { val boundaryCallback = TimelineBoundaryCallback(roomId, taskExecutor, paginationTask, monarchy, PagingRequestHelper(MainThreadExecutor())) RoomDataHelper.fakeInitialSync(monarchy, roomId) - val timelineHolder = DefaultTimelineHolder(roomId, monarchy, taskExecutor, boundaryCallback, getContextOfEventTask) + val timelineHolder = DefaultTimelineHolder(roomId, monarchy, taskExecutor, boundaryCallback, getContextOfEventTask, RoomMemberExtractor(monarchy, roomId)) val timelineObserver = LiveDataTestObserver.test(timelineHolder.timeline()) timelineObserver.awaitNextValue().assertHasValue() var pagedList = timelineObserver.value() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt index 714ac0f7dc..467329c8e1 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/api/Matrix.kt @@ -12,6 +12,7 @@ import im.vector.matrix.android.internal.di.MatrixModule import im.vector.matrix.android.internal.di.NetworkModule import im.vector.matrix.android.internal.util.BackgroundDetectionObserver import org.koin.standalone.inject +import java.util.concurrent.atomic.AtomicBoolean class Matrix private constructor(context: Context) : MatrixKoinComponent { @@ -40,9 +41,12 @@ class Matrix private constructor(context: Context) : MatrixKoinComponent { companion object { private lateinit var instance: Matrix + private val isInit = AtomicBoolean(false) internal fun initialize(context: Context) { - instance = Matrix(context.applicationContext) + if (isInit.compareAndSet(false, true)) { + instance = Matrix(context.applicationContext) + } } fun getInstance(): Matrix {