From fb2f6fe1bd567ffccc753d13f37a8612c41e8a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Claus=20R=C3=B8rbech?= Date: Mon, 8 Jul 2024 14:15:43 +0200 Subject: [PATCH] Fix sync client and realm tests --- .../test/mongodb/common/SyncClientTests.kt | 4 +- .../test/mongodb/common/SyncedRealmTests.kt | 364 ++++++++++-------- 2 files changed, 198 insertions(+), 170 deletions(-) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientTests.kt index dd8d461b38..e4403d0e84 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncClientTests.kt @@ -8,7 +8,7 @@ import io.realm.kotlin.mongodb.sync.SyncConfiguration import io.realm.kotlin.test.mongodb.TestApp import io.realm.kotlin.test.mongodb.asTestApp import io.realm.kotlin.test.mongodb.createUserAndLogIn -import io.realm.kotlin.test.mongodb.util.DefaultPartitionBasedAppInitializer +import io.realm.kotlin.test.mongodb.util.DefaultFlexibleSyncAppInitializer import io.realm.kotlin.test.util.TestHelper import io.realm.kotlin.test.util.use import kotlin.test.AfterTest @@ -29,7 +29,7 @@ class SyncClientTests { @BeforeTest fun setup() { - app = TestApp(this::class.simpleName, DefaultPartitionBasedAppInitializer) + app = TestApp(this::class.simpleName, DefaultFlexibleSyncAppInitializer) val (email, password) = TestHelper.randomEmail() to "password1234" user = runBlocking { app.createUserAndLogIn(email, password) diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index 6755835db8..0797f221a3 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -721,79 +721,100 @@ class SyncedRealmTests { fun roundtripCollectionsInMixed() = runBlocking { val (email1, password1) = randomEmail() to "password1234" val (email2, password2) = randomEmail() to "password1234" - val app = TestApp(this::class.simpleName, DefaultFlexibleSyncAppInitializer) - val user1 = app.createUserAndLogIn(email1, password1) - val user2 = app.createUserAndLogIn(email2, password2) - - // Create object with all types - val selector = ObjectId().toString() - var parentId: ObjectId? = null - var childId: ObjectId? = null + TestApp(this::class.simpleName, DefaultFlexibleSyncAppInitializer).use { app -> + val user1 = app.createUserAndLogIn(email1, password1) + val user2 = app.createUserAndLogIn(email2, password2) - createFlexibleSyncConfig( - user = user1, - initialSubscriptions = { realm -> - realm.query("selector = $0", selector).subscribe() - } - ).let { config -> - Realm.open(config).use { realm -> - realm.write { - val child = ( - JsonStyleRealmObject().apply { - this.selector = selector - } - ) - childId = child.id + // Create object with all types + val selector = ObjectId().toString() + var parentId: ObjectId? = null + var childId: ObjectId? = null - parentId = copyToRealm( - JsonStyleRealmObject().apply { - this.selector = selector - value = realmAnyDictionaryOf( - "primitive" to 1, - // List with nested dictionary - "list" to realmAnyListOf(1, "Realm", child, realmAnyDictionaryOf("listkey1" to 1, "listkey2" to "Realm", "listkey3" to child)), - "dictionary" to realmAnyDictionaryOf("dictkey1" to 1, "dictkey2" to "Realm", "dictkey3" to child, "dictkey4" to realmAnyListOf(1, 2, 3)) - ) - } - ).id + createFlexibleSyncConfig( + user = user1, + initialSubscriptions = { realm -> + realm.query("selector = $0", selector).subscribe() + } + ).let { config -> + Realm.open(config).use { realm -> + realm.write { + val child = ( + JsonStyleRealmObject().apply { + this.selector = selector + } + ) + childId = child.id + + parentId = copyToRealm( + JsonStyleRealmObject().apply { + this.selector = selector + value = realmAnyDictionaryOf( + "primitive" to 1, + // List with nested dictionary + "list" to realmAnyListOf( + 1, + "Realm", + child, + realmAnyDictionaryOf( + "listkey1" to 1, + "listkey2" to "Realm", + "listkey3" to child + ) + ), + "dictionary" to realmAnyDictionaryOf( + "dictkey1" to 1, + "dictkey2" to "Realm", + "dictkey3" to child, + "dictkey4" to realmAnyListOf(1, 2, 3) + ) + ) + } + ).id + } + realm.syncSession.uploadAllLocalChangesOrFail() } - realm.syncSession.uploadAllLocalChangesOrFail() - } - } - createFlexibleSyncConfig( - user = user2, - initialSubscriptions = { realm -> - realm.query("selector = $0", selector).subscribe() } - ).let { config -> - Realm.open(config).use { realm -> - realm.syncSession.downloadAllServerChanges(10.seconds) - val flow = realm.query("_id = $0", parentId).asFlow() - val parent = withTimeout(10.seconds) { - flow.first { - it.list.size >= 1 - }.list[0] + createFlexibleSyncConfig( + user = user2, + initialSubscriptions = { realm -> + realm.query("selector = $0", selector).subscribe() } - parent.let { - val value = it.value!!.asDictionary() - assertEquals(RealmAny.Companion.create(1), value["primitive"]) - value["list"]!!.asList().let { - assertEquals(1, it[0]!!.asInt()) - assertEquals("Realm", it[1]!!.asString()) - assertEquals(childId, it[2]!!.asRealmObject().id) - it[3]!!.asDictionary().let { dict -> - assertEquals(1, dict["listkey1"]!!.asInt()) - assertEquals("Realm", dict["listkey2"]!!.asString()) - assertEquals(childId, dict["listkey3"]!!.asRealmObject().id) - } - assertEquals(childId, it[2]!!.asRealmObject().id) + ).let { config -> + Realm.open(config).use { realm -> + realm.syncSession.downloadAllServerChanges(10.seconds) + val flow = realm.query("_id = $0", parentId).asFlow() + val parent = withTimeout(10.seconds) { + flow.first { + it.list.size >= 1 + }.list[0] } - value["dictionary"]!!.asDictionary().let { - assertEquals(1, it["dictkey1"]!!.asInt()) - assertEquals("Realm", it["dictkey2"]!!.asString()) - assertEquals(childId, it["dictkey3"]!!.asRealmObject().id) - it["dictkey4"]!!.asList().let { - assertEquals(realmAnyListOf(1, 2, 3).asList(), it) + parent.let { + val value = it.value!!.asDictionary() + assertEquals(RealmAny.Companion.create(1), value["primitive"]) + value["list"]!!.asList().let { + assertEquals(1, it[0]!!.asInt()) + assertEquals("Realm", it[1]!!.asString()) + assertEquals(childId, it[2]!!.asRealmObject().id) + it[3]!!.asDictionary().let { dict -> + assertEquals(1, dict["listkey1"]!!.asInt()) + assertEquals("Realm", dict["listkey2"]!!.asString()) + assertEquals( + childId, + dict["listkey3"]!!.asRealmObject().id + ) + } + assertEquals(childId, it[2]!!.asRealmObject().id) + } + value["dictionary"]!!.asDictionary().let { + assertEquals(1, it["dictkey1"]!!.asInt()) + assertEquals("Realm", it["dictkey2"]!!.asString()) + assertEquals( + childId, + it["dictkey3"]!!.asRealmObject().id + ) + it["dictkey4"]!!.asList().let { + assertEquals(realmAnyListOf(1, 2, 3).asList(), it) + } } } } @@ -805,122 +826,129 @@ class SyncedRealmTests { fun collectionsInMixed_asFlow() = runBlocking { val (email1, password1) = randomEmail() to "password1234" val (email2, password2) = randomEmail() to "password1234" - val app = TestApp(this::class.simpleName, DefaultFlexibleSyncAppInitializer) - val user1 = app.createUserAndLogIn(email1, password1) - val user2 = app.createUserAndLogIn(email2, password2) + TestApp(this::class.simpleName, DefaultFlexibleSyncAppInitializer).use { app -> + val user1 = app.createUserAndLogIn(email1, password1) + val user2 = app.createUserAndLogIn(email2, password2) - // Create object with all types - val selector = ObjectId().toString() + // Create object with all types + val selector = ObjectId().toString() - val updateChannel = TestChannel() + val updateChannel = TestChannel() - val configWriter = createFlexibleSyncConfig( - user = user1, - initialSubscriptions = { realm -> - realm.query("selector = $0", selector).subscribe() + val configWriter = createFlexibleSyncConfig( + user = user1, + initialSubscriptions = { realm -> + realm.query("selector = $0", selector).subscribe() + } + ) + val configReader = createFlexibleSyncConfig( + user = user2, + initialSubscriptions = { realm -> + realm.query("selector = $0", selector).subscribe() + }, + ) { + this.waitForInitialRemoteData(10.seconds) } - ) - val configReader = createFlexibleSyncConfig( - user = user2, - initialSubscriptions = { realm -> - realm.query("selector = $0", selector).subscribe() - }, - ) { - this.waitForInitialRemoteData(10.seconds) - } - Realm.open(configWriter).use { writerRealm -> - val source = writerRealm.write { - copyToRealm( - JsonStyleRealmObject().apply { - this.selector = selector - value = realmAnyDictionaryOf( - // List with nested dictionary - "list" to realmAnyListOf( - 1, - "Realm", - realmAnyDictionaryOf("listkey1" to 1) - ), - // Dictionary with nested list - "dictionary" to realmAnyDictionaryOf( - "dictkey1" to 1, - "dictkey2" to "Realm", - "dictkey3" to realmAnyListOf(1, 2, 3) + Realm.open(configWriter).use { writerRealm -> + val source = writerRealm.write { + copyToRealm( + JsonStyleRealmObject().apply { + this.selector = selector + value = realmAnyDictionaryOf( + // List with nested dictionary + "list" to realmAnyListOf( + 1, + "Realm", + realmAnyDictionaryOf("listkey1" to 1) + ), + // Dictionary with nested list + "dictionary" to realmAnyDictionaryOf( + "dictkey1" to 1, + "dictkey2" to "Realm", + "dictkey3" to realmAnyListOf(1, 2, 3) + ) ) - ) + } + ) + } + writerRealm.syncSession.uploadAllLocalChangesOrFail() + + Realm.open(configReader).use { readerRealm -> + val reader = + readerRealm.query("selector = $0", selector).find() + .single() + val listener = async { + reader.asFlow().collect { + updateChannel.trySendOrFail(it.obj!!) + } } - ) - } - writerRealm.syncSession.uploadAllLocalChangesOrFail() - - Realm.open(configReader).use { readerRealm -> - val reader = readerRealm.query("selector = $0", selector).find().single() - val listener = async { - reader.asFlow().collect { - updateChannel.trySendOrFail(it.obj!!) + // Flush initial event from channel + updateChannel.receiveOrFail() + + // List add + writerRealm.write { + findLatest(source)!!.run { + value!!.asDictionary()["list"]!!.asList() + .add(RealmAny.Companion.create(6)) + } } - } - // Flush initial event from channel - updateChannel.receiveOrFail() - - // List add - writerRealm.write { - findLatest(source)!!.run { - value!!.asDictionary()["list"]!!.asList().add(RealmAny.Companion.create(6)) + updateChannel.receiveOrFail().run { + val updatedList = value!!.asDictionary()["list"]!!.asList() + assertEquals(4, updatedList.size) + assertEquals(1, updatedList[0]!!.asInt()) + assertEquals("Realm", updatedList[1]!!.asString()) + assertIs>(updatedList[2]!!.asDictionary()) + assertEquals(6, updatedList[3]!!.asInt()) } - } - updateChannel.receiveOrFail().run { - val updatedList = value!!.asDictionary()["list"]!!.asList() - assertEquals(4, updatedList.size) - assertEquals(1, updatedList[0]!!.asInt()) - assertEquals("Realm", updatedList[1]!!.asString()) - assertIs>(updatedList[2]!!.asDictionary()) - assertEquals(6, updatedList[3]!!.asInt()) - } - // List removal - writerRealm.write { - findLatest(source)!!.run { - value!!.asDictionary()["list"]!!.asList().removeAt(1) + // List removal + writerRealm.write { + findLatest(source)!!.run { + value!!.asDictionary()["list"]!!.asList().removeAt(1) + } + } + updateChannel.receiveOrFail().run { + val updatedList = value!!.asDictionary()["list"]!!.asList() + assertEquals(3, updatedList.size) + assertEquals(1, updatedList[0]!!.asInt()) + assertIs>(updatedList[1]!!.asDictionary()) + assertEquals(6, updatedList[2]!!.asInt()) } - } - updateChannel.receiveOrFail().run { - val updatedList = value!!.asDictionary()["list"]!!.asList() - assertEquals(3, updatedList.size) - assertEquals(1, updatedList[0]!!.asInt()) - assertIs>(updatedList[1]!!.asDictionary()) - assertEquals(6, updatedList[2]!!.asInt()) - } - // Dictionary add - writerRealm.write { - findLatest(source)!!.run { - value!!.asDictionary()["dictionary"]!!.asDictionary()["dictkey4"] = RealmAny.Companion.create(6) + // Dictionary add + writerRealm.write { + findLatest(source)!!.run { + value!!.asDictionary()["dictionary"]!!.asDictionary()["dictkey4"] = + RealmAny.Companion.create(6) + } + } + updateChannel.receiveOrFail().run { + val updatedDictionary = + value!!.asDictionary()["dictionary"]!!.asDictionary() + assertEquals(4, updatedDictionary.size) + assertEquals(1, updatedDictionary["dictkey1"]!!.asInt()) + assertEquals("Realm", updatedDictionary["dictkey2"]!!.asString()) + assertIs>(updatedDictionary["dictkey3"]!!.asList()) + assertEquals(6, updatedDictionary["dictkey4"]!!.asInt()) } - } - updateChannel.receiveOrFail().run { - val updatedDictionary = value!!.asDictionary()["dictionary"]!!.asDictionary() - assertEquals(4, updatedDictionary.size) - assertEquals(1, updatedDictionary["dictkey1"]!!.asInt()) - assertEquals("Realm", updatedDictionary["dictkey2"]!!.asString()) - assertIs>(updatedDictionary["dictkey3"]!!.asList()) - assertEquals(6, updatedDictionary["dictkey4"]!!.asInt()) - } - // Dictionary removal - writerRealm.write { - findLatest(source)!!.run { - value!!.asDictionary()["dictionary"]!!.asDictionary().remove("dictkey3") + // Dictionary removal + writerRealm.write { + findLatest(source)!!.run { + value!!.asDictionary()["dictionary"]!!.asDictionary().remove("dictkey3") + } + } + updateChannel.receiveOrFail().run { + val updatedDictionary = + value!!.asDictionary()["dictionary"]!!.asDictionary() + assertEquals(3, updatedDictionary.size) + assertEquals(1, updatedDictionary["dictkey1"]!!.asInt()) + assertEquals("Realm", updatedDictionary["dictkey2"]!!.asString()) + assertEquals(6, updatedDictionary["dictkey4"]!!.asInt()) } - } - updateChannel.receiveOrFail().run { - val updatedDictionary = value!!.asDictionary()["dictionary"]!!.asDictionary() - assertEquals(3, updatedDictionary.size) - assertEquals(1, updatedDictionary["dictkey1"]!!.asInt()) - assertEquals("Realm", updatedDictionary["dictkey2"]!!.asString()) - assertEquals(6, updatedDictionary["dictkey4"]!!.asInt()) - } - listener.cancel() + listener.cancel() + } } } }