diff --git a/vector/src/main/java/im/vector/app/core/notification/EnableNotificationsSettingUpdater.kt b/vector/src/main/java/im/vector/app/core/notification/EnableNotificationsSettingUpdater.kt index 21febaee9d..81b524cde9 100644 --- a/vector/src/main/java/im/vector/app/core/notification/EnableNotificationsSettingUpdater.kt +++ b/vector/src/main/java/im/vector/app/core/notification/EnableNotificationsSettingUpdater.kt @@ -18,7 +18,6 @@ package im.vector.app.core.notification import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import javax.inject.Inject @@ -35,7 +34,6 @@ class EnableNotificationsSettingUpdater @Inject constructor( job?.cancel() job = session.coroutineScope.launch { updateEnableNotificationsSettingOnChangeUseCase.execute(session) - .launchIn(this) } } } diff --git a/vector/src/main/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCase.kt b/vector/src/main/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCase.kt index a6bcf17b5c..55a2cfdc64 100644 --- a/vector/src/main/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCase.kt +++ b/vector/src/main/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCase.kt @@ -19,8 +19,7 @@ package im.vector.app.core.notification import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.devices.v2.notification.GetNotificationsStatusUseCase import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.session.Session import timber.log.Timber @@ -35,11 +34,11 @@ class UpdateEnableNotificationsSettingOnChangeUseCase @Inject constructor( private val getNotificationsStatusUseCase: GetNotificationsStatusUseCase, ) { - // TODO add unit tests - fun execute(session: Session): Flow { - val deviceId = session.sessionParams.deviceId ?: return emptyFlow() - return getNotificationsStatusUseCase.execute(session, deviceId) + suspend fun execute(session: Session) { + val deviceId = session.sessionParams.deviceId ?: return + getNotificationsStatusUseCase.execute(session, deviceId) .onEach(::updatePreference) + .collect() } private fun updatePreference(notificationStatus: NotificationsStatus) { diff --git a/vector/src/test/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCaseTest.kt b/vector/src/test/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCaseTest.kt new file mode 100644 index 0000000000..5cced75735 --- /dev/null +++ b/vector/src/test/java/im/vector/app/core/notification/UpdateEnableNotificationsSettingOnChangeUseCaseTest.kt @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2022 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 im.vector.app.core.notification + +import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus +import im.vector.app.test.fakes.FakeGetNotificationsStatusUseCase +import im.vector.app.test.fakes.FakeSession +import im.vector.app.test.fakes.FakeVectorPreferences +import kotlinx.coroutines.test.runTest +import org.junit.Test + +private const val A_SESSION_ID = "session-id" + +class UpdateEnableNotificationsSettingOnChangeUseCaseTest { + + private val fakeSession = FakeSession().also { it.givenSessionId(A_SESSION_ID) } + private val fakeVectorPreferences = FakeVectorPreferences() + private val fakeGetNotificationsStatusUseCase = FakeGetNotificationsStatusUseCase() + + private val updateEnableNotificationsSettingOnChangeUseCase = UpdateEnableNotificationsSettingOnChangeUseCase( + vectorPreferences = fakeVectorPreferences.instance, + getNotificationsStatusUseCase = fakeGetNotificationsStatusUseCase.instance, + ) + + @Test + fun `given notifications are enabled when execute then setting is updated to true`() = runTest { + // Given + fakeGetNotificationsStatusUseCase.givenExecuteReturns( + fakeSession, + A_SESSION_ID, + NotificationsStatus.ENABLED, + ) + fakeVectorPreferences.givenSetNotificationEnabledForDevice() + + // When + updateEnableNotificationsSettingOnChangeUseCase.execute(fakeSession) + + // Then + fakeVectorPreferences.verifySetNotificationEnabledForDevice(true) + } + + @Test + fun `given notifications are disabled when execute then setting is updated to false`() = runTest { + // Given + fakeGetNotificationsStatusUseCase.givenExecuteReturns( + fakeSession, + A_SESSION_ID, + NotificationsStatus.DISABLED, + ) + fakeVectorPreferences.givenSetNotificationEnabledForDevice() + + // When + updateEnableNotificationsSettingOnChangeUseCase.execute(fakeSession) + + // Then + fakeVectorPreferences.verifySetNotificationEnabledForDevice(false) + } + + @Test + fun `given notifications toggle is not supported when execute then nothing is done`() = runTest { + // Given + fakeGetNotificationsStatusUseCase.givenExecuteReturns( + fakeSession, + A_SESSION_ID, + NotificationsStatus.NOT_SUPPORTED, + ) + fakeVectorPreferences.givenSetNotificationEnabledForDevice() + + // When + updateEnableNotificationsSettingOnChangeUseCase.execute(fakeSession) + + // Then + fakeVectorPreferences.verifySetNotificationEnabledForDevice(true, inverse = true) + fakeVectorPreferences.verifySetNotificationEnabledForDevice(false, inverse = true) + } +} diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt index 444e14ec0e..86a9969a6a 100644 --- a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModelTest.kt @@ -22,11 +22,11 @@ import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MavericksTestRule import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase -import im.vector.app.features.settings.devices.v2.notification.GetNotificationsStatusUseCase import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus import im.vector.app.features.settings.devices.v2.signout.InterceptSignoutFlowResponseUseCase import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder +import im.vector.app.test.fakes.FakeGetNotificationsStatusUseCase import im.vector.app.test.fakes.FakePendingAuthHandler import im.vector.app.test.fakes.FakeSignoutSessionsUseCase import im.vector.app.test.fakes.FakeTogglePushNotificationUseCase @@ -77,7 +77,7 @@ class SessionOverviewViewModelTest { private val fakePendingAuthHandler = FakePendingAuthHandler() private val refreshDevicesUseCase = mockk(relaxed = true) private val togglePushNotificationUseCase = FakeTogglePushNotificationUseCase() - private val fakeGetNotificationsStatusUseCase = mockk() + private val fakeGetNotificationsStatusUseCase = FakeGetNotificationsStatusUseCase() private val notificationsStatus = NotificationsStatus.ENABLED private fun createViewModel() = SessionOverviewViewModel( @@ -90,7 +90,7 @@ class SessionOverviewViewModelTest { activeSessionHolder = fakeActiveSessionHolder.instance, refreshDevicesUseCase = refreshDevicesUseCase, togglePushNotificationUseCase = togglePushNotificationUseCase.instance, - getNotificationsStatusUseCase = fakeGetNotificationsStatusUseCase, + getNotificationsStatusUseCase = fakeGetNotificationsStatusUseCase.instance, ) @Before @@ -100,7 +100,11 @@ class SessionOverviewViewModelTest { every { SystemClock.elapsedRealtime() } returns 1234 givenVerificationService() - every { fakeGetNotificationsStatusUseCase.execute(fakeActiveSessionHolder.fakeSession, A_SESSION_ID_1) } returns flowOf(notificationsStatus) + fakeGetNotificationsStatusUseCase.givenExecuteReturns( + fakeActiveSessionHolder.fakeSession, + A_SESSION_ID_1, + notificationsStatus + ) } private fun givenVerificationService(): FakeVerificationService { diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeGetNotificationsStatusUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeGetNotificationsStatusUseCase.kt new file mode 100644 index 0000000000..a9c1b37d69 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeGetNotificationsStatusUseCase.kt @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 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 im.vector.app.test.fakes + +import im.vector.app.features.settings.devices.v2.notification.GetNotificationsStatusUseCase +import im.vector.app.features.settings.devices.v2.notification.NotificationsStatus +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.flow.flowOf +import org.matrix.android.sdk.api.session.Session + +class FakeGetNotificationsStatusUseCase { + + val instance = mockk() + + fun givenExecuteReturns( + session: Session, + sessionId: String, + notificationsStatus: NotificationsStatus + ) { + every { instance.execute(session, sessionId) } returns flowOf(notificationsStatus) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt index cd4f70bf63..4baa7e2b90 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeVectorPreferences.kt @@ -18,6 +18,7 @@ package im.vector.app.test.fakes import im.vector.app.features.settings.VectorPreferences import io.mockk.every +import io.mockk.justRun import io.mockk.mockk import io.mockk.verify @@ -42,5 +43,13 @@ class FakeVectorPreferences { } fun givenTextFormatting(isEnabled: Boolean) = - every { instance.isTextFormattingEnabled() } returns isEnabled + every { instance.isTextFormattingEnabled() } returns isEnabled + + fun givenSetNotificationEnabledForDevice() { + justRun { instance.setNotificationEnabledForDevice(any()) } + } + + fun verifySetNotificationEnabledForDevice(enabled: Boolean, inverse: Boolean = false) { + verify(inverse = inverse) { instance.setNotificationEnabledForDevice(enabled) } + } }