Skip to content

Commit 4a04bd5

Browse files
authored
Merge pull request #5394 from element-hq/feature/bma/testIgnoredUser
Add troubleshhot notification test about blocked users
2 parents 2408e98 + 46d528e commit 4a04bd5

File tree

46 files changed

+529
-216
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+529
-216
lines changed

build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ allprojects {
9393
// Fix compilation warning for annotations
9494
// See https://youtrack.jetbrains.com/issue/KT-73255/Change-defaulting-rule-for-annotations for more details
9595
freeCompilerArgs.add("-Xannotation-default-target=first-only")
96+
// Opt-in to context receivers
97+
freeCompilerArgs.add("-Xcontext-parameters")
9698
}
9799
}
98100
}

features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ class PreferencesFlowNode(
208208
navigateUp()
209209
}
210210
}
211+
212+
override fun openIgnoredUsers() {
213+
backstack.push(NavTarget.BlockedUsers)
214+
}
211215
})
212216
.build()
213217
}

libraries/permissions/impl/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ dependencies {
4343
testCommonDependencies(libs)
4444
testImplementation(projects.libraries.matrix.test)
4545
testImplementation(projects.libraries.permissions.test)
46+
testImplementation(projects.libraries.troubleshoot.test)
4647
testImplementation(projects.services.toolbox.test)
4748
}

libraries/permissions/impl/src/main/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTest.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dev.zacsweers.metro.Inject
1515
import io.element.android.libraries.permissions.api.PermissionStateProvider
1616
import io.element.android.libraries.permissions.impl.R
1717
import io.element.android.libraries.permissions.impl.action.PermissionActions
18+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootNavigator
1819
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest
1920
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate
2021
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState
@@ -54,7 +55,10 @@ class NotificationTroubleshootCheckPermissionTest(
5455

5556
override suspend fun reset() = delegate.reset()
5657

57-
override suspend fun quickFix(coroutineScope: CoroutineScope) {
58+
override suspend fun quickFix(
59+
coroutineScope: CoroutineScope,
60+
navigator: NotificationTroubleshootNavigator,
61+
) {
5862
// Do not bother about asking the permission inline, just lead the user to the settings
5963
permissionActions.openSettings()
6064
}

libraries/permissions/impl/src/test/kotlin/io/element/android/libraries/permissions/impl/troubleshoot/NotificationTroubleshootCheckPermissionTestTest.kt

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88
package io.element.android.libraries.permissions.impl.troubleshoot
99

1010
import android.os.Build
11-
import app.cash.turbine.test
1211
import com.google.common.truth.Truth.assertThat
1312
import io.element.android.libraries.permissions.impl.action.FakePermissionActions
1413
import io.element.android.libraries.permissions.test.FakePermissionStateProvider
1514
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState
15+
import io.element.android.libraries.troubleshoot.test.FakeNotificationTroubleshootNavigator
16+
import io.element.android.libraries.troubleshoot.test.runAndTestState
1617
import io.element.android.services.toolbox.test.sdk.FakeBuildVersionSdkIntProvider
1718
import io.element.android.services.toolbox.test.strings.FakeStringProvider
1819
import kotlinx.coroutines.launch
@@ -28,10 +29,7 @@ class NotificationTroubleshootCheckPermissionTestTest {
2829
permissionActions = FakePermissionActions(),
2930
stringProvider = FakeStringProvider(),
3031
)
31-
launch {
32-
sut.run(this)
33-
}
34-
sut.state.test {
32+
sut.runAndTestState {
3533
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
3634
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
3735
val lastItem = awaitItem()
@@ -47,10 +45,7 @@ class NotificationTroubleshootCheckPermissionTestTest {
4745
permissionActions = FakePermissionActions(),
4846
stringProvider = FakeStringProvider(),
4947
)
50-
launch {
51-
sut.run(this)
52-
}
53-
sut.state.test {
48+
sut.runAndTestState {
5449
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
5550
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
5651
val lastItem = awaitItem()
@@ -74,17 +69,14 @@ class NotificationTroubleshootCheckPermissionTestTest {
7469
permissionActions = actions,
7570
stringProvider = FakeStringProvider(),
7671
)
77-
launch {
78-
sut.run(this)
79-
}
80-
sut.state.test {
72+
sut.runAndTestState {
8173
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
8274
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
8375
val lastItem = awaitItem()
84-
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(true))
76+
assertThat(lastItem.status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(hasQuickFix = true))
8577
// Quick fix
86-
launch {
87-
sut.quickFix(this)
78+
backgroundScope.launch {
79+
sut.quickFix(this, FakeNotificationTroubleshootNavigator())
8880
// Run the test again (IRL it will be done thanks to the resuming of the application)
8981
sut.run(this)
9082
}
@@ -109,13 +101,10 @@ class NotificationTroubleshootCheckPermissionTestTest {
109101
permissionActions = actions,
110102
stringProvider = FakeStringProvider(),
111103
)
112-
launch {
113-
sut.run(this)
114-
}
115-
sut.state.test {
104+
sut.runAndTestState {
116105
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
117106
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.InProgress)
118-
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(true))
107+
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Failure(hasQuickFix = true))
119108
sut.reset()
120109
assertThat(awaitItem().status).isEqualTo(NotificationTroubleshootTestState.Status.Idle(true))
121110
}

libraries/push/impl/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ dependencies {
7272
testImplementation(projects.libraries.push.test)
7373
testImplementation(projects.libraries.pushproviders.test)
7474
testImplementation(projects.libraries.pushstore.test)
75+
testImplementation(projects.libraries.troubleshoot.test)
7576
testImplementation(projects.features.call.test)
7677
testImplementation(projects.features.lockscreen.test)
7778
testImplementation(projects.services.appnavstate.test)

libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/CurrentPushProviderTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CurrentPushProviderTest(
4444
} else {
4545
delegate.updateState(
4646
description = stringProvider.getString(R.string.troubleshoot_notifications_test_current_push_provider_failure),
47-
status = NotificationTroubleshootTestState.Status.Failure(false)
47+
status = NotificationTroubleshootTestState.Status.Failure()
4848
)
4949
}
5050
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.libraries.push.impl.troubleshoot
9+
10+
import dev.zacsweers.metro.ContributesIntoSet
11+
import dev.zacsweers.metro.Inject
12+
import io.element.android.libraries.di.SessionScope
13+
import io.element.android.libraries.matrix.api.MatrixClient
14+
import io.element.android.libraries.push.impl.R
15+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootNavigator
16+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest
17+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate
18+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState
19+
import io.element.android.services.toolbox.api.strings.StringProvider
20+
import kotlinx.coroutines.CoroutineScope
21+
import kotlinx.coroutines.flow.StateFlow
22+
23+
@ContributesIntoSet(SessionScope::class)
24+
@Inject
25+
class IgnoredUsersTest(
26+
private val matrixClient: MatrixClient,
27+
private val stringProvider: StringProvider,
28+
) : NotificationTroubleshootTest {
29+
override val order = 80
30+
private val delegate = NotificationTroubleshootTestDelegate(
31+
defaultName = stringProvider.getString(R.string.troubleshoot_notifications_test_blocked_users_title),
32+
defaultDescription = stringProvider.getString(R.string.troubleshoot_notifications_test_blocked_users_description),
33+
fakeDelay = NotificationTroubleshootTestDelegate.SHORT_DELAY,
34+
)
35+
override val state: StateFlow<NotificationTroubleshootTestState> = delegate.state
36+
37+
override suspend fun run(coroutineScope: CoroutineScope) {
38+
delegate.start()
39+
val ignorerUsers = matrixClient.ignoredUsersFlow.value
40+
if (ignorerUsers.isEmpty()) {
41+
delegate.updateState(
42+
description = stringProvider.getString(R.string.troubleshoot_notifications_test_blocked_users_result_none),
43+
status = NotificationTroubleshootTestState.Status.Success,
44+
)
45+
} else {
46+
delegate.updateState(
47+
description = stringProvider.getQuantityString(
48+
R.plurals.troubleshoot_notifications_test_blocked_users_result_some,
49+
ignorerUsers.size,
50+
ignorerUsers.size
51+
),
52+
status = NotificationTroubleshootTestState.Status.Failure(
53+
hasQuickFix = true,
54+
isCritical = false,
55+
quickFixButtonString = stringProvider.getString(R.string.troubleshoot_notifications_test_blocked_users_quick_fix),
56+
),
57+
)
58+
}
59+
}
60+
61+
override suspend fun quickFix(
62+
coroutineScope: CoroutineScope,
63+
navigator: NotificationTroubleshootNavigator,
64+
) {
65+
navigator.openIgnoredUsers()
66+
}
67+
68+
override suspend fun reset() = delegate.reset()
69+
}

libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/NotificationTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class NotificationTest(
5454
} else {
5555
delegate.updateState(
5656
description = stringProvider.getString(R.string.troubleshoot_notifications_test_display_notification_permission_failure),
57-
status = NotificationTroubleshootTestState.Status.Failure(false)
57+
status = NotificationTroubleshootTestState.Status.Failure()
5858
)
5959
}
6060
}
@@ -81,7 +81,7 @@ class NotificationTest(
8181
notificationDisplayer.dismissDiagnosticNotification()
8282
delegate.updateState(
8383
description = stringProvider.getString(R.string.troubleshoot_notifications_test_display_notification_failure),
84-
status = NotificationTroubleshootTestState.Status.Failure(false)
84+
status = NotificationTroubleshootTestState.Status.Failure()
8585
)
8686
}
8787
)

libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/troubleshoot/PushLoopbackTest.kt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import dev.zacsweers.metro.Inject
1313
import io.element.android.libraries.push.api.PushService
1414
import io.element.android.libraries.push.api.gateway.PushGatewayFailure
1515
import io.element.android.libraries.push.impl.R
16+
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootNavigator
1617
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTest
1718
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestDelegate
1819
import io.element.android.libraries.troubleshoot.api.test.NotificationTroubleshootTestState
@@ -56,23 +57,23 @@ class PushLoopbackTest(
5657
val hasQuickFix = pushService.getCurrentPushProvider()?.canRotateToken() == true
5758
delegate.updateState(
5859
description = stringProvider.getString(R.string.troubleshoot_notifications_test_push_loop_back_failure_1),
59-
status = NotificationTroubleshootTestState.Status.Failure(hasQuickFix)
60+
status = NotificationTroubleshootTestState.Status.Failure(hasQuickFix = hasQuickFix)
6061
)
6162
job.cancel()
6263
return
6364
} catch (e: Exception) {
6465
Timber.e(e, "Failed to test push")
6566
delegate.updateState(
6667
description = stringProvider.getString(R.string.troubleshoot_notifications_test_push_loop_back_failure_2, e.message),
67-
status = NotificationTroubleshootTestState.Status.Failure(false)
68+
status = NotificationTroubleshootTestState.Status.Failure()
6869
)
6970
job.cancel()
7071
return
7172
}
7273
if (!testPushResult) {
7374
delegate.updateState(
7475
description = stringProvider.getString(R.string.troubleshoot_notifications_test_push_loop_back_failure_3),
75-
status = NotificationTroubleshootTestState.Status.Failure(false)
76+
status = NotificationTroubleshootTestState.Status.Failure()
7677
)
7778
job.cancel()
7879
return
@@ -93,13 +94,16 @@ class PushLoopbackTest(
9394
job.cancel()
9495
delegate.updateState(
9596
description = stringProvider.getString(R.string.troubleshoot_notifications_test_push_loop_back_failure_4),
96-
status = NotificationTroubleshootTestState.Status.Failure(false)
97+
status = NotificationTroubleshootTestState.Status.Failure()
9798
)
9899
}
99100
)
100101
}
101102

102-
override suspend fun quickFix(coroutineScope: CoroutineScope) {
103+
override suspend fun quickFix(
104+
coroutineScope: CoroutineScope,
105+
navigator: NotificationTroubleshootNavigator,
106+
) {
103107
delegate.start()
104108
pushService.getCurrentPushProvider()?.rotateToken()
105109
run(coroutineScope)

0 commit comments

Comments
 (0)