From 4400cd364344eacad8e162503ab8987fed95f6f9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Oct 2025 16:15:09 +0200 Subject: [PATCH 1/3] Extract code that log a ConsoleMessage so that it can be reused. --- .../features/call/impl/ui/CallScreenView.kt | 42 ++++--------- .../call/impl/ui/ElementCallActivity.kt | 5 ++ .../browser/ConsoleMessageLogger.kt | 61 +++++++++++++++++++ 3 files changed, 77 insertions(+), 31 deletions(-) create mode 100644 libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ConsoleMessageLogger.kt diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt index 88d2e81f8b..2f7a700794 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenView.kt @@ -8,7 +8,6 @@ package io.element.android.features.call.impl.ui import android.annotation.SuppressLint -import android.util.Log import android.view.ViewGroup import android.webkit.ConsoleMessage import android.webkit.JavascriptInterface @@ -60,6 +59,7 @@ interface CallScreenNavigator { internal fun CallScreenView( state: CallScreenState, pipState: PictureInPictureState, + onConsoleMessage: (ConsoleMessage) -> Unit, requestPermissions: (Array, RequestPermissionCallback) -> Unit, modifier: Modifier = Modifier, ) { @@ -108,6 +108,7 @@ internal fun CallScreenView( val callback: RequestPermissionCallback = { request.grant(it) } requestPermissions(androidPermissions.toTypedArray(), callback) }, + onConsoleMessage = onConsoleMessage, onCreateWebView = { webView -> webView.addBackHandler(onBackPressed = ::handleBack) val interceptor = WebViewWidgetMessageInterceptor( @@ -174,6 +175,7 @@ private fun CallWebView( url: AsyncData, userAgent: String, onPermissionsRequest: (PermissionRequest) -> Unit, + onConsoleMessage: (ConsoleMessage) -> Unit, onCreateWebView: (WebView) -> Unit, onDestroyWebView: (WebView) -> Unit, modifier: Modifier = Modifier, @@ -188,7 +190,11 @@ private fun CallWebView( factory = { context -> WebView(context).apply { onCreateWebView(this) - setup(userAgent, onPermissionsRequest) + setup( + userAgent = userAgent, + onPermissionsRequested = onPermissionsRequest, + onConsoleMessage = onConsoleMessage, + ) } }, update = { webView -> @@ -208,6 +214,7 @@ private fun CallWebView( private fun WebView.setup( userAgent: String, onPermissionsRequested: (PermissionRequest) -> Unit, + onConsoleMessage: (ConsoleMessage) -> Unit, ) { layoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, @@ -232,35 +239,7 @@ private fun WebView.setup( } override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean { - val priority = when (consoleMessage.messageLevel()) { - ConsoleMessage.MessageLevel.ERROR -> Log.ERROR - ConsoleMessage.MessageLevel.WARNING -> Log.WARN - else -> Log.DEBUG - } - - val message = buildString { - append(consoleMessage.sourceId()) - append(":") - append(consoleMessage.lineNumber()) - append(" ") - append(consoleMessage.message()) - } - - if (message.contains("password=")) { - // Avoid logging any messages that contain "password" to prevent leaking sensitive information - return true - } - - Timber.tag("WebView").log( - priority = priority, - message = buildString { - append(consoleMessage.sourceId()) - append(":") - append(consoleMessage.lineNumber()) - append(" ") - append(consoleMessage.message()) - }, - ) + onConsoleMessage(consoleMessage) return true } } @@ -286,6 +265,7 @@ internal fun CallScreenViewPreview( state = state, pipState = aPictureInPictureState(), requestPermissions = { _, _ -> }, + onConsoleMessage = {}, ) } diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt index bf210b0a42..ae04606d29 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/ElementCallActivity.kt @@ -42,6 +42,7 @@ import io.element.android.features.call.impl.pip.PipView import io.element.android.features.call.impl.services.CallForegroundService import io.element.android.features.call.impl.utils.CallIntentDataParser import io.element.android.features.enterprise.api.EnterpriseService +import io.element.android.libraries.androidutils.browser.ConsoleMessageLogger import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.bindings import io.element.android.libraries.audio.api.AudioFocus @@ -65,6 +66,7 @@ class ElementCallActivity : @Inject lateinit var pictureInPicturePresenter: PictureInPicturePresenter @Inject lateinit var buildMeta: BuildMeta @Inject lateinit var audioFocus: AudioFocus + @Inject lateinit var consoleMessageLogger: ConsoleMessageLogger private lateinit var presenter: Presenter @@ -119,6 +121,9 @@ class ElementCallActivity : CallScreenView( state = state, pipState = pipState, + onConsoleMessage = { + consoleMessageLogger.log("ElementCall", it) + }, requestPermissions = { permissions, callback -> requestPermissionCallback = callback requestPermissionsLauncher.launch(permissions) diff --git a/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ConsoleMessageLogger.kt b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ConsoleMessageLogger.kt new file mode 100644 index 0000000000..3c3cf24ebc --- /dev/null +++ b/libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/browser/ConsoleMessageLogger.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.androidutils.browser + +import android.util.Log +import android.webkit.ConsoleMessage +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.Inject +import timber.log.Timber + +interface ConsoleMessageLogger { + fun log( + tag: String, + consoleMessage: ConsoleMessage, + ) +} + +@ContributesBinding(AppScope::class) +@Inject +class DefaultConsoleMessageLogger : ConsoleMessageLogger { + override fun log( + tag: String, + consoleMessage: ConsoleMessage, + ) { + val priority = when (consoleMessage.messageLevel()) { + ConsoleMessage.MessageLevel.ERROR -> Log.ERROR + ConsoleMessage.MessageLevel.WARNING -> Log.WARN + else -> Log.DEBUG + } + + val message = buildString { + append(consoleMessage.sourceId()) + append(":") + append(consoleMessage.lineNumber()) + append(" ") + append(consoleMessage.message()) + } + + // Avoid logging any messages that contain "password" to prevent leaking sensitive information + if (message.contains("password=")) { + return + } + + Timber.tag(tag).log( + priority = priority, + message = buildString { + append(consoleMessage.sourceId()) + append(":") + append(consoleMessage.lineNumber()) + append(" ") + append(consoleMessage.message()) + }, + ) + } +} From 7c437761c494de1d1e50bfbd365116814aae5357 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Oct 2025 16:37:08 +0200 Subject: [PATCH 2/3] Move Json provider from Network module to AppModule to reuse it. --- .../main/kotlin/io/element/android/x/di/AppModule.kt | 7 +++++++ .../features/call/impl/ui/CallScreenPresenter.kt | 5 +++-- .../call/impl/utils/WidgetMessageSerializer.kt | 12 +++++++----- .../features/call/ui/CallScreenPresenterTest.kt | 6 +++++- .../impl/screens/createaccount/MessageParser.kt | 4 ++-- .../createaccount/DefaultMessageParserTest.kt | 4 +++- .../android/libraries/network/NetworkModule.kt | 7 ------- .../pushproviders/unifiedpush/UnifiedPushParser.kt | 6 +++--- .../impl/DefaultSessionWellknownRetriever.kt | 6 +++--- .../impl/DefaultSessionWellknownRetrieverTest.kt | 2 +- 10 files changed, 34 insertions(+), 25 deletions(-) diff --git a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt index d98a05321d..02f132d34a 100644 --- a/app/src/main/kotlin/io/element/android/x/di/AppModule.kt +++ b/app/src/main/kotlin/io/element/android/x/di/AppModule.kt @@ -35,6 +35,7 @@ import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.MainScope import kotlinx.coroutines.plus +import kotlinx.serialization.json.Json import java.io.File @BindingContainer @@ -120,4 +121,10 @@ object AppModule { fun providesEmojibaseProvider(@ApplicationContext context: Context): EmojibaseProvider { return DefaultEmojibaseProvider(context) } + + @Provides + @SingleIn(AppScope::class) + fun providesJson(): Json = Json { + ignoreUnknownKeys = true + } } diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt index 06929093f5..7604dbae18 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/ui/CallScreenPresenter.kt @@ -64,6 +64,7 @@ class CallScreenPresenter( private val appForegroundStateService: AppForegroundStateService, @AppCoroutineScope private val appCoroutineScope: CoroutineScope, + private val widgetMessageSerializer: WidgetMessageSerializer, ) : Presenter { @AssistedFactory interface Factory { @@ -258,7 +259,7 @@ class CallScreenPresenter( } private fun parseMessage(message: String): WidgetMessage? { - return WidgetMessageSerializer.deserialize(message).getOrNull() + return widgetMessageSerializer.deserialize(message).getOrNull() } private fun sendHangupMessage(widgetId: String, messageInterceptor: WidgetMessageInterceptor) { @@ -269,7 +270,7 @@ class CallScreenPresenter( action = WidgetMessage.Action.HangUp, data = null, ) - messageInterceptor.sendMessage(WidgetMessageSerializer.serialize(message)) + messageInterceptor.sendMessage(widgetMessageSerializer.serialize(message)) } private fun CoroutineScope.close(widgetDriver: MatrixWidgetDriver?, navigator: CallScreenNavigator) = launch(dispatchers.io) { diff --git a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WidgetMessageSerializer.kt b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WidgetMessageSerializer.kt index a21cadab7a..2beaea7061 100644 --- a/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WidgetMessageSerializer.kt +++ b/features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WidgetMessageSerializer.kt @@ -7,18 +7,20 @@ package io.element.android.features.call.impl.utils +import dev.zacsweers.metro.Inject import io.element.android.features.call.impl.data.WidgetMessage import io.element.android.libraries.core.extensions.runCatchingExceptions import kotlinx.serialization.json.Json -object WidgetMessageSerializer { - private val coder = Json { ignoreUnknownKeys = true } - +@Inject +class WidgetMessageSerializer( + private val json: Json, +) { fun deserialize(message: String): Result { - return runCatchingExceptions { coder.decodeFromString(WidgetMessage.serializer(), message) } + return runCatchingExceptions { json.decodeFromString(WidgetMessage.serializer(), message) } } fun serialize(message: WidgetMessage): String { - return coder.encodeToString(WidgetMessage.serializer(), message) + return json.encodeToString(WidgetMessage.serializer(), message) } } diff --git a/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt b/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt index 47a91afa1c..c3a68994da 100644 --- a/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt +++ b/features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt @@ -16,6 +16,7 @@ import io.element.android.features.call.api.CallType import io.element.android.features.call.impl.ui.CallScreenEvents import io.element.android.features.call.impl.ui.CallScreenNavigator import io.element.android.features.call.impl.ui.CallScreenPresenter +import io.element.android.features.call.impl.utils.WidgetMessageSerializer import io.element.android.features.call.utils.FakeActiveCallManager import io.element.android.features.call.utils.FakeCallWidgetProvider import io.element.android.features.call.utils.FakeWidgetMessageInterceptor @@ -46,11 +47,13 @@ import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.advanceTimeBy import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest +import kotlinx.serialization.json.Json import org.junit.Rule import org.junit.Test import kotlin.time.Duration.Companion.seconds -@OptIn(ExperimentalCoroutinesApi::class) class CallScreenPresenterTest { +@OptIn(ExperimentalCoroutinesApi::class) +class CallScreenPresenterTest { @get:Rule val warmUpRule = WarmUpRule() @@ -409,6 +412,7 @@ import kotlin.time.Duration.Companion.seconds languageTagProvider = FakeLanguageTagProvider("en-US"), appForegroundStateService = appForegroundStateService, appCoroutineScope = backgroundScope, + widgetMessageSerializer = WidgetMessageSerializer(Json { ignoreUnknownKeys = true }), ) } } diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/MessageParser.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/MessageParser.kt index 8450aef1d3..8762bc5e46 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/MessageParser.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/createaccount/MessageParser.kt @@ -26,10 +26,10 @@ interface MessageParser { @Inject class DefaultMessageParser( private val accountProviderDataSource: AccountProviderDataSource, + private val json: Json, ) : MessageParser { override fun parse(message: String): ExternalSession { - val parser = Json { ignoreUnknownKeys = true } - val response = parser.decodeFromString(MobileRegistrationResponse.serializer(), message) + val response = json.decodeFromString(MobileRegistrationResponse.serializer(), message) val userId = response.userId ?: error("No user ID in response") val homeServer = response.homeServer ?: accountProviderDataSource.flow.value.url val accessToken = response.accessToken ?: error("No access token in response") diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/DefaultMessageParserTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/DefaultMessageParserTest.kt index a1fbbc0fe2..fa97a2b1fc 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/DefaultMessageParserTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/createaccount/DefaultMessageParserTest.kt @@ -13,6 +13,7 @@ import io.element.android.features.enterprise.test.FakeEnterpriseService import io.element.android.features.login.impl.accountprovider.AccountProviderDataSource import io.element.android.libraries.matrix.api.auth.external.ExternalSession import kotlinx.serialization.SerializationException +import kotlinx.serialization.json.Json import org.junit.Assert.assertThrows import org.junit.Test @@ -68,7 +69,8 @@ class DefaultMessageParserTest { private fun createDefaultMessageParser(): DefaultMessageParser { return DefaultMessageParser( - AccountProviderDataSource(FakeEnterpriseService()) + accountProviderDataSource = AccountProviderDataSource(FakeEnterpriseService()), + json = Json { ignoreUnknownKeys = true }, ) } } diff --git a/libraries/network/src/main/kotlin/io/element/android/libraries/network/NetworkModule.kt b/libraries/network/src/main/kotlin/io/element/android/libraries/network/NetworkModule.kt index 6ede5a0c48..b749ebec39 100644 --- a/libraries/network/src/main/kotlin/io/element/android/libraries/network/NetworkModule.kt +++ b/libraries/network/src/main/kotlin/io/element/android/libraries/network/NetworkModule.kt @@ -15,7 +15,6 @@ import dev.zacsweers.metro.SingleIn import io.element.android.libraries.core.meta.BuildMeta import io.element.android.libraries.network.interceptors.FormattedJsonHttpLogger import io.element.android.libraries.network.interceptors.UserAgentInterceptor -import kotlinx.serialization.json.Json import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import java.util.concurrent.TimeUnit @@ -35,12 +34,6 @@ object NetworkModule { addInterceptor(userAgentInterceptor) if (buildMeta.isDebuggable) addInterceptor(providesHttpLoggingInterceptor()) }.build() - - @Provides - @SingleIn(AppScope::class) - fun providesJson(): Json = Json { - ignoreUnknownKeys = true - } } private fun providesHttpLoggingInterceptor(): HttpLoggingInterceptor { diff --git a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParser.kt b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParser.kt index f1290636c3..14a0bf3e85 100644 --- a/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParser.kt +++ b/libraries/pushproviders/unifiedpush/src/main/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParser.kt @@ -13,9 +13,9 @@ import io.element.android.libraries.pushproviders.api.PushData import kotlinx.serialization.json.Json @Inject -class UnifiedPushParser { - private val json by lazy { Json { ignoreUnknownKeys = true } } - +class UnifiedPushParser( + private val json: Json, +) { fun parse(message: ByteArray, clientSecret: String): PushData? { return tryOrNull { json.decodeFromString(String(message)) }?.toPushData(clientSecret) } diff --git a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetriever.kt b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetriever.kt index 81bbab5ab8..c34a0a12d3 100644 --- a/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetriever.kt +++ b/libraries/wellknown/impl/src/main/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetriever.kt @@ -22,7 +22,7 @@ import timber.log.Timber @Inject class DefaultSessionWellknownRetriever( private val matrixClient: MatrixClient, - private val parser: Json, + private val json: Json, ) : SessionWellknownRetriever { private val domain by lazy { matrixClient.userIdServerName() } @@ -32,7 +32,7 @@ class DefaultSessionWellknownRetriever( .getUrl(url) .mapCatchingExceptions { val data = String(it) - parser.decodeFromString(InternalWellKnown.serializer(), data) + json.decodeFromString(InternalWellKnown.serializer(), data) } .onFailure { Timber.e(it, "Failed to retrieve .well-known from $domain") } .map { it.map() } @@ -45,7 +45,7 @@ class DefaultSessionWellknownRetriever( .getUrl(url) .mapCatchingExceptions { val data = String(it) - parser.decodeFromString(InternalElementWellKnown.serializer(), data) + json.decodeFromString(InternalElementWellKnown.serializer(), data) } .onFailure { Timber.e(it, "Failed to retrieve Element .well-known from $domain") } .map { it.map() } diff --git a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt index 624370466a..2c788cae63 100644 --- a/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt +++ b/libraries/wellknown/impl/src/test/kotlin/io/element/android/libraries/wellknown/impl/DefaultSessionWellknownRetrieverTest.kt @@ -244,6 +244,6 @@ class DefaultSessionWellknownRetrieverTest { userIdServerNameLambda = { "user.domain.org" }, getUrlLambda = getUrlLambda, ), - parser = Json { ignoreUnknownKeys = true } + json = Json { ignoreUnknownKeys = true }, ) } From b01de9efa76ab5537851cfb11d030ce5dad380bf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 16 Oct 2025 18:15:01 +0200 Subject: [PATCH 3/3] Fix tests. --- .../unifiedpush/UnifiedPushParserTest.kt | 19 +++++++++++++------ .../VectorUnifiedPushMessagingReceiverTest.kt | 3 ++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParserTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParserTest.kt index 89d4fec3b2..a269f906fe 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParserTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/UnifiedPushParserTest.kt @@ -12,6 +12,7 @@ import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.pushproviders.api.PushData import io.element.android.tests.testutils.assertThrowsInDebug +import kotlinx.serialization.json.Json import org.junit.Test class UnifiedPushParserTest { @@ -25,7 +26,7 @@ class UnifiedPushParserTest { @Test fun `test edge cases UnifiedPush`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() // Empty string assertThat(pushParser.parse("".toByteArray(), aClientSecret)).isNull() // Empty Json @@ -36,13 +37,13 @@ class UnifiedPushParserTest { @Test fun `test UnifiedPush format`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() assertThat(pushParser.parse(UNIFIED_PUSH_DATA.toByteArray(), aClientSecret)).isEqualTo(validData) } @Test fun `test empty roomId`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() assertThrowsInDebug { pushParser.parse(UNIFIED_PUSH_DATA.replace(A_ROOM_ID.value, "").toByteArray(), aClientSecret) } @@ -50,7 +51,7 @@ class UnifiedPushParserTest { @Test fun `test invalid roomId`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() assertThrowsInDebug { pushParser.parse(UNIFIED_PUSH_DATA.mutate(A_ROOM_ID.value, "aRoomId:domain"), aClientSecret) } @@ -58,7 +59,7 @@ class UnifiedPushParserTest { @Test fun `test empty eventId`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() assertThrowsInDebug { pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, ""), aClientSecret) } @@ -66,7 +67,7 @@ class UnifiedPushParserTest { @Test fun `test invalid eventId`() { - val pushParser = UnifiedPushParser() + val pushParser = createUnifiedPushParser() assertThrowsInDebug { pushParser.parse(UNIFIED_PUSH_DATA.mutate(AN_EVENT_ID.value, "anEventId"), aClientSecret) } @@ -81,3 +82,9 @@ class UnifiedPushParserTest { private fun String.mutate(oldValue: String, newValue: String): ByteArray { return replace(oldValue, newValue).toByteArray() } + +fun createUnifiedPushParser( + json: Json = Json { ignoreUnknownKeys = true }, +) = UnifiedPushParser( + json = json, +) diff --git a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt index 0215ff66ee..5465149642 100644 --- a/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt +++ b/libraries/pushproviders/unifiedpush/src/test/kotlin/io/element/android/libraries/pushproviders/unifiedpush/VectorUnifiedPushMessagingReceiverTest.kt @@ -191,6 +191,7 @@ class VectorUnifiedPushMessagingReceiverTest { } private fun TestScope.createVectorUnifiedPushMessagingReceiver( + unifiedPushParser: UnifiedPushParser = createUnifiedPushParser(), pushHandler: PushHandler = FakePushHandler(), unifiedPushStore: UnifiedPushStore = FakeUnifiedPushStore(), unifiedPushGatewayResolver: UnifiedPushGatewayResolver = FakeUnifiedPushGatewayResolver(), @@ -199,7 +200,7 @@ class VectorUnifiedPushMessagingReceiverTest { endpointRegistrationHandler: EndpointRegistrationHandler = EndpointRegistrationHandler(), ): VectorUnifiedPushMessagingReceiver { return VectorUnifiedPushMessagingReceiver().apply { - this.pushParser = UnifiedPushParser() + this.pushParser = unifiedPushParser this.pushHandler = pushHandler this.guardServiceStarter = NoopGuardServiceStarter() this.unifiedPushStore = unifiedPushStore