diff --git a/cells/build.gradle.kts b/cells/build.gradle.kts index 86bfcf23da5..d9d64ccb627 100644 --- a/cells/build.gradle.kts +++ b/cells/build.gradle.kts @@ -49,6 +49,7 @@ kotlin { implementation(libs.turbine) // ktor test implementation(libs.ktor.mock) + implementation(libs.ktor.contentNegotiation) // mocks implementation(libs.okio.test) } diff --git a/cells/src/commonMain/kotlin/com/wire/kalium/cells/data/CellsApiImpl.kt b/cells/src/commonMain/kotlin/com/wire/kalium/cells/data/CellsApiImpl.kt index 98976060896..830225d5038 100644 --- a/cells/src/commonMain/kotlin/com/wire/kalium/cells/data/CellsApiImpl.kt +++ b/cells/src/commonMain/kotlin/com/wire/kalium/cells/data/CellsApiImpl.kt @@ -323,7 +323,7 @@ internal class CellsApiImpl( }.mapSuccess { } override suspend fun getAllTags(): NetworkResponse> = wrapCellsResponse { - nodeServiceApi.listNamespaceValues(namespace = TAGS_METADATA, operationValues = listOf()) + nodeServiceApi.listNamespaceValues(namespace = TAGS_METADATA) }.mapSuccess { it.propertyValues ?: emptyList() } private fun networkError(message: String) = diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 535ff25f4a7..4b053bca91f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,7 +12,7 @@ compose-material3 = "1.0.0-alpha01" compose-jetbrains = "1.8.2" fileKit = "0.10.0-beta04" android-security = "1.1.0-alpha06" -ktor = "2.3.10" +ktor = "3.2.3" okio = "3.9.0" ok-http = "4.12.0" # 3.0.1 with a fix for a bug https://github.com/mockative/mockative/issues/143 uploaded to a temporary repo @@ -43,7 +43,7 @@ jna = "5.17.0" core-crypto = "9.1.1" completeKotlin = "1.1.0" desugar-jdk = "2.1.3" -kermit = "2.0.3" +kermit = "2.0.6" detekt = "1.23.8" agp = "8.10.1" dokka = "2.0.0" @@ -69,7 +69,7 @@ jmh = "1.37" jmhReport = "0.9.6" xerialDriver = "3.48.0.0" kotlinx-io = "0.5.3" -cells-sdk = "0.1.1-alpha10" +cells-sdk = "0.1.1-alpha15" [plugins] # Home-made convention plugins diff --git a/logic/build.gradle.kts b/logic/build.gradle.kts index e2f5d6f8f99..0e5448d0e4d 100644 --- a/logic/build.gradle.kts +++ b/logic/build.gradle.kts @@ -126,18 +126,21 @@ kotlin { } android { - testOptions.unitTests.isIncludeAndroidResources = true -} + testOptions { + unitTests { + isIncludeAndroidResources = true + all { test -> + test.enabled = true -android { - testOptions.unitTests.all { test -> - // only run tests that are different for the android platform, the rest is covered by the jvm tests - file("src/androidUnitTest/kotlin").let { dir -> - if (dir.exists() && dir.isDirectory) { - dir.walk().forEach { - if (it.isFile && it.extension == "kt") { - it.relativeToOrNull(dir)?.let { - test.include(it.path.removeSuffix(".kt").suffixIfNot("*")) + // only run tests that are different for the android platform, the rest is covered by the jvm tests + file("src/androidUnitTest/kotlin").let { dir -> + if (dir.exists() && dir.isDirectory) { + dir.walk().forEach { + if (it.isFile && it.extension == "kt") { + it.relativeToOrNull(dir)?.let { + test.include(it.path.removeSuffix(".kt").suffixIfNot("*")) + } + } } } } diff --git a/network/build.gradle.kts b/network/build.gradle.kts index b797ad50cfb..9ca2fbbec57 100644 --- a/network/build.gradle.kts +++ b/network/build.gradle.kts @@ -62,6 +62,7 @@ kotlin { // mock engine implementation(libs.ktor.mock) + implementation(libs.ktor.contentNegotiation) // KTX implementation(libs.ktxDateTime) diff --git a/network/consumer-proguard-rules.pro b/network/consumer-proguard-rules.pro index ea9ab67ecea..63fe79790a7 100644 --- a/network/consumer-proguard-rules.pro +++ b/network/consumer-proguard-rules.pro @@ -45,3 +45,25 @@ # protobuf -keep class * extends com.google.protobuf.GeneratedMessageLite { *; } + +# Ktor +-dontwarn io.ktor.client.network.sockets.SocketTimeoutException +-dontwarn io.ktor.client.network.sockets.TimeoutExceptionsCommonKt +-dontwarn io.ktor.client.plugins.HttpTimeout$HttpTimeoutCapabilityConfiguration +-dontwarn io.ktor.client.plugins.HttpTimeout$Plugin +-dontwarn io.ktor.client.plugins.HttpTimeout +-dontwarn io.ktor.util.InternalAPI +-dontwarn io.ktor.utils.io.ByteReadChannelJVMKt +-dontwarn io.ktor.utils.io.CoroutinesKt +-dontwarn io.ktor.utils.io.core.ByteBuffersKt +-dontwarn io.ktor.utils.io.core.BytePacketBuilder +-dontwarn io.ktor.utils.io.core.ByteReadPacket$Companion +-dontwarn io.ktor.utils.io.core.ByteReadPacket +-dontwarn io.ktor.utils.io.core.CloseableJVMKt +-dontwarn io.ktor.utils.io.core.Input +-dontwarn io.ktor.utils.io.core.InputArraysKt +-dontwarn io.ktor.utils.io.core.InputPrimitivesKt +-dontwarn io.ktor.utils.io.core.Output +-dontwarn io.ktor.utils.io.core.OutputPrimitivesKt +-dontwarn io.ktor.utils.io.core.PreviewKt +-dontwarn okhttp3.internal.Util diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumKtorCustomLogging.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumKtorCustomLogging.kt index 417121b0b0a..0ab59e440b6 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumKtorCustomLogging.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumKtorCustomLogging.kt @@ -21,26 +21,24 @@ package com.wire.kalium.network import com.wire.kalium.logger.KaliumLogger import com.wire.kalium.network.utils.obfuscatePath import io.ktor.client.HttpClient -import io.ktor.client.HttpClientConfig import io.ktor.client.plugins.HttpClientPlugin import io.ktor.client.plugins.logging.DEFAULT import io.ktor.client.plugins.logging.LogLevel import io.ktor.client.plugins.logging.Logger import io.ktor.client.plugins.logging.Logging -import io.ktor.client.plugins.observer.ResponseHandler -import io.ktor.client.plugins.observer.ResponseObserver import io.ktor.client.request.HttpRequestBuilder import io.ktor.client.request.HttpSendPipeline import io.ktor.client.statement.HttpReceivePipeline import io.ktor.client.statement.HttpResponsePipeline +import io.ktor.client.statement.readRawBytes import io.ktor.http.Url import io.ktor.http.content.OutgoingContent import io.ktor.http.contentType import io.ktor.util.AttributeKey -import io.ktor.util.InternalAPI import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.charsets.Charset import io.ktor.utils.io.core.readText +import io.ktor.utils.io.readRemaining import kotlin.coroutines.cancellation.CancellationException private val KaliumHttpCustomLogger = AttributeKey("KaliumHttpLogger") @@ -120,7 +118,6 @@ class KaliumKtorCustomLogging private constructor( } } - @OptIn(InternalAPI::class) private fun setupResponseLogging(client: HttpClient) { client.receivePipeline.intercept(HttpReceivePipeline.State) { response -> if (level == LogLevel.NONE || response.call.attributes.contains(DisableLogging)) return@intercept @@ -157,20 +154,20 @@ class KaliumKtorCustomLogging private constructor( if (!level.body) return - val observer: ResponseHandler = observer@{ - if (level == LogLevel.NONE || it.call.attributes.contains(DisableLogging)) { - return@observer + client.receivePipeline.intercept(HttpReceivePipeline.After) { response -> + if (level == LogLevel.NONE || response.call.attributes.contains(DisableLogging)) { + return@intercept } - val logger = it.call.attributes[KaliumHttpCustomLogger] + val logger = response.call.attributes[KaliumHttpCustomLogger] + try { - logger.logResponseBody(it.contentType(), it.content) + logger.logResponseBody(response.contentType(), ByteReadChannel(response.readRawBytes())) } catch (_: Throwable) { } finally { logger.closeResponseLog() } } - ResponseObserver.install(ResponseObserver(observer), client) } private fun logRequest(request: HttpRequestBuilder): OutgoingContent? { @@ -214,14 +211,6 @@ class KaliumKtorCustomLogging private constructor( } } -/** - * Configure and install [Logging] in [HttpClient]. - */ -@Suppress("FunctionNaming") -fun HttpClientConfig<*>.Logging(block: Logging.Config.() -> Unit = {}) { - install(Logging, block) -} - @Suppress("TooGenericExceptionCaught") internal suspend inline fun ByteReadChannel.tryReadText(charset: Charset): String? = try { readRemaining().readText(charset = charset) diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumObservingUtils.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumObservingUtils.kt index 53d088a7df7..dcb58ec95bd 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumObservingUtils.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/KaliumObservingUtils.kt @@ -20,19 +20,19 @@ package com.wire.kalium.network import io.ktor.http.content.OutgoingContent import io.ktor.util.copyToBoth -import io.ktor.utils.io.ByteWriteChannel -import io.ktor.utils.io.close import io.ktor.utils.io.ByteChannel import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.ByteWriteChannel +import io.ktor.utils.io.writeFully import io.ktor.utils.io.writer -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope internal suspend fun OutgoingContent.observe(log: ByteWriteChannel): OutgoingContent = when (this) { is OutgoingContent.ByteArrayContent -> { log.writeFully(bytes(), 0, bytes().size) - log.close() + log.flushAndClose() this } is OutgoingContent.ReadChannelContent -> { @@ -49,7 +49,7 @@ internal suspend fun OutgoingContent.observe(log: ByteWriteChannel): OutgoingCon KaliumLoggedContent(this, responseChannel) } else -> { - log.close() + log.flushAndClose() this } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/NetworkClient.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/NetworkClient.kt index b358edc9809..163d674d483 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/NetworkClient.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/NetworkClient.kt @@ -44,6 +44,8 @@ import io.ktor.http.Url import io.ktor.http.appendPathSegments import io.ktor.serialization.kotlinx.json.json import io.ktor.websocket.WebSocketSession +import kotlin.time.Duration.Companion.milliseconds +import io.ktor.client.plugins.websocket.pingInterval /** * Provides a [HttpClient] that has all the @@ -146,7 +148,7 @@ internal class AuthenticatedWebSocketClient( install(WebSockets) { // Depending on the Engine (OkHttp for example), we might // need to set this value there too, as this here won't work - pingInterval = WEBSOCKET_PING_INTERVAL_MILLIS + pingInterval = WEBSOCKET_PING_INTERVAL_MILLIS.milliseconds } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/AssetApiV0.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/AssetApiV0.kt index 8846b60d209..947e873c2ca 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/AssetApiV0.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/AssetApiV0.kt @@ -47,6 +47,8 @@ import io.ktor.utils.io.close import io.ktor.utils.io.core.ByteReadPacket import io.ktor.utils.io.core.isNotEmpty import io.ktor.utils.io.core.readBytes +import io.ktor.utils.io.readRemaining +import io.ktor.utils.io.writePacket import io.ktor.utils.io.writeStringUtf8 import okio.Buffer import okio.Sink diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/NotificationApiV0.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/NotificationApiV0.kt index 35ff1c1a5a4..1109835dfa1 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/NotificationApiV0.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/NotificationApiV0.kt @@ -51,6 +51,8 @@ import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.http.HttpStatusCode import io.ktor.http.Url +import io.ktor.utils.io.CancellationException +import io.ktor.websocket.CloseReason import io.ktor.websocket.Frame import io.ktor.websocket.WebSocketSession import io.ktor.websocket.close @@ -149,10 +151,15 @@ internal open class NotificationApiV0 internal constructor( defaultClientWebSocketSession.incoming .consumeAsFlow() - .onCompletion { - defaultClientWebSocketSession.close() - logger.w("Websocket Closed", it) - emit(WebSocketEvent.Close(it)) + .onCompletion { cause -> + val closeReason = if (cause == null || cause is CancellationException) { + CloseReason(CloseReason.Codes.NORMAL, "Normal closure") + } else { + CloseReason(CloseReason.Codes.INTERNAL_ERROR, "Error: ${cause.message}") + } + defaultClientWebSocketSession.close(closeReason) + logger.w("Websocket Closed", cause) + emit(WebSocketEvent.Close(cause)) } .collect { frame -> logger.v("Websocket Received Frame: $frame") diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v9/authenticated/NotificationApiV9.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v9/authenticated/NotificationApiV9.kt index cc5316a96ae..fbe974f0b75 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v9/authenticated/NotificationApiV9.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v9/authenticated/NotificationApiV9.kt @@ -38,6 +38,8 @@ import com.wire.kalium.network.utils.setWSSUrl import com.wire.kalium.network.utils.wrapKaliumResponse import io.ktor.client.request.get import io.ktor.client.request.parameter +import io.ktor.utils.io.CancellationException +import io.ktor.websocket.CloseReason import io.ktor.websocket.Frame import io.ktor.websocket.WebSocketSession import io.ktor.websocket.close @@ -118,12 +120,17 @@ internal open class NotificationApiV9 internal constructor( defaultClientWebSocketSession.incoming .consumeAsFlow() - .onCompletion { + .onCompletion { cause -> defaultClientWebSocketSession.close() - logger.w("Websocket Closed", it) - session?.close(it) + logger.w("Websocket Closed", cause) + val closeReason = if (cause == null || cause is CancellationException) { + CloseReason(CloseReason.Codes.NORMAL, "Normal closure") + } else { + CloseReason(CloseReason.Codes.INTERNAL_ERROR, "Error: ${cause.message}") + } + session?.close(closeReason) session = null - emit(WebSocketEvent.Close(it)) + emit(WebSocketEvent.Close(cause)) } .collect { frame -> logger.v("Websocket Received Frame: $frame") diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/networkContainer/AuthenticatedNetworkContainer.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/networkContainer/AuthenticatedNetworkContainer.kt index c94b9a1bd48..37f598d3644 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/networkContainer/AuthenticatedNetworkContainer.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/networkContainer/AuthenticatedNetworkContainer.kt @@ -302,7 +302,7 @@ internal class AuthenticatedHttpClientProviderImpl( } val newSession = sessionManager.updateToken( accessTokenApi = accessTokenApi(client), - oldRefreshToken = oldTokens!!.refreshToken + oldRefreshToken = oldTokens!!.refreshToken ?: error("Old refresh token is null!") ) BearerTokens( accessToken = newSession.accessToken, diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/serialization/ByteArrayConverter.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/serialization/ByteArrayConverter.kt index 0c8e8801062..50fd580d5f3 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/serialization/ByteArrayConverter.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/serialization/ByteArrayConverter.kt @@ -24,9 +24,9 @@ import io.ktor.http.content.OutgoingContent import io.ktor.serialization.Configuration import io.ktor.serialization.ContentConverter import io.ktor.util.reflect.TypeInfo -import io.ktor.util.toByteArray import io.ktor.utils.io.ByteReadChannel import io.ktor.utils.io.charsets.Charset +import io.ktor.utils.io.toByteArray /** * A ContentConverter which does nothing, it simply passes byte arrays through as they are. This is useful @@ -38,7 +38,7 @@ class ByteArrayConverter : ContentConverter { return content.toByteArray() } - override suspend fun serializeNullable(contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any?): OutgoingContent? { + override suspend fun serialize(contentType: ContentType, charset: Charset, typeInfo: TypeInfo, value: Any?): OutgoingContent? { return ByteArrayContent(value as ByteArray, contentType) } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/session/SessionManager.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/session/SessionManager.kt index a039cedca8f..4b724f88a36 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/session/SessionManager.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/session/SessionManager.kt @@ -33,11 +33,11 @@ import io.ktor.client.utils.buildHeaders import io.ktor.http.HttpHeaders import io.ktor.http.HttpProtocolVersion import io.ktor.http.HttpStatusCode -import io.ktor.util.InternalAPI import io.ktor.util.date.GMTDate import io.ktor.utils.io.ByteReadChannel import io.mockative.Mockable import kotlin.coroutines.CoroutineContext +import io.ktor.utils.io.InternalAPI @Mockable interface SessionManager { @@ -83,7 +83,9 @@ private fun HttpClient.addWWWAuthenticateHeaderIfNeeded() { override val version: HttpProtocolVersion = response.version override val requestTime: GMTDate = response.requestTime override val responseTime: GMTDate = response.responseTime - override val content: ByteReadChannel = response.content + + @InternalAPI + override val rawContent: ByteReadChannel get() = response.rawContent override val headers get() = headers override val coroutineContext: CoroutineContext = response.coroutineContext } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/utils/NetworkUtils.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/utils/NetworkUtils.kt index 70fca9a902c..223d005632a 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/utils/NetworkUtils.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/utils/NetworkUtils.kt @@ -35,7 +35,7 @@ import io.ktor.http.Url internal fun HttpRequestBuilder.setWSSUrl(baseUrl: Url, vararg path: String) { url { host = baseUrl.host - pathSegments = baseUrl.pathSegments + path + pathSegments = baseUrl.rawSegments + path protocol = URLProtocol.WSS port = URLProtocol.WSS.defaultPort } @@ -53,7 +53,7 @@ internal fun HttpRequestBuilder.setUrl(baseUrl: String, vararg path: String) { private fun HttpRequestBuilder.setHttpsUrl(baseUrl: Url, path: List) { url { host = baseUrl.host - pathSegments = baseUrl.pathSegments + path + pathSegments = baseUrl.rawSegments + path protocol = URLProtocol.HTTPS } } diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/utils/ObfuscateUtil.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/utils/ObfuscateUtil.kt index 469300134e9..853f838efad 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/utils/ObfuscateUtil.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/utils/ObfuscateUtil.kt @@ -89,7 +89,7 @@ fun obfuscatePath(url: Url): String { var requestToLog = url.host - requestToLog += url.pathSegments.joinToString("/") { + requestToLog += url.rawSegments.joinToString("/") { it.obfuscateUrlPath() } diff --git a/network/src/commonTest/kotlin/com/wire/kalium/api/ApiTest.kt b/network/src/commonTest/kotlin/com/wire/kalium/api/ApiTest.kt index 58aa56ec85c..6fe26662e3b 100644 --- a/network/src/commonTest/kotlin/com/wire/kalium/api/ApiTest.kt +++ b/network/src/commonTest/kotlin/com/wire/kalium/api/ApiTest.kt @@ -72,7 +72,7 @@ internal abstract class ApiTest { get() = { val newSession = TEST_SESSION_MANAGER.updateToken( accessTokenApi = AccessTokenApiV0(client), - oldRefreshToken = oldTokens!!.refreshToken + oldRefreshToken = oldTokens!!.refreshToken ?: error("Old refresh token is null!") ) newSession.let { BearerTokens(accessToken = it.accessToken, refreshToken = it.refreshToken) diff --git a/network/src/commonTest/kotlin/com/wire/kalium/api/common/SessionManagerIntegrationTest.kt b/network/src/commonTest/kotlin/com/wire/kalium/api/common/SessionManagerIntegrationTest.kt index a4d44f7c09c..e9dcf3cf37d 100644 --- a/network/src/commonTest/kotlin/com/wire/kalium/api/common/SessionManagerIntegrationTest.kt +++ b/network/src/commonTest/kotlin/com/wire/kalium/api/common/SessionManagerIntegrationTest.kt @@ -72,7 +72,7 @@ class SessionManagerIntegrationTest { val refreshToken: suspend RefreshTokensParams.() -> BearerTokens? = { val newSession = sessionManager.updateToken( accessTokenApi = AccessTokenApiV0(client), - oldRefreshToken = oldTokens!!.refreshToken + oldRefreshToken = oldTokens!!.refreshToken ?: error("Old refresh token is null!") ) newSession.let { BearerTokens(accessToken = it.accessToken, refreshToken = it.refreshToken) @@ -118,7 +118,7 @@ class SessionManagerIntegrationTest { val refreshToken: suspend RefreshTokensParams.() -> BearerTokens? = { val newSession = sessionManager.updateToken( accessTokenApi = AccessTokenApiV0(client), - oldRefreshToken = oldTokens!!.refreshToken + oldRefreshToken = oldTokens!!.refreshToken ?: error("Old refresh token is null!") ) newSession.let { BearerTokens(accessToken = it.accessToken, refreshToken = it.refreshToken) @@ -156,7 +156,7 @@ class SessionManagerIntegrationTest { val refreshToken: suspend RefreshTokensParams.() -> BearerTokens? = { val newSession = sessionManager.updateToken( AccessTokenApiV0(client), - oldTokens!!.refreshToken + oldTokens!!.refreshToken ?: error("Old refresh token is null!") ) newSession.let { BearerTokens(accessToken = it.accessToken, refreshToken = it.refreshToken) diff --git a/network/src/commonTest/kotlin/com/wire/kalium/api/v0/user/client/ClientApiV0Test.kt b/network/src/commonTest/kotlin/com/wire/kalium/api/v0/user/client/ClientApiV0Test.kt index 59635e69549..a4b45bb315f 100644 --- a/network/src/commonTest/kotlin/com/wire/kalium/api/v0/user/client/ClientApiV0Test.kt +++ b/network/src/commonTest/kotlin/com/wire/kalium/api/v0/user/client/ClientApiV0Test.kt @@ -168,9 +168,9 @@ internal class ClientApiV0Test : ApiTest() { } ) val clientApi = ClientApiV0(networkClient) - clientApi.registerToken(VALID_PUSH_TOKEN_REQUEST.serializableData) val actual = clientApi.registerToken(VALID_PUSH_TOKEN_REQUEST.serializableData) + assertIs>(actual) assertTrue(actual.isSuccessful()) }