From 6acc86641ac72ba79ba49abccc6fa24f18912afd Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 May 2024 15:46:04 +0200 Subject: [PATCH 1/6] Make AnalyticsStore an interface and create DefaultAnalyticsStore --- .../analytics/impl/store/AnalyticsStore.kt | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/store/AnalyticsStore.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/store/AnalyticsStore.kt index 5e9b0d88ef..b866af42b1 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/store/AnalyticsStore.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/store/AnalyticsStore.kt @@ -23,7 +23,9 @@ import androidx.datastore.preferences.core.booleanPreferencesKey import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore +import com.squareup.anvil.annotations.ContributesBinding import io.element.android.libraries.core.bool.orFalse +import io.element.android.libraries.di.AppScope import io.element.android.libraries.di.ApplicationContext import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.distinctUntilChanged @@ -41,44 +43,55 @@ private val Context.dataStore: DataStore by preferencesDataStore(na * - did ask user consent (Boolean); * - analytics Id (String). */ -class AnalyticsStore @Inject constructor( +interface AnalyticsStore { + val userConsentFlow: Flow + val didAskUserConsentFlow: Flow + val analyticsIdFlow: Flow + suspend fun setUserConsent(newUserConsent: Boolean) + suspend fun setDidAskUserConsent(newValue: Boolean = true) + suspend fun setAnalyticsId(newAnalyticsId: String) + suspend fun reset() +} + +@ContributesBinding(AppScope::class) +class DefaultAnalyticsStore @Inject constructor( @ApplicationContext private val context: Context -) { +) : AnalyticsStore { private val userConsent = booleanPreferencesKey("user_consent") private val didAskUserConsent = booleanPreferencesKey("did_ask_user_consent") private val analyticsId = stringPreferencesKey("analytics_id") - val userConsentFlow: Flow = context.dataStore.data + override val userConsentFlow: Flow = context.dataStore.data .map { preferences -> preferences[userConsent].orFalse() } .distinctUntilChanged() - val didAskUserConsentFlow: Flow = context.dataStore.data + override val didAskUserConsentFlow: Flow = context.dataStore.data .map { preferences -> preferences[didAskUserConsent].orFalse() } .distinctUntilChanged() - val analyticsIdFlow: Flow = context.dataStore.data + override val analyticsIdFlow: Flow = context.dataStore.data .map { preferences -> preferences[analyticsId].orEmpty() } .distinctUntilChanged() - suspend fun setUserConsent(newUserConsent: Boolean) { + override suspend fun setUserConsent(newUserConsent: Boolean) { context.dataStore.edit { settings -> settings[userConsent] = newUserConsent } } - suspend fun setDidAskUserConsent(newValue: Boolean = true) { + override suspend fun setDidAskUserConsent(newValue: Boolean) { context.dataStore.edit { settings -> settings[didAskUserConsent] = newValue } } - suspend fun setAnalyticsId(newAnalyticsId: String) { + override suspend fun setAnalyticsId(newAnalyticsId: String) { context.dataStore.edit { settings -> settings[analyticsId] = newAnalyticsId } } - suspend fun reset() { + override suspend fun reset() { context.dataStore.edit { it.clear() } From d4e6b4fa1d263e20c97c5d5167ae761cdb3c1152 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 May 2024 17:36:24 +0200 Subject: [PATCH 2/6] Remove dead code `AnalyticsService.onSignOut`. DefaultAnalyticsService is observing the Session. --- .../android/services/analytics/api/AnalyticsService.kt | 5 ----- .../services/analytics/impl/DefaultAnalyticsService.kt | 5 ----- .../android/services/analytics/noop/NoopAnalyticsService.kt | 1 - 3 files changed, 11 deletions(-) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 8d904e2743..b09d8bd3be 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -57,11 +57,6 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { */ suspend fun setAnalyticsId(analyticsId: String) - /** - * To be called when a session is destroyed. - */ - suspend fun onSignOut() - /** * Reset the analytics service (will ask for user consent again). */ diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index 42acd29b56..e828d4c7ee 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -91,11 +91,6 @@ class DefaultAnalyticsService @Inject constructor( analyticsStore.setAnalyticsId(analyticsId) } - override suspend fun onSignOut() { - // stop all providers - analyticsProviders.onEach { it.stop() } - } - override suspend fun onSessionCreated(userId: String) { // Nothing to do } diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt index ed18d2bd9a..54246b0269 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt @@ -38,7 +38,6 @@ class NoopAnalyticsService @Inject constructor() : AnalyticsService { override suspend fun setDidAskUserConsent() = Unit override fun getAnalyticsId(): Flow = flowOf("") override suspend fun setAnalyticsId(analyticsId: String) = Unit - override suspend fun onSignOut() = Unit override suspend fun reset() = Unit override fun capture(event: VectorAnalyticsEvent) = Unit override fun screen(screen: VectorAnalyticsScreen) = Unit From d4ea1da7295be6690d97cfe55cd1216f122d4144 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 28 May 2024 17:35:48 +0200 Subject: [PATCH 3/6] Add test on DefaultAnalyticsService --- services/analytics/impl/build.gradle.kts | 6 +- .../impl/DefaultAnalyticsServiceTest.kt | 286 ++++++++++++++++++ .../impl/store/FakeAnalyticsStore.kt | 47 +++ .../analyticsproviders/test/build.gradle.kts | 27 ++ .../test/FakeAnalyticsProvider.kt | 41 +++ 5 files changed, 406 insertions(+), 1 deletion(-) create mode 100644 services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt create mode 100644 services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/store/FakeAnalyticsStore.kt create mode 100644 services/analyticsproviders/test/build.gradle.kts create mode 100644 services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt diff --git a/services/analytics/impl/build.gradle.kts b/services/analytics/impl/build.gradle.kts index 623ab493c3..4cecbc2c85 100644 --- a/services/analytics/impl/build.gradle.kts +++ b/services/analytics/impl/build.gradle.kts @@ -43,5 +43,9 @@ dependencies { implementation(libs.androidx.datastore.preferences) testImplementation(libs.coroutines.test) - testImplementation(libs.test.mockk) + testImplementation(libs.test.junit) + testImplementation(libs.test.truth) + testImplementation(projects.libraries.sessionStorage.test) + testImplementation(projects.services.analyticsproviders.test) + testImplementation(projects.tests.testutils) } diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt new file mode 100644 index 0000000000..89946f0ffb --- /dev/null +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +@file:OptIn(ExperimentalCoroutinesApi::class) + +package io.element.android.services.analytics.impl + +import com.google.common.truth.Truth.assertThat +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent +import im.vector.app.features.analytics.itf.VectorAnalyticsScreen +import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.analytics.plan.PollEnd +import im.vector.app.features.analytics.plan.UserProperties +import io.element.android.libraries.sessionstorage.api.observer.SessionObserver +import io.element.android.libraries.sessionstorage.test.observer.NoOpSessionObserver +import io.element.android.services.analytics.impl.store.AnalyticsStore +import io.element.android.services.analytics.impl.store.FakeAnalyticsStore +import io.element.android.services.analyticsproviders.api.AnalyticsProvider +import io.element.android.services.analyticsproviders.test.FakeAnalyticsProvider +import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.runCancellableScopeTest +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class DefaultAnalyticsServiceTest { + @Test + fun `getAvailableAnalyticsProviders return the set of provider`() = runCancellableScopeTest { + val providers = setOf( + FakeAnalyticsProvider(name = "provider1", stopLambda = { }), + FakeAnalyticsProvider(name = "provider2", stopLambda = { }), + ) + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsProviders = providers + ) + val result = sut.getAvailableAnalyticsProviders() + assertThat(result).isEqualTo(providers) + } + + @Test + fun `when consent is not provided, capture is no op`() = runCancellableScopeTest { + val sut = createDefaultAnalyticsService(it) + sut.capture(anEvent) + } + + @Test + fun `when consent is provided, capture is sent to the AnalyticsProvider`() = runCancellableScopeTest { + val initLambda = lambdaRecorder { } + val captureLambda = lambdaRecorder { _ -> } + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = FakeAnalyticsStore(defaultUserConsent = true), + analyticsProviders = setOf( + FakeAnalyticsProvider( + initLambda = initLambda, + captureLambda = captureLambda, + ) + ) + ) + initLambda.assertions().isCalledOnce() + sut.capture(anEvent) + captureLambda.assertions().isCalledOnce().with(value(anEvent)) + } + + @Test + fun `when consent is not provided, screen is no op`() = runCancellableScopeTest { + val sut = createDefaultAnalyticsService(it) + sut.screen(aScreen) + } + + @Test + fun `when consent is provided, screen is sent to the AnalyticsProvider`() = runCancellableScopeTest { + val initLambda = lambdaRecorder { } + val screenLambda = lambdaRecorder { _ -> } + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = FakeAnalyticsStore(defaultUserConsent = true), + analyticsProviders = setOf( + FakeAnalyticsProvider( + initLambda = initLambda, + screenLambda = screenLambda, + ) + ) + ) + initLambda.assertions().isCalledOnce() + sut.screen(aScreen) + screenLambda.assertions().isCalledOnce().with(value(aScreen)) + } + + @Test + fun `when consent is not provided, trackError is no op`() = runCancellableScopeTest { + val sut = createDefaultAnalyticsService(it) + sut.trackError(anError) + } + + @Test + fun `when consent is provided, trackError is sent to the AnalyticsProvider`() = runCancellableScopeTest { + val initLambda = lambdaRecorder { } + val trackErrorLambda = lambdaRecorder { _ -> } + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = FakeAnalyticsStore(defaultUserConsent = true), + analyticsProviders = setOf( + FakeAnalyticsProvider( + initLambda = initLambda, + trackErrorLambda = trackErrorLambda, + ) + ) + ) + initLambda.assertions().isCalledOnce() + sut.trackError(anError) + trackErrorLambda.assertions().isCalledOnce().with(value(anError)) + } + + @Test + fun `setUserConsent is sent to the store`() = runCancellableScopeTest { + val store = FakeAnalyticsStore() + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = store, + ) + assertThat(store.userConsentFlow.first()).isFalse() + assertThat(sut.getUserConsent().first()).isFalse() + sut.setUserConsent(true) + assertThat(store.userConsentFlow.first()).isTrue() + assertThat(sut.getUserConsent().first()).isTrue() + } + + @Test + fun `setAnalyticsId is sent to the store`() = runCancellableScopeTest { + val store = FakeAnalyticsStore() + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = store, + ) + assertThat(store.analyticsIdFlow.first()).isEqualTo("") + assertThat(sut.getAnalyticsId().first()).isEqualTo("") + sut.setAnalyticsId(anId) + assertThat(store.analyticsIdFlow.first()).isEqualTo(anId) + assertThat(sut.getAnalyticsId().first()).isEqualTo(anId) + } + + @Test + fun `setDidAskUserConsent is sent to the store`() = runCancellableScopeTest { + val store = FakeAnalyticsStore() + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = store, + ) + assertThat(store.didAskUserConsentFlow.first()).isFalse() + assertThat(sut.didAskUserConsent().first()).isFalse() + sut.setDidAskUserConsent() + assertThat(store.didAskUserConsentFlow.first()).isTrue() + assertThat(sut.didAskUserConsent().first()).isTrue() + } + + @Test + fun `when a session is deleted, the store is reset`() = runCancellableScopeTest { + val resetLambda = lambdaRecorder { } + val store = FakeAnalyticsStore( + resetLambda = resetLambda, + ) + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = store, + ) + sut.onSessionDeleted("userId") + resetLambda.assertions().isCalledOnce() + } + + @Test + fun `when reset is invoked, the user consent is reset`() = runCancellableScopeTest { + val store = FakeAnalyticsStore( + defaultDidAskUserConsent = true, + ) + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsStore = store, + ) + assertThat(store.didAskUserConsentFlow.first()).isTrue() + sut.reset() + assertThat(store.didAskUserConsentFlow.first()).isFalse() + } + + @Test + fun `when a session is added, nothing happen`() = runCancellableScopeTest { + val sut = createDefaultAnalyticsService( + coroutineScope = it, + ) + sut.onSessionCreated("userId") + } + + @Test + fun `when consent is not provided, updateUserProperties is stored for future use`() = runTest { + val completable = CompletableDeferred() + val updateUserPropertiesLambda = lambdaRecorder { _ -> + completable.complete(Unit) + } + launch { + val sut = createDefaultAnalyticsService( + coroutineScope = this, + analyticsProviders = setOf( + FakeAnalyticsProvider( + initLambda = { }, + stopLambda = { }, + updateUserPropertiesLambda = updateUserPropertiesLambda, + ) + ) + ) + sut.updateUserProperties(aUserProperty) + updateUserPropertiesLambda.assertions().isNeverCalled() + // Give user consent + sut.setUserConsent(true) + completable.await() + updateUserPropertiesLambda.assertions().isCalledOnce().with(value(aUserProperty)) + cancel() + } + } + + @Test + fun `when consent is provided, updateUserProperties is sent to the provider`() = runCancellableScopeTest { + val updateUserPropertiesLambda = lambdaRecorder { _ -> } + val sut = createDefaultAnalyticsService( + coroutineScope = it, + analyticsProviders = setOf( + FakeAnalyticsProvider( + initLambda = { }, + updateUserPropertiesLambda = updateUserPropertiesLambda, + ) + ), + analyticsStore = FakeAnalyticsStore(defaultUserConsent = true), + ) + sut.updateUserProperties(aUserProperty) + updateUserPropertiesLambda.assertions().isCalledOnce().with(value(aUserProperty)) + } + + private suspend fun createDefaultAnalyticsService( + coroutineScope: CoroutineScope, + analyticsProviders: Set<@JvmSuppressWildcards AnalyticsProvider> = setOf( + FakeAnalyticsProvider( + stopLambda = { }, + ) + ), + analyticsStore: AnalyticsStore = FakeAnalyticsStore(), + sessionObserver: SessionObserver = NoOpSessionObserver(), + ) = DefaultAnalyticsService( + analyticsProviders = analyticsProviders, + analyticsStore = analyticsStore, + coroutineScope = coroutineScope, + sessionObserver = sessionObserver, + ).also { + // Wait for the service to be ready + delay(1) + } + + private companion object { + private val anEvent = PollEnd() + private val aScreen = MobileScreen(screenName = MobileScreen.ScreenName.User) + private val aUserProperty = UserProperties( + ftueUseCaseSelection = UserProperties.FtueUseCaseSelection.WorkMessaging, + ) + private val anError = Exception("a reason") + private val anId = "anId" + } +} diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/store/FakeAnalyticsStore.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/store/FakeAnalyticsStore.kt new file mode 100644 index 0000000000..8453f1c1b6 --- /dev/null +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/store/FakeAnalyticsStore.kt @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.analytics.impl.store + +import io.element.android.tests.testutils.lambda.lambdaError +import kotlinx.coroutines.flow.MutableStateFlow + +class FakeAnalyticsStore( + defaultUserConsent: Boolean = false, + defaultDidAskUserConsent: Boolean = false, + defaultAnalyticsId: String = "", + private val resetLambda: () -> Unit = { lambdaError() }, +) : AnalyticsStore { + override val userConsentFlow = MutableStateFlow(defaultUserConsent) + override val didAskUserConsentFlow = MutableStateFlow(defaultDidAskUserConsent) + override val analyticsIdFlow = MutableStateFlow(defaultAnalyticsId) + + override suspend fun setUserConsent(newUserConsent: Boolean) { + userConsentFlow.emit(newUserConsent) + } + + override suspend fun setDidAskUserConsent(newValue: Boolean) { + didAskUserConsentFlow.emit(newValue) + } + + override suspend fun setAnalyticsId(newAnalyticsId: String) { + analyticsIdFlow.emit(newAnalyticsId) + } + + override suspend fun reset() { + resetLambda() + } +} diff --git a/services/analyticsproviders/test/build.gradle.kts b/services/analyticsproviders/test/build.gradle.kts new file mode 100644 index 0000000000..14545c866c --- /dev/null +++ b/services/analyticsproviders/test/build.gradle.kts @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.services.analyticsproviders.test" +} + +dependencies { + implementation(projects.services.analyticsproviders.api) + implementation(projects.tests.testutils) +} diff --git a/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt new file mode 100644 index 0000000000..92665ceb86 --- /dev/null +++ b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.services.analyticsproviders.test + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent +import im.vector.app.features.analytics.itf.VectorAnalyticsScreen +import im.vector.app.features.analytics.plan.UserProperties + +import io.element.android.services.analyticsproviders.api.AnalyticsProvider +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeAnalyticsProvider( + override val name: String = "FakeAnalyticsProvider", + private val initLambda: () -> Unit = { lambdaError() }, + private val stopLambda: () -> Unit = { lambdaError() }, + private val captureLambda: (VectorAnalyticsEvent) -> Unit = { lambdaError() }, + private val screenLambda: (VectorAnalyticsScreen) -> Unit = { lambdaError() }, + private val updateUserPropertiesLambda: (UserProperties) -> Unit = { lambdaError() }, + private val trackErrorLambda: (Throwable) -> Unit = { lambdaError() } +) : AnalyticsProvider { + override fun init() = initLambda() + override fun stop() = stopLambda() + override fun capture(event: VectorAnalyticsEvent) = captureLambda(event) + override fun screen(screen: VectorAnalyticsScreen) = screenLambda(screen) + override fun updateUserProperties(userProperties: UserProperties) = updateUserPropertiesLambda(userProperties) + override fun trackError(throwable: Throwable) = trackErrorLambda(throwable) +} From 04cd2bf8f52b204d19b1f28a28337d5a2b885260 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 29 May 2024 00:30:38 +0200 Subject: [PATCH 4/6] Fix compilation issue --- .../android/services/analytics/test/FakeAnalyticsService.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index 2d9f320422..35ca5c7904 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -54,9 +54,6 @@ class FakeAnalyticsService( override suspend fun setAnalyticsId(analyticsId: String) { } - override suspend fun onSignOut() { - } - override fun capture(event: VectorAnalyticsEvent) { capturedEvents += event } From d4f651eeda09ad794eb7001fde6e378ff177e07d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 29 May 2024 00:35:47 +0200 Subject: [PATCH 5/6] Make anId a const. --- .../analytics/impl/DefaultAnalyticsServiceTest.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt index 89946f0ffb..5b685b6c16 100644 --- a/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsServiceTest.kt @@ -156,9 +156,9 @@ class DefaultAnalyticsServiceTest { ) assertThat(store.analyticsIdFlow.first()).isEqualTo("") assertThat(sut.getAnalyticsId().first()).isEqualTo("") - sut.setAnalyticsId(anId) - assertThat(store.analyticsIdFlow.first()).isEqualTo(anId) - assertThat(sut.getAnalyticsId().first()).isEqualTo(anId) + sut.setAnalyticsId(AN_ID) + assertThat(store.analyticsIdFlow.first()).isEqualTo(AN_ID) + assertThat(sut.getAnalyticsId().first()).isEqualTo(AN_ID) } @Test @@ -281,6 +281,6 @@ class DefaultAnalyticsServiceTest { ftueUseCaseSelection = UserProperties.FtueUseCaseSelection.WorkMessaging, ) private val anError = Exception("a reason") - private val anId = "anId" + private const val AN_ID = "anId" } } From 9d50ef06a2ec65d3bae3f4551ec0a88b13ee2e97 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 29 May 2024 01:54:06 +0200 Subject: [PATCH 6/6] Cleanup import --- .../services/analyticsproviders/test/FakeAnalyticsProvider.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt index 92665ceb86..fcbfc4112f 100644 --- a/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt +++ b/services/analyticsproviders/test/src/main/kotlin/io/element/android/services/analyticsproviders/test/FakeAnalyticsProvider.kt @@ -19,7 +19,6 @@ package io.element.android.services.analyticsproviders.test import im.vector.app.features.analytics.itf.VectorAnalyticsEvent import im.vector.app.features.analytics.itf.VectorAnalyticsScreen import im.vector.app.features.analytics.plan.UserProperties - import io.element.android.services.analyticsproviders.api.AnalyticsProvider import io.element.android.tests.testutils.lambda.lambdaError