diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index 228d6c5547..552b78bbb8 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -218,7 +218,7 @@ class HomeActivity : fcmHelper.ensureFcmTokenIsRetrieved( this, pushersManager, - vectorPreferences.areNotificationEnabledForDevice() + homeActivityViewModel.shouldAddHttpPusher() ) } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 595878ecc1..61a8e5b79e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -143,6 +143,14 @@ class HomeActivityViewModel @AssistedInject constructor( } } + fun shouldAddHttpPusher() = if (vectorPreferences.areNotificationEnabledForDevice()) { + val currentSession = activeSessionHolder.getActiveSession() + val currentPushers = currentSession.pushersService().getPushers() + currentPushers.none { it.deviceId == currentSession.sessionParams.deviceId } + } else { + false + } + fun observeLocalNotificationsSilenced() { val currentSession = activeSessionHolder.getActiveSession() val deviceId = currentSession.cryptoService().getMyDevice().deviceId diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt index 463d5bb495..a1cd7ea586 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewFragment.kt @@ -47,7 +47,6 @@ import im.vector.app.features.workers.signout.SignOutUiWorker import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel -import org.matrix.android.sdk.api.session.pushers.Pusher import javax.inject.Inject /** @@ -178,7 +177,7 @@ class SessionOverviewFragment : updateEntryDetails(state.deviceId) updateSessionInfo(state) updateLoading(state.isLoading) - updatePushNotificationToggle(state.deviceId, state.pushers.invoke().orEmpty()) + updatePushNotificationToggle(state.deviceId, state.notificationsEnabled) } private fun updateToolbar(viewState: SessionOverviewViewState) { @@ -219,18 +218,13 @@ class SessionOverviewFragment : } } - private fun updatePushNotificationToggle(deviceId: String, pushers: List) { + private fun updatePushNotificationToggle(deviceId: String, enabled: Boolean) { views.sessionOverviewPushNotifications.apply { - if (pushers.isEmpty()) { - isVisible = false - } else { - val allPushersAreEnabled = pushers.all { it.enabled } - setOnCheckedChangeListener(null) - setChecked(allPushersAreEnabled) - post { - setOnCheckedChangeListener { _, isChecked -> - viewModel.handle(SessionOverviewAction.TogglePushNotifications(deviceId, isChecked)) - } + setOnCheckedChangeListener(null) + setChecked(enabled) + post { + setOnCheckedChangeListener { _, isChecked -> + viewModel.handle(SessionOverviewAction.TogglePushNotifications(deviceId, isChecked)) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt index a7b0435e29..21054270f8 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewModel.kt @@ -36,24 +36,27 @@ import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSes import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.failure.Failure -import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth import org.matrix.android.sdk.flow.flow +import org.matrix.android.sdk.flow.unwrap import timber.log.Timber import javax.net.ssl.HttpsURLConnection import kotlin.coroutines.Continuation class SessionOverviewViewModel @AssistedInject constructor( @Assisted val initialState: SessionOverviewViewState, - private val session: Session, private val stringProvider: StringProvider, private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase, private val checkIfCurrentSessionCanBeVerifiedUseCase: CheckIfCurrentSessionCanBeVerifiedUseCase, @@ -61,6 +64,7 @@ class SessionOverviewViewModel @AssistedInject constructor( private val interceptSignoutFlowResponseUseCase: InterceptSignoutFlowResponseUseCase, private val pendingAuthHandler: PendingAuthHandler, private val activeSessionHolder: ActiveSessionHolder, + private val togglePushNotificationUseCase: TogglePushNotificationUseCase, refreshDevicesUseCase: RefreshDevicesUseCase, ) : VectorSessionsListViewModel( initialState, activeSessionHolder, refreshDevicesUseCase @@ -74,11 +78,16 @@ class SessionOverviewViewModel @AssistedInject constructor( } init { + refreshPushers() observeSessionInfo(initialState.deviceId) observeCurrentSessionInfo() observePushers(initialState.deviceId) } + private fun refreshPushers() { + activeSessionHolder.getSafeActiveSession()?.pushersService()?.refreshPushers() + } + private fun observeSessionInfo(deviceId: String) { getDeviceFullInfoUseCase.execute(deviceId) .onEach { setState { copy(deviceInfo = Success(it)) } } @@ -99,10 +108,20 @@ class SessionOverviewViewModel @AssistedInject constructor( } private fun observePushers(deviceId: String) { - session.flow() + val session = activeSessionHolder.getSafeActiveSession() ?: return + val pusherFlow = session.flow() .livePushers() .map { it.filter { pusher -> pusher.deviceId == deviceId } } - .execute { copy(pushers = it) } + .map { it.takeIf { it.isNotEmpty() }?.any { pusher -> pusher.enabled } } + + val accountDataFlow = session.flow() + .liveUserAccountData(TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId) + .unwrap() + .map { it.content.toModel()?.isSilenced?.not() } + + merge(pusherFlow, accountDataFlow) + .onEach { it?.let { setState { copy(notificationsEnabled = it) } } } + .launchIn(viewModelScope) } override fun handle(action: SessionOverviewAction) { @@ -213,10 +232,8 @@ class SessionOverviewViewModel @AssistedInject constructor( private fun handleTogglePusherAction(action: SessionOverviewAction.TogglePushNotifications) { viewModelScope.launch { - val devicePushers = awaitState().pushers.invoke()?.filter { it.deviceId == action.deviceId } - devicePushers?.forEach { pusher -> - session.pushersService().togglePusher(pusher, action.enabled) - } + togglePushNotificationUseCase.execute(action.deviceId, action.enabled) + setState { copy(notificationsEnabled = action.enabled) } } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt index c2d4a858b3..440805bad6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewViewState.kt @@ -20,14 +20,13 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized import im.vector.app.features.settings.devices.v2.DeviceFullInfo -import org.matrix.android.sdk.api.session.pushers.Pusher data class SessionOverviewViewState( val deviceId: String, val isCurrentSessionTrusted: Boolean = false, val deviceInfo: Async = Uninitialized, val isLoading: Boolean = false, - val pushers: Async> = Uninitialized, + val notificationsEnabled: Boolean = false, ) : MavericksState { constructor(args: SessionOverviewArgs) : this( deviceId = args.deviceId diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCase.kt new file mode 100644 index 0000000000..45c234aaef --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCase.kt @@ -0,0 +1,45 @@ +/* + * 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.features.settings.devices.v2.overview + +import im.vector.app.core.di.ActiveSessionHolder +import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes +import org.matrix.android.sdk.api.session.events.model.toContent +import javax.inject.Inject + +class TogglePushNotificationUseCase @Inject constructor( + private val activeSessionHolder: ActiveSessionHolder, +) { + + suspend fun execute(deviceId: String, enabled: Boolean) { + val session = activeSessionHolder.getSafeActiveSession() ?: return + val devicePusher = session.pushersService().getPushers().firstOrNull { it.deviceId == deviceId } + devicePusher?.let { pusher -> + session.pushersService().togglePusher(pusher, enabled) + } + + val accountData = session.accountDataService().getUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId) + if (accountData != null) { + val newNotificationSettingsContent = LocalNotificationSettingsContent(isSilenced = !enabled) + session.accountDataService().updateUserAccountData( + UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId, + newNotificationSettingsContent.toContent(), + ) + } + } +} diff --git a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt index 750e50d578..113a810ac2 100644 --- a/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt +++ b/vector/src/test/java/im/vector/app/core/pushers/PushersManagerTest.kt @@ -114,6 +114,6 @@ class PushersManagerTest { pushersManager.togglePusherForCurrentSession(true) - pushersService.verifyOnlyGetPushersAndTogglePusherCalled(pusher, true) + pushersService.verifyTogglePusherCalled(pusher, 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 73c9c5aa95..544059b77f 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 @@ -18,7 +18,6 @@ package im.vector.app.features.settings.devices.v2.overview import android.os.SystemClock import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MavericksTestRule import im.vector.app.R @@ -30,8 +29,8 @@ import im.vector.app.features.settings.devices.v2.signout.SignoutSessionUseCase import im.vector.app.features.settings.devices.v2.verification.CheckIfCurrentSessionCanBeVerifiedUseCase import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakePendingAuthHandler -import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeStringProvider +import im.vector.app.test.fakes.FakeTogglePushNotificationUseCase import im.vector.app.test.fakes.FakeVerificationService import im.vector.app.test.fixtures.PusherFixture.aPusher import im.vector.app.test.test @@ -79,7 +78,6 @@ class SessionOverviewViewModelTest { private val args = SessionOverviewArgs( deviceId = A_SESSION_ID_1 ) - private val fakeSession = FakeSession() private val getDeviceFullInfoUseCase = mockk(relaxed = true) private val fakeActiveSessionHolder = FakeActiveSessionHolder() private val fakeStringProvider = FakeStringProvider() @@ -88,10 +86,10 @@ class SessionOverviewViewModelTest { private val interceptSignoutFlowResponseUseCase = mockk() private val fakePendingAuthHandler = FakePendingAuthHandler() private val refreshDevicesUseCase = mockk() + private val togglePushNotificationUseCase = FakeTogglePushNotificationUseCase() private fun createViewModel() = SessionOverviewViewModel( initialState = SessionOverviewViewState(args), - session = fakeSession, stringProvider = fakeStringProvider.instance, getDeviceFullInfoUseCase = getDeviceFullInfoUseCase, checkIfCurrentSessionCanBeVerifiedUseCase = checkIfCurrentSessionCanBeVerifiedUseCase, @@ -100,6 +98,7 @@ class SessionOverviewViewModelTest { pendingAuthHandler = fakePendingAuthHandler.instance, activeSessionHolder = fakeActiveSessionHolder.instance, refreshDevicesUseCase = refreshDevicesUseCase, + togglePushNotificationUseCase = togglePushNotificationUseCase.instance, ) @Before @@ -116,6 +115,13 @@ class SessionOverviewViewModelTest { unmockkAll() } + @Test + fun `given the viewModel has been initialized then pushers are refreshed`() { + createViewModel() + + fakeActiveSessionHolder.fakeSession.pushersService().verifyRefreshPushers() + } + @Test fun `given the viewModel has been initialized then viewState is updated with session info`() { val deviceFullInfo = mockk() @@ -125,7 +131,7 @@ class SessionOverviewViewModelTest { deviceId = A_SESSION_ID_1, deviceInfo = Success(deviceFullInfo), isCurrentSessionTrusted = true, - pushers = Loading(), + notificationsEnabled = true, ) val viewModel = createViewModel() @@ -221,7 +227,7 @@ class SessionOverviewViewModelTest { isCurrentSessionTrusted = true, deviceInfo = Success(deviceFullInfo), isLoading = false, - pushers = Loading(), + notificationsEnabled = true, ) // When @@ -258,7 +264,7 @@ class SessionOverviewViewModelTest { isCurrentSessionTrusted = true, deviceInfo = Success(deviceFullInfo), isLoading = false, - pushers = Loading(), + notificationsEnabled = true, ) fakeStringProvider.given(R.string.authentication_error, AUTH_ERROR_MESSAGE) @@ -293,7 +299,7 @@ class SessionOverviewViewModelTest { isCurrentSessionTrusted = true, deviceInfo = Success(deviceFullInfo), isLoading = false, - pushers = Loading(), + notificationsEnabled = true, ) fakeStringProvider.given(R.string.matrix_error, AN_ERROR_MESSAGE) @@ -461,26 +467,22 @@ class SessionOverviewViewModelTest { @Test fun `when viewModel init, then observe pushers and emit to state`() { val pushers = listOf(aPusher(deviceId = A_SESSION_ID_1)) - fakeSession.pushersService().givenPushersLive(pushers) + fakeActiveSessionHolder.fakeSession.pushersService().givenPushersLive(pushers) val viewModel = createViewModel() viewModel.test() - .assertLatestState { state -> state.pushers.invoke() == pushers } + .assertLatestState { state -> state.notificationsEnabled } .finish() } @Test - fun `when handle TogglePushNotifications, then toggle enabled for device pushers`() { - val pushers = listOf( - aPusher(deviceId = A_SESSION_ID_1, enabled = false), - aPusher(deviceId = "another id", enabled = false) - ) - fakeSession.pushersService().givenPushersLive(pushers) - + fun `when handle TogglePushNotifications, then execute use case and update state`() { val viewModel = createViewModel() + viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID_1, true)) - fakeSession.pushersService().verifyOnlyTogglePusherCalled(pushers.first(), true) + togglePushNotificationUseCase.verifyExecute(A_SESSION_ID_1, true) + viewModel.test().assertLatestState { state -> state.notificationsEnabled }.finish() } } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCaseTest.kt new file mode 100644 index 0000000000..dc64c74836 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/overview/TogglePushNotificationUseCaseTest.kt @@ -0,0 +1,67 @@ +/* + * 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.features.settings.devices.v2.overview + +import im.vector.app.test.fakes.FakeActiveSessionHolder +import im.vector.app.test.fixtures.PusherFixture +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent +import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes +import org.matrix.android.sdk.api.session.events.model.toContent + +class TogglePushNotificationUseCaseTest { + + private val activeSessionHolder = FakeActiveSessionHolder() + private val togglePushNotificationUseCase = TogglePushNotificationUseCase(activeSessionHolder.instance) + + @Test + fun `when execute, then toggle enabled for device pushers`() = runTest { + val sessionId = "a_session_id" + val pushers = listOf( + PusherFixture.aPusher(deviceId = sessionId, enabled = false), + PusherFixture.aPusher(deviceId = "another id", enabled = false) + ) + activeSessionHolder.fakeSession.pushersService().givenPushersLive(pushers) + activeSessionHolder.fakeSession.pushersService().givenGetPushers(pushers) + + togglePushNotificationUseCase.execute(sessionId, true) + + activeSessionHolder.fakeSession.pushersService().verifyTogglePusherCalled(pushers.first(), true) + } + + @Test + fun `when execute, then toggle local notification settings`() = runTest { + val sessionId = "a_session_id" + val pushers = listOf( + PusherFixture.aPusher(deviceId = sessionId, enabled = false), + PusherFixture.aPusher(deviceId = "another id", enabled = false) + ) + activeSessionHolder.fakeSession.pushersService().givenPushersLive(pushers) + activeSessionHolder.fakeSession.accountDataService().givenGetUserAccountDataEventReturns( + UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + sessionId, + LocalNotificationSettingsContent(isSilenced = true).toContent() + ) + + togglePushNotificationUseCase.execute(sessionId, true) + + activeSessionHolder.fakeSession.accountDataService().verifyUpdateUserAccountDataEventSucceeds( + UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + sessionId, + LocalNotificationSettingsContent(isSilenced = false).toContent(), + ) + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakePushersService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakePushersService.kt index 4ad3052538..4e4323275b 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakePushersService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakePushersService.kt @@ -17,7 +17,6 @@ package im.vector.app.test.fakes import androidx.lifecycle.liveData -import io.mockk.Ordering import io.mockk.coVerify import io.mockk.every import io.mockk.justRun @@ -38,16 +37,8 @@ class FakePushersService : PushersService by mockk(relaxed = true) { every { getPushersLive() } returns liveData { emit(pushers) } } - fun verifyOnlyGetPushersAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { - coVerify(ordering = Ordering.ALL) { - getPushers() - togglePusher(pusher, enable) - } - } - - fun verifyOnlyTogglePusherCalled(pusher: Pusher, enable: Boolean) { - coVerify(ordering = Ordering.ALL) { - getPushersLive() // verifies only getPushersLive and the following togglePusher was called + fun verifyTogglePusherCalled(pusher: Pusher, enable: Boolean) { + coVerify { togglePusher(pusher, enable) } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt index 34a0d8edb3..615330463b 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt @@ -26,7 +26,7 @@ import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.events.model.Content -class FakeSessionAccountDataService : SessionAccountDataService by mockk() { +class FakeSessionAccountDataService : SessionAccountDataService by mockk(relaxed = true) { fun givenGetUserAccountDataEventReturns(type: String, content: Content) { every { getUserAccountDataEvent(type) } returns UserAccountDataEvent(type, content) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeTogglePushNotificationUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeTogglePushNotificationUseCase.kt new file mode 100644 index 0000000000..92e311cfb7 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeTogglePushNotificationUseCase.kt @@ -0,0 +1,33 @@ +/* + * 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.overview.TogglePushNotificationUseCase +import io.mockk.coJustRun +import io.mockk.coVerify +import io.mockk.mockk + +class FakeTogglePushNotificationUseCase { + + val instance = mockk { + coJustRun { execute(any(), any()) } + } + + fun verifyExecute(deviceId: String, enabled: Boolean) { + coVerify { instance.execute(deviceId, enabled) } + } +}