Merge pull request #5388 from element-hq/feature/bma/fixIssueOnFtueNotificationScreen
Change in clear cache behavior
This commit is contained in:
commit
8dee4d0137
15 changed files with 1 additions and 114 deletions
|
|
@ -15,9 +15,6 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
interface FtueService {
|
interface FtueService {
|
||||||
/** The current state of the FTUE. */
|
/** The current state of the FTUE. */
|
||||||
val state: StateFlow<FtueState>
|
val state: StateFlow<FtueState>
|
||||||
|
|
||||||
/** Reset the FTUE state. */
|
|
||||||
suspend fun reset()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The state of the FTUE. */
|
/** The state of the FTUE. */
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,6 @@ class DefaultFtueService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun reset() {
|
|
||||||
analyticsService.reset()
|
|
||||||
if (sdkVersionProvider.isAtLeast(Build.VERSION_CODES.TIRAMISU)) {
|
|
||||||
permissionStateProvider.resetPermission(Manifest.permission.POST_NOTIFICATIONS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
combine(
|
combine(
|
||||||
sessionVerificationService.sessionVerifiedStatus.onEach { sessionVerifiedStatus ->
|
sessionVerificationService.sessionVerifiedStatus.onEach { sessionVerifiedStatus ->
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import io.element.android.services.analytics.noop.NoopAnalyticsService
|
import io.element.android.services.analytics.noop.NoopAnalyticsService
|
||||||
import io.element.android.services.analytics.test.FakeAnalyticsService
|
import io.element.android.services.analytics.test.FakeAnalyticsService
|
||||||
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
|
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
|
||||||
import io.element.android.tests.testutils.lambda.lambdaRecorder
|
|
||||||
import io.element.android.tests.testutils.lambda.value
|
|
||||||
import kotlinx.coroutines.test.TestScope
|
import kotlinx.coroutines.test.TestScope
|
||||||
import kotlinx.coroutines.test.runTest
|
import kotlinx.coroutines.test.runTest
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -191,47 +189,6 @@ class DefaultFtueServiceTest {
|
||||||
assertThat(awaitItem()).isEqualTo(InternalFtueState.Complete)
|
assertThat(awaitItem()).isEqualTo(InternalFtueState.Complete)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `reset do the expected actions S`() = runTest {
|
|
||||||
val resetAnalyticsLambda = lambdaRecorder<Unit> { }
|
|
||||||
val analyticsService = FakeAnalyticsService(
|
|
||||||
resetLambda = resetAnalyticsLambda
|
|
||||||
)
|
|
||||||
val resetPermissionLambda = lambdaRecorder<String, Unit> { }
|
|
||||||
val permissionStateProvider = FakePermissionStateProvider(
|
|
||||||
resetPermissionLambda = resetPermissionLambda
|
|
||||||
)
|
|
||||||
val service = createDefaultFtueService(
|
|
||||||
sdkIntVersion = Build.VERSION_CODES.S,
|
|
||||||
permissionStateProvider = permissionStateProvider,
|
|
||||||
analyticsService = analyticsService,
|
|
||||||
)
|
|
||||||
service.reset()
|
|
||||||
resetAnalyticsLambda.assertions().isCalledOnce()
|
|
||||||
resetPermissionLambda.assertions().isNeverCalled()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `reset do the expected actions TIRAMISU`() = runTest {
|
|
||||||
val resetLambda = lambdaRecorder<Unit> { }
|
|
||||||
val analyticsService = FakeAnalyticsService(
|
|
||||||
resetLambda = resetLambda
|
|
||||||
)
|
|
||||||
val resetPermissionLambda = lambdaRecorder<String, Unit> { }
|
|
||||||
val permissionStateProvider = FakePermissionStateProvider(
|
|
||||||
resetPermissionLambda = resetPermissionLambda
|
|
||||||
)
|
|
||||||
val service = createDefaultFtueService(
|
|
||||||
sdkIntVersion = Build.VERSION_CODES.TIRAMISU,
|
|
||||||
permissionStateProvider = permissionStateProvider,
|
|
||||||
analyticsService = analyticsService,
|
|
||||||
)
|
|
||||||
service.reset()
|
|
||||||
resetLambda.assertions().isCalledOnce()
|
|
||||||
resetPermissionLambda.assertions().isCalledOnce()
|
|
||||||
.with(value("android.permission.POST_NOTIFICATIONS"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun TestScope.createDefaultFtueService(
|
internal fun TestScope.createDefaultFtueService(
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,11 @@ package io.element.android.features.ftue.test
|
||||||
|
|
||||||
import io.element.android.features.ftue.api.state.FtueService
|
import io.element.android.features.ftue.api.state.FtueService
|
||||||
import io.element.android.features.ftue.api.state.FtueState
|
import io.element.android.features.ftue.api.state.FtueState
|
||||||
import io.element.android.tests.testutils.lambda.lambdaError
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
class FakeFtueService(
|
class FakeFtueService : FtueService {
|
||||||
private val resetLambda: () -> Unit = { lambdaError() },
|
|
||||||
) : FtueService {
|
|
||||||
override val state: MutableStateFlow<FtueState> = MutableStateFlow(FtueState.Unknown)
|
override val state: MutableStateFlow<FtueState> = MutableStateFlow(FtueState.Unknown)
|
||||||
|
|
||||||
override suspend fun reset() {
|
|
||||||
resetLambda()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun emitState(newState: FtueState) {
|
suspend fun emitState(newState: FtueState) {
|
||||||
state.emit(newState)
|
state.emit(newState)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,6 @@ dependencies {
|
||||||
implementation(projects.features.rageshake.api)
|
implementation(projects.features.rageshake.api)
|
||||||
implementation(projects.features.lockscreen.api)
|
implementation(projects.features.lockscreen.api)
|
||||||
implementation(projects.features.analytics.api)
|
implementation(projects.features.analytics.api)
|
||||||
implementation(projects.features.ftue.api)
|
|
||||||
implementation(projects.features.licenses.api)
|
implementation(projects.features.licenses.api)
|
||||||
implementation(projects.features.logout.api)
|
implementation(projects.features.logout.api)
|
||||||
implementation(projects.features.deactivation.api)
|
implementation(projects.features.deactivation.api)
|
||||||
|
|
@ -101,7 +100,6 @@ dependencies {
|
||||||
testImplementation(projects.libraries.preferences.test)
|
testImplementation(projects.libraries.preferences.test)
|
||||||
testImplementation(projects.libraries.push.test)
|
testImplementation(projects.libraries.push.test)
|
||||||
testImplementation(projects.libraries.pushstore.test)
|
testImplementation(projects.libraries.pushstore.test)
|
||||||
testImplementation(projects.features.ftue.test)
|
|
||||||
testImplementation(projects.features.invite.test)
|
testImplementation(projects.features.invite.test)
|
||||||
testImplementation(projects.features.rageshake.test)
|
testImplementation(projects.features.rageshake.test)
|
||||||
testImplementation(projects.features.logout.test)
|
testImplementation(projects.features.logout.test)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import coil3.SingletonImageLoader
|
||||||
import dev.zacsweers.metro.ContributesBinding
|
import dev.zacsweers.metro.ContributesBinding
|
||||||
import dev.zacsweers.metro.Inject
|
import dev.zacsweers.metro.Inject
|
||||||
import dev.zacsweers.metro.Provider
|
import dev.zacsweers.metro.Provider
|
||||||
import io.element.android.features.ftue.api.state.FtueService
|
|
||||||
import io.element.android.features.invite.api.SeenInvitesStore
|
import io.element.android.features.invite.api.SeenInvitesStore
|
||||||
import io.element.android.features.preferences.impl.DefaultCacheService
|
import io.element.android.features.preferences.impl.DefaultCacheService
|
||||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||||
|
|
@ -36,7 +35,6 @@ class DefaultClearCacheUseCase(
|
||||||
private val coroutineDispatchers: CoroutineDispatchers,
|
private val coroutineDispatchers: CoroutineDispatchers,
|
||||||
private val defaultCacheService: DefaultCacheService,
|
private val defaultCacheService: DefaultCacheService,
|
||||||
private val okHttpClient: Provider<OkHttpClient>,
|
private val okHttpClient: Provider<OkHttpClient>,
|
||||||
private val ftueService: FtueService,
|
|
||||||
private val pushService: PushService,
|
private val pushService: PushService,
|
||||||
private val seenInvitesStore: SeenInvitesStore,
|
private val seenInvitesStore: SeenInvitesStore,
|
||||||
private val activeRoomsHolder: ActiveRoomsHolder,
|
private val activeRoomsHolder: ActiveRoomsHolder,
|
||||||
|
|
@ -56,7 +54,6 @@ class DefaultClearCacheUseCase(
|
||||||
// Clear app cache
|
// Clear app cache
|
||||||
context.cacheDir.deleteRecursively()
|
context.cacheDir.deleteRecursively()
|
||||||
// Clear some settings
|
// Clear some settings
|
||||||
ftueService.reset()
|
|
||||||
seenInvitesStore.clear()
|
seenInvitesStore.clear()
|
||||||
// Ensure any error will be displayed again
|
// Ensure any error will be displayed again
|
||||||
pushService.setIgnoreRegistrationError(matrixClient.sessionId, false)
|
pushService.setIgnoreRegistrationError(matrixClient.sessionId, false)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ package io.element.android.features.preferences.impl.tasks
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import app.cash.turbine.test
|
import app.cash.turbine.test
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import io.element.android.features.ftue.test.FakeFtueService
|
|
||||||
import io.element.android.features.invite.test.InMemorySeenInvitesStore
|
import io.element.android.features.invite.test.InMemorySeenInvitesStore
|
||||||
import io.element.android.features.preferences.impl.DefaultCacheService
|
import io.element.android.features.preferences.impl.DefaultCacheService
|
||||||
import io.element.android.libraries.matrix.api.core.SessionId
|
import io.element.android.libraries.matrix.api.core.SessionId
|
||||||
|
|
@ -41,10 +40,6 @@ class DefaultClearCacheUseCaseTest {
|
||||||
clearCacheLambda = clearCacheLambda,
|
clearCacheLambda = clearCacheLambda,
|
||||||
)
|
)
|
||||||
val defaultCacheService = DefaultCacheService()
|
val defaultCacheService = DefaultCacheService()
|
||||||
val resetFtueLambda = lambdaRecorder<Unit> { }
|
|
||||||
val ftueService = FakeFtueService(
|
|
||||||
resetLambda = resetFtueLambda,
|
|
||||||
)
|
|
||||||
val setIgnoreRegistrationErrorLambda = lambdaRecorder<SessionId, Boolean, Unit> { _, _ -> }
|
val setIgnoreRegistrationErrorLambda = lambdaRecorder<SessionId, Boolean, Unit> { _, _ -> }
|
||||||
val resetBatteryOptimizationStateResult = lambdaRecorder<Unit> { }
|
val resetBatteryOptimizationStateResult = lambdaRecorder<Unit> { }
|
||||||
val pushService = FakePushService(
|
val pushService = FakePushService(
|
||||||
|
|
@ -59,7 +54,6 @@ class DefaultClearCacheUseCaseTest {
|
||||||
coroutineDispatchers = testCoroutineDispatchers(),
|
coroutineDispatchers = testCoroutineDispatchers(),
|
||||||
defaultCacheService = defaultCacheService,
|
defaultCacheService = defaultCacheService,
|
||||||
okHttpClient = { OkHttpClient.Builder().build() },
|
okHttpClient = { OkHttpClient.Builder().build() },
|
||||||
ftueService = ftueService,
|
|
||||||
pushService = pushService,
|
pushService = pushService,
|
||||||
seenInvitesStore = seenInvitesStore,
|
seenInvitesStore = seenInvitesStore,
|
||||||
activeRoomsHolder = activeRoomsHolder,
|
activeRoomsHolder = activeRoomsHolder,
|
||||||
|
|
@ -67,7 +61,6 @@ class DefaultClearCacheUseCaseTest {
|
||||||
defaultCacheService.clearedCacheEventFlow.test {
|
defaultCacheService.clearedCacheEventFlow.test {
|
||||||
sut.invoke()
|
sut.invoke()
|
||||||
clearCacheLambda.assertions().isCalledOnce()
|
clearCacheLambda.assertions().isCalledOnce()
|
||||||
resetFtueLambda.assertions().isCalledOnce()
|
|
||||||
setIgnoreRegistrationErrorLambda.assertions().isCalledOnce()
|
setIgnoreRegistrationErrorLambda.assertions().isCalledOnce()
|
||||||
.with(value(matrixClient.sessionId), value(false))
|
.with(value(matrixClient.sessionId), value(false))
|
||||||
resetBatteryOptimizationStateResult.assertions().isCalledOnce()
|
resetBatteryOptimizationStateResult.assertions().isCalledOnce()
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,4 @@ interface PermissionStateProvider {
|
||||||
|
|
||||||
suspend fun setPermissionAsked(permission: String, value: Boolean)
|
suspend fun setPermissionAsked(permission: String, value: Boolean)
|
||||||
fun isPermissionAsked(permission: String): Flow<Boolean>
|
fun isPermissionAsked(permission: String): Flow<Boolean>
|
||||||
|
|
||||||
suspend fun resetPermission(permission: String)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,4 @@ class DefaultPermissionStateProvider(
|
||||||
override suspend fun setPermissionAsked(permission: String, value: Boolean) = permissionsStore.setPermissionAsked(permission, value)
|
override suspend fun setPermissionAsked(permission: String, value: Boolean) = permissionsStore.setPermissionAsked(permission, value)
|
||||||
|
|
||||||
override fun isPermissionAsked(permission: String): Flow<Boolean> = permissionsStore.isPermissionAsked(permission)
|
override fun isPermissionAsked(permission: String): Flow<Boolean> = permissionsStore.isPermissionAsked(permission)
|
||||||
|
|
||||||
override suspend fun resetPermission(permission: String) = permissionsStore.resetPermission(permission)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ class FakePermissionStateProvider(
|
||||||
private var permissionGranted: Boolean = true,
|
private var permissionGranted: Boolean = true,
|
||||||
permissionDenied: Boolean = false,
|
permissionDenied: Boolean = false,
|
||||||
permissionAsked: Boolean = false,
|
permissionAsked: Boolean = false,
|
||||||
private val resetPermissionLambda: (String) -> Unit = {},
|
|
||||||
) : PermissionStateProvider {
|
) : PermissionStateProvider {
|
||||||
private val permissionDeniedFlow = MutableStateFlow(permissionDenied)
|
private val permissionDeniedFlow = MutableStateFlow(permissionDenied)
|
||||||
private val permissionAskedFlow = MutableStateFlow(permissionAsked)
|
private val permissionAskedFlow = MutableStateFlow(permissionAsked)
|
||||||
|
|
@ -37,10 +36,4 @@ class FakePermissionStateProvider(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isPermissionAsked(permission: String): Flow<Boolean> = permissionAskedFlow
|
override fun isPermissionAsked(permission: String): Flow<Boolean> = permissionAskedFlow
|
||||||
|
|
||||||
override suspend fun resetPermission(permission: String) {
|
|
||||||
setPermissionAsked(permission, false)
|
|
||||||
setPermissionDenied(permission, false)
|
|
||||||
resetPermissionLambda(permission)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,4 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker {
|
||||||
* Update analyticsId from the AccountData.
|
* Update analyticsId from the AccountData.
|
||||||
*/
|
*/
|
||||||
suspend fun setAnalyticsId(analyticsId: String)
|
suspend fun setAnalyticsId(analyticsId: String)
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the analytics service (will ask for user consent again).
|
|
||||||
*/
|
|
||||||
suspend fun reset()
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,10 +70,6 @@ class DefaultAnalyticsService(
|
||||||
analyticsStore.setDidAskUserConsent()
|
analyticsStore.setDidAskUserConsent()
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun reset() {
|
|
||||||
analyticsStore.setDidAskUserConsent(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun setAnalyticsId(analyticsId: String) {
|
override suspend fun setAnalyticsId(analyticsId: String) {
|
||||||
Timber.tag(analyticsTag.value).d("setAnalyticsId($analyticsId)")
|
Timber.tag(analyticsTag.value).d("setAnalyticsId($analyticsId)")
|
||||||
analyticsStore.setAnalyticsId(analyticsId)
|
analyticsStore.setAnalyticsId(analyticsId)
|
||||||
|
|
|
||||||
|
|
@ -180,20 +180,6 @@ class DefaultAnalyticsServiceTest {
|
||||||
resetLambda.assertions().isCalledOnce()
|
resetLambda.assertions().isCalledOnce()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `when reset is invoked, the user consent is reset`() = runTest {
|
|
||||||
val store = FakeAnalyticsStore(
|
|
||||||
defaultDidAskUserConsent = true,
|
|
||||||
)
|
|
||||||
val sut = createDefaultAnalyticsService(
|
|
||||||
coroutineScope = backgroundScope,
|
|
||||||
analyticsStore = store,
|
|
||||||
)
|
|
||||||
assertThat(store.didAskUserConsentFlow.first()).isTrue()
|
|
||||||
sut.reset()
|
|
||||||
assertThat(store.didAskUserConsentFlow.first()).isFalse()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `when a session is added, nothing happen`() = runTest {
|
fun `when a session is added, nothing happen`() = runTest {
|
||||||
val sut = createDefaultAnalyticsService(
|
val sut = createDefaultAnalyticsService(
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ class NoopAnalyticsService : AnalyticsService {
|
||||||
override suspend fun setDidAskUserConsent() = Unit
|
override suspend fun setDidAskUserConsent() = Unit
|
||||||
override val analyticsIdFlow: Flow<String> = flowOf("")
|
override val analyticsIdFlow: Flow<String> = flowOf("")
|
||||||
override suspend fun setAnalyticsId(analyticsId: String) = Unit
|
override suspend fun setAnalyticsId(analyticsId: String) = Unit
|
||||||
override suspend fun reset() = Unit
|
|
||||||
override fun capture(event: VectorAnalyticsEvent) = Unit
|
override fun capture(event: VectorAnalyticsEvent) = Unit
|
||||||
override fun screen(screen: VectorAnalyticsScreen) = Unit
|
override fun screen(screen: VectorAnalyticsScreen) = Unit
|
||||||
override fun updateUserProperties(userProperties: UserProperties) = Unit
|
override fun updateUserProperties(userProperties: UserProperties) = Unit
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||||
class FakeAnalyticsService(
|
class FakeAnalyticsService(
|
||||||
isEnabled: Boolean = false,
|
isEnabled: Boolean = false,
|
||||||
didAskUserConsent: Boolean = false,
|
didAskUserConsent: Boolean = false,
|
||||||
private val resetLambda: () -> Unit = {},
|
|
||||||
) : AnalyticsService {
|
) : AnalyticsService {
|
||||||
private val isEnabledFlow = MutableStateFlow(isEnabled)
|
private val isEnabledFlow = MutableStateFlow(isEnabled)
|
||||||
override val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent)
|
override val didAskUserConsentFlow = MutableStateFlow(didAskUserConsent)
|
||||||
|
|
@ -65,9 +64,4 @@ class FakeAnalyticsService(
|
||||||
override fun updateSuperProperties(updatedProperties: SuperProperties) {
|
override fun updateSuperProperties(updatedProperties: SuperProperties) {
|
||||||
// No op
|
// No op
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun reset() {
|
|
||||||
didAskUserConsentFlow.value = false
|
|
||||||
resetLambda()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue