Skip to content

Commit b6f141f

Browse files
authored
[RKOTLIN-1115] Add support for switching user (#1816)
1 parent fc7bad7 commit b6f141f

File tree

8 files changed

+50
-41
lines changed

8 files changed

+50
-41
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* None.
55

66
### Enhancements
7-
* None.
7+
* [Sync] Add support for switching users with `App.switchUser(User)`. (Issue [#1813](https://github.com/realm/realm-kotlin/issues/1813)/[RKOTLIN-1115](https://jira.mongodb.org/browse/RKOTLIN-1115)).
88

99
### Fixed
1010
* None.

packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@ expect object RealmInterop {
529529
fun realm_app_remove_user(app: RealmAppPointer, user: RealmUserPointer, callback: AppCallback<Unit>)
530530
fun realm_app_delete_user(app: RealmAppPointer, user: RealmUserPointer, callback: AppCallback<Unit>)
531531
fun realm_app_link_credentials(app: RealmAppPointer, user: RealmUserPointer, credentials: RealmCredentialsPointer, callback: AppCallback<RealmUserPointer>)
532+
fun realm_app_switch_user(app: RealmAppPointer, user: RealmUserPointer)
532533
fun realm_clear_cached_apps()
533534
fun realm_app_sync_client_get_default_file_path_for_realm(
534535
syncConfig: RealmSyncConfigurationPointer,

packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,10 @@ actual object RealmInterop {
12011201
realmc.realm_app_link_user(app.cptr(), user.cptr(), credentials.cptr(), callback)
12021202
}
12031203

1204+
actual fun realm_app_switch_user(app: RealmAppPointer, user: RealmUserPointer) {
1205+
realmc.realm_app_switch_user(app.cptr(), user.cptr())
1206+
}
1207+
12041208
actual fun realm_app_get_current_user(app: RealmAppPointer): RealmUserPointer? {
12051209
val ptr = realmc.realm_app_get_current_user(app.cptr())
12061210
return nativePointerOrNull(ptr)

packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,6 +2357,10 @@ actual object RealmInterop {
23572357
)
23582358
}
23592359

2360+
actual fun realm_app_switch_user(app: RealmAppPointer, user: RealmUserPointer) {
2361+
checkedBooleanResult(realm_wrapper.realm_app_switch_user(app.cptr(), user.cptr()))
2362+
}
2363+
23602364
actual fun realm_clear_cached_apps() {
23612365
realm_wrapper.realm_clear_cached_apps()
23622366
}

packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/App.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,15 @@ public interface App {
121121
*/
122122
public suspend fun login(credentials: Credentials): User
123123

124+
/**
125+
* Switch current user.
126+
*
127+
* @param user the user that should be the new current user. The user must be one of the users
128+
* that are already logged in.
129+
* @throws IllegalStateException If the [user] is not logged in.
130+
*/
131+
public fun switchUser(user: User)
132+
124133
/**
125134
* Create a [Flow] of [AuthenticationChange]-events to receive notifications of updates to all
126135
* app user authentication states: login, logout and removal.

packages/library-sync/src/commonMain/kotlin/io/realm/kotlin/mongodb/internal/AppImpl.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ public class AppImpl(
163163
}
164164
}
165165

166+
override fun switchUser(user: User) {
167+
Validation.isType<UserImpl>(user)
168+
RealmInterop.realm_app_switch_user(this.nativePointer, user.nativePointer)
169+
}
170+
166171
internal fun reportAuthenticationChange(user: User, change: User.State) {
167172
val event: AuthenticationChange = when (change) {
168173
User.State.LOGGED_OUT -> LoggedOutImpl(user)

packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/AppTests.kt

Lines changed: 25 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import kotlin.test.assertNotEquals
6262
import kotlin.test.assertNull
6363
import kotlin.test.assertSame
6464
import kotlin.test.assertTrue
65+
import kotlin.test.fail
6566

6667
class AppTests {
6768

@@ -210,30 +211,30 @@ class AppTests {
210211
assertTrue(app.allUsers().isEmpty())
211212
}
212213

213-
// @Test
214-
// fun switchUser() {
215-
// val user1: User = app.login(Credentials.anonymous())
216-
// assertEquals(user1, app.currentUser())
217-
// val user2: User = app.login(Credentials.anonymous())
218-
// assertEquals(user2, app.currentUser())
219-
//
220-
// assertEquals(user1, app.switchUser(user1))
221-
// assertEquals(user1, app.currentUser())
222-
// }
223-
//
224-
// @Test
225-
// fun switchUser_throwIfUserNotLoggedIn() = runBlocking {
226-
// val user1 = app.login(Credentials.anonymous())
227-
// val user2 = app.login(Credentials.anonymous())
228-
// assertEquals(user2, app.currentUser)
229-
//
230-
// user1.logOut()
231-
// try {
232-
// app.switchUser(user1)
233-
// fail()
234-
// } catch (ignore: IllegalArgumentException) {
235-
// }
236-
// }
214+
@Test
215+
fun switchUser() = runBlocking {
216+
val user1: User = app.login(Credentials.anonymous())
217+
assertEquals(user1, app.currentUser)
218+
val user2: User = app.login(Credentials.anonymous())
219+
assertEquals(user2, app.currentUser)
220+
221+
app.switchUser(user1)
222+
assertEquals(user1, app.currentUser)
223+
}
224+
225+
@Test
226+
fun switchUser_throwIfUserNotLoggedIn() = runBlocking {
227+
val user1 = app.login(Credentials.anonymous())
228+
val user2 = app.login(Credentials.anonymous())
229+
assertEquals(user2, app.currentUser)
230+
231+
user1.logOut()
232+
try {
233+
app.switchUser(user1)
234+
fail()
235+
} catch (ignore: IllegalStateException) {
236+
}
237+
}
237238

238239
@Test
239240
fun currentUser_FallbackToNextValidUser() = runBlocking {
@@ -262,21 +263,6 @@ class AppTests {
262263
assertNull(app.currentUser)
263264
}
264265

265-
// @Test
266-
// fun switchUser_nullThrows() {
267-
// try {
268-
// app.switchUser(TestHelper.getNull())
269-
// fail()
270-
// } catch (ignore: IllegalArgumentException) {
271-
// }
272-
// }
273-
//
274-
// @Ignore("Add this test once we have support for both EmailPassword and ApiKey Auth Providers")
275-
// @Test
276-
// fun switchUser_authProvidersLockUsers() {
277-
// TODO("FIXME")
278-
// }
279-
//
280266
@Test
281267
fun authenticationChangeAsFlow() = runBlocking<Unit> {
282268
val c = TestChannel<AuthenticationChange>()

packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/FunctionsTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ class FunctionsTests {
10201020
runBlocking {
10211021
anonUser.logOut()
10221022
}
1023-
assertFailsWithMessage<ServiceException>("[Service][Unknown(4351)] unauthorized") {
1023+
assertFailsWithMessage<ServiceException>("unauthorized") {
10241024
runBlocking {
10251025
functions.call(FIRST_ARG_FUNCTION.name, 1, 2, 3)
10261026
}

0 commit comments

Comments
 (0)