Merge pull request #7692 from vector-im/feature/mna/listen-notification-account-data

Update notifications setting when m.local_notification_settings.<device-id> event changes for current device (PSG-874)
This commit is contained in:
Maxime NATUREL 2022-12-06 14:12:01 +01:00 committed by GitHub
commit 6f0a95b828
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 377 additions and 29 deletions

1
changelog.d/7632.feature Normal file
View File

@ -0,0 +1 @@
Update notifications setting when m.local_notification_settings.<device-id> event changes for current device

View File

@ -0,0 +1,32 @@
/*
* 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.notification
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.matrix.android.sdk.api.session.Session
import javax.inject.Inject
class CanToggleNotificationsViaAccountDataUseCase @Inject constructor(
private val getNotificationSettingsAccountDataUpdatesUseCase: GetNotificationSettingsAccountDataUpdatesUseCase,
) {
fun execute(session: Session, deviceId: String): Flow<Boolean> {
return getNotificationSettingsAccountDataUpdatesUseCase.execute(session, deviceId)
.map { it?.isSilenced != null }
}
}

View File

@ -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.features.settings.devices.v2.notification
import androidx.lifecycle.asFlow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.events.model.toModel
import javax.inject.Inject
class GetNotificationSettingsAccountDataUpdatesUseCase @Inject constructor() {
fun execute(session: Session, deviceId: String): Flow<LocalNotificationSettingsContent?> {
return session
.accountDataService()
.getLiveUserAccountDataEvent(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId)
.asFlow()
.map { it.getOrNull()?.content?.toModel<LocalNotificationSettingsContent>() }
}
}

View File

@ -31,20 +31,30 @@ import javax.inject.Inject
class GetNotificationsStatusUseCase @Inject constructor( class GetNotificationsStatusUseCase @Inject constructor(
private val canToggleNotificationsViaPusherUseCase: CanToggleNotificationsViaPusherUseCase, private val canToggleNotificationsViaPusherUseCase: CanToggleNotificationsViaPusherUseCase,
private val checkIfCanToggleNotificationsViaAccountDataUseCase: CheckIfCanToggleNotificationsViaAccountDataUseCase, private val canToggleNotificationsViaAccountDataUseCase: CanToggleNotificationsViaAccountDataUseCase,
) { ) {
fun execute(session: Session, deviceId: String): Flow<NotificationsStatus> { fun execute(session: Session, deviceId: String): Flow<NotificationsStatus> {
return when { return canToggleNotificationsViaAccountDataUseCase.execute(session, deviceId)
checkIfCanToggleNotificationsViaAccountDataUseCase.execute(session, deviceId) -> { .flatMapLatest { canToggle ->
if (canToggle) {
notificationStatusFromAccountData(session, deviceId)
} else {
notificationStatusFromPusher(session, deviceId)
}
}
.distinctUntilChanged()
}
private fun notificationStatusFromAccountData(session: Session, deviceId: String) =
session.flow() session.flow()
.liveUserAccountData(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId) .liveUserAccountData(UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + deviceId)
.unwrap() .unwrap()
.map { it.content.toModel<LocalNotificationSettingsContent>()?.isSilenced?.not() } .map { it.content.toModel<LocalNotificationSettingsContent>()?.isSilenced?.not() }
.map { if (it == true) NotificationsStatus.ENABLED else NotificationsStatus.DISABLED } .map { if (it == true) NotificationsStatus.ENABLED else NotificationsStatus.DISABLED }
.distinctUntilChanged()
} private fun notificationStatusFromPusher(session: Session, deviceId: String) =
else -> canToggleNotificationsViaPusherUseCase.execute(session) canToggleNotificationsViaPusherUseCase.execute(session)
.flatMapLatest { canToggle -> .flatMapLatest { canToggle ->
if (canToggle) { if (canToggle) {
session.flow() session.flow()
@ -63,6 +73,4 @@ class GetNotificationsStatusUseCase @Inject constructor(
flowOf(NotificationsStatus.NOT_SUPPORTED) flowOf(NotificationsStatus.NOT_SUPPORTED)
} }
} }
}
}
} }

View File

@ -16,6 +16,8 @@
package im.vector.app.features.settings.notifications package im.vector.app.features.settings.notifications
import android.content.SharedPreferences
import androidx.annotation.VisibleForTesting
import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.MavericksViewModelFactory
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
@ -50,6 +52,31 @@ class VectorSettingsNotificationPreferenceViewModel @AssistedInject constructor(
companion object : MavericksViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory() companion object : MavericksViewModelFactory<VectorSettingsNotificationPreferenceViewModel, VectorDummyViewState> by hiltMavericksViewModelFactory()
@VisibleForTesting
val notificationsPreferenceListener: SharedPreferences.OnSharedPreferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener { _, key ->
if (key == VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY) {
if (vectorPreferences.areNotificationEnabledForDevice()) {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled)
} else {
_viewEvents.post(VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled)
}
}
}
init {
observeNotificationsEnabledPreference()
}
private fun observeNotificationsEnabledPreference() {
vectorPreferences.subscribeToChanges(notificationsPreferenceListener)
}
override fun onCleared() {
vectorPreferences.unsubscribeToChanges(notificationsPreferenceListener)
super.onCleared()
}
override fun handle(action: VectorSettingsNotificationPreferenceViewAction) { override fun handle(action: VectorSettingsNotificationPreferenceViewAction) {
when (action) { when (action) {
VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice() VectorSettingsNotificationPreferenceViewAction.DisableNotificationsForDevice -> handleDisableNotificationsForDevice()

View File

@ -0,0 +1,88 @@
/*
* 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.notification
import im.vector.app.test.fakes.FakeSession
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBe
import org.junit.Test
import org.matrix.android.sdk.api.account.LocalNotificationSettingsContent
class CanToggleNotificationsViaAccountDataUseCaseTest {
private val fakeGetNotificationSettingsAccountDataUpdatesUseCase = mockk<GetNotificationSettingsAccountDataUpdatesUseCase>()
private val canToggleNotificationsViaAccountDataUseCase = CanToggleNotificationsViaAccountDataUseCase(
getNotificationSettingsAccountDataUpdatesUseCase = fakeGetNotificationSettingsAccountDataUpdatesUseCase,
)
@Test
fun `given current session and content for account data when execute then true is returned`() = runTest {
// Given
val aSession = FakeSession()
val aDeviceId = "aDeviceId"
val localNotificationSettingsContent = LocalNotificationSettingsContent(
isSilenced = true,
)
every { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(any(), any()) } returns flowOf(localNotificationSettingsContent)
// When
val result = canToggleNotificationsViaAccountDataUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBe true
verify { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId) }
}
@Test
fun `given current session and empty content for account data when execute then false is returned`() = runTest {
// Given
val aSession = FakeSession()
val aDeviceId = "aDeviceId"
val localNotificationSettingsContent = LocalNotificationSettingsContent(
isSilenced = null,
)
every { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(any(), any()) } returns flowOf(localNotificationSettingsContent)
// When
val result = canToggleNotificationsViaAccountDataUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBe false
verify { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId) }
}
@Test
fun `given current session and no related account data when execute then false is returned`() = runTest {
// Given
val aSession = FakeSession()
val aDeviceId = "aDeviceId"
every { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(any(), any()) } returns flowOf(null)
// When
val result = canToggleNotificationsViaAccountDataUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBe false
verify { fakeGetNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId) }
}
}

View File

@ -0,0 +1,109 @@
/*
* 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.notification
import im.vector.app.test.fakes.FakeFlowLiveDataConversions
import im.vector.app.test.fakes.FakeSession
import im.vector.app.test.fakes.givenAsFlow
import io.mockk.unmockkAll
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.test.runTest
import org.amshove.kluent.shouldBeEqualTo
import org.junit.After
import org.junit.Before
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 GetNotificationSettingsAccountDataUpdatesUseCaseTest {
private val fakeFlowLiveDataConversions = FakeFlowLiveDataConversions()
private val getNotificationSettingsAccountDataUpdatesUseCase = GetNotificationSettingsAccountDataUpdatesUseCase()
@Before
fun setUp() {
fakeFlowLiveDataConversions.setup()
}
@After
fun tearDown() {
unmockkAll()
}
@Test
fun `given a device id when execute then retrieve the account data event corresponding to this id if any`() = runTest {
// Given
val aDeviceId = "device-id"
val aSession = FakeSession()
val expectedContent = LocalNotificationSettingsContent(isSilenced = true)
aSession
.accountDataService()
.givenGetLiveUserAccountDataEventReturns(
type = UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + aDeviceId,
content = expectedContent.toContent(),
)
.givenAsFlow()
// When
val result = getNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBeEqualTo expectedContent
}
@Test
fun `given a device id and no content for account data when execute then retrieve the account data event corresponding to this id if any`() = runTest {
// Given
val aDeviceId = "device-id"
val aSession = FakeSession()
aSession
.accountDataService()
.givenGetLiveUserAccountDataEventReturns(
type = UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + aDeviceId,
content = null,
)
.givenAsFlow()
// When
val result = getNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBeEqualTo null
}
@Test
fun `given a device id and empty content for account data when execute then retrieve the account data event corresponding to this id if any`() = runTest {
// Given
val aDeviceId = "device-id"
val aSession = FakeSession()
val expectedContent = LocalNotificationSettingsContent(isSilenced = null)
aSession
.accountDataService()
.givenGetLiveUserAccountDataEventReturns(
type = UserAccountDataTypes.TYPE_LOCAL_NOTIFICATION_SETTINGS + aDeviceId,
content = expectedContent.toContent(),
)
.givenAsFlow()
// When
val result = getNotificationSettingsAccountDataUpdatesUseCase.execute(aSession, aDeviceId).firstOrNull()
// Then
result shouldBeEqualTo expectedContent
}
}

View File

@ -22,6 +22,7 @@ import im.vector.app.test.fixtures.PusherFixture
import im.vector.app.test.testDispatcher import im.vector.app.test.testDispatcher
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verify
import io.mockk.verifyOrder import io.mockk.verifyOrder
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.flow.firstOrNull
@ -46,14 +47,14 @@ class GetNotificationsStatusUseCaseTest {
val instantTaskExecutorRule = InstantTaskExecutorRule() val instantTaskExecutorRule = InstantTaskExecutorRule()
private val fakeSession = FakeSession() private val fakeSession = FakeSession()
private val fakeCheckIfCanToggleNotificationsViaAccountDataUseCase = private val fakeCanToggleNotificationsViaAccountDataUseCase =
mockk<CheckIfCanToggleNotificationsViaAccountDataUseCase>() mockk<CanToggleNotificationsViaAccountDataUseCase>()
private val fakeCanToggleNotificationsViaPusherUseCase = private val fakeCanToggleNotificationsViaPusherUseCase =
mockk<CanToggleNotificationsViaPusherUseCase>() mockk<CanToggleNotificationsViaPusherUseCase>()
private val getNotificationsStatusUseCase = private val getNotificationsStatusUseCase =
GetNotificationsStatusUseCase( GetNotificationsStatusUseCase(
checkIfCanToggleNotificationsViaAccountDataUseCase = fakeCheckIfCanToggleNotificationsViaAccountDataUseCase, canToggleNotificationsViaAccountDataUseCase = fakeCanToggleNotificationsViaAccountDataUseCase,
canToggleNotificationsViaPusherUseCase = fakeCanToggleNotificationsViaPusherUseCase, canToggleNotificationsViaPusherUseCase = fakeCanToggleNotificationsViaPusherUseCase,
) )
@ -70,7 +71,7 @@ class GetNotificationsStatusUseCaseTest {
@Test @Test
fun `given current session and toggle is not supported when execute then resulting flow contains NOT_SUPPORTED value`() = runTest { fun `given current session and toggle is not supported when execute then resulting flow contains NOT_SUPPORTED value`() = runTest {
// Given // Given
every { fakeCheckIfCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns false every { fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns flowOf(false)
every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(false) every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(false)
// When // When
@ -80,7 +81,7 @@ class GetNotificationsStatusUseCaseTest {
result.firstOrNull() shouldBeEqualTo NotificationsStatus.NOT_SUPPORTED result.firstOrNull() shouldBeEqualTo NotificationsStatus.NOT_SUPPORTED
verifyOrder { verifyOrder {
// we should first check account data // we should first check account data
fakeCheckIfCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID)
fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession)
} }
} }
@ -95,7 +96,7 @@ class GetNotificationsStatusUseCaseTest {
) )
) )
fakeSession.pushersService().givenPushersLive(pushers) fakeSession.pushersService().givenPushersLive(pushers)
every { fakeCheckIfCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns false every { fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns flowOf(false)
every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(true) every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(true)
// When // When
@ -109,7 +110,7 @@ class GetNotificationsStatusUseCaseTest {
fun `given toggle via pusher is supported and no registered pusher when execute then resulting flow contains NOT_SUPPORTED value`() = runTest { fun `given toggle via pusher is supported and no registered pusher when execute then resulting flow contains NOT_SUPPORTED value`() = runTest {
// Given // Given
fakeSession.pushersService().givenPushersLive(emptyList()) fakeSession.pushersService().givenPushersLive(emptyList())
every { fakeCheckIfCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns false every { fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns flowOf(false)
every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(true) every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(true)
// When // When
@ -120,7 +121,7 @@ class GetNotificationsStatusUseCaseTest {
} }
@Test @Test
fun `given current session and toggle via account data is supported when execute then resulting flow contains status based on settings value`() = runTest { fun `given current session and toggle via account data is supported when execute then resulting flow contains status based on account data`() = runTest {
// Given // Given
fakeSession fakeSession
.accountDataService() .accountDataService()
@ -130,7 +131,7 @@ class GetNotificationsStatusUseCaseTest {
isSilenced = false isSilenced = false
).toContent(), ).toContent(),
) )
every { fakeCheckIfCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns true every { fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID) } returns flowOf(true)
every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(false) every { fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession) } returns flowOf(false)
// When // When
@ -138,5 +139,11 @@ class GetNotificationsStatusUseCaseTest {
// Then // Then
result.firstOrNull() shouldBeEqualTo NotificationsStatus.ENABLED result.firstOrNull() shouldBeEqualTo NotificationsStatus.ENABLED
verify {
fakeCanToggleNotificationsViaAccountDataUseCase.execute(fakeSession, A_DEVICE_ID)
}
verify(inverse = true) {
fakeCanToggleNotificationsViaPusherUseCase.execute(fakeSession)
}
} }
} }

View File

@ -21,6 +21,7 @@ import im.vector.app.core.platform.VectorDummyViewState
import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase import im.vector.app.core.pushers.EnsureFcmTokenIsRetrievedUseCase
import im.vector.app.core.pushers.RegisterUnifiedPushUseCase import im.vector.app.core.pushers.RegisterUnifiedPushUseCase
import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase import im.vector.app.core.pushers.UnregisterUnifiedPushUseCase
import im.vector.app.features.settings.VectorPreferences.Companion.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY
import im.vector.app.test.fakes.FakePushersManager import im.vector.app.test.fakes.FakePushersManager
import im.vector.app.test.fakes.FakeVectorPreferences import im.vector.app.test.fakes.FakeVectorPreferences
import im.vector.app.test.test import im.vector.app.test.test
@ -60,6 +61,40 @@ class VectorSettingsNotificationPreferenceViewModelTest {
toggleNotificationsForCurrentSessionUseCase = fakeToggleNotificationsForCurrentSessionUseCase, toggleNotificationsForCurrentSessionUseCase = fakeToggleNotificationsForCurrentSessionUseCase,
) )
@Test
fun `given view model init when notifications are enabled in preferences then view event is posted`() {
// Given
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(true)
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceEnabled
val viewModel = createViewModel()
// When
val viewModelTest = viewModel.test()
viewModel.notificationsPreferenceListener.onSharedPreferenceChanged(mockk(), SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
// Then
viewModelTest
.assertEvent { event -> event == expectedEvent }
.finish()
}
@Test
fun `given view model init when notifications are disabled in preferences then view event is posted`() {
// Given
fakeVectorPreferences.givenAreNotificationsEnabledForDevice(false)
val expectedEvent = VectorSettingsNotificationPreferenceViewEvent.NotificationsForDeviceDisabled
val viewModel = createViewModel()
// When
val viewModelTest = viewModel.test()
viewModel.notificationsPreferenceListener.onSharedPreferenceChanged(mockk(), SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
// Then
viewModelTest
.assertEvent { event -> event == expectedEvent }
.finish()
}
@Test @Test
fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() { fun `given DisableNotificationsForDevice action when handling action then disable use case is called`() {
// Given // Given

View File

@ -16,6 +16,8 @@
package im.vector.app.test.fakes package im.vector.app.test.fakes
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import io.mockk.coEvery import io.mockk.coEvery
import io.mockk.coVerify import io.mockk.coVerify
import io.mockk.every import io.mockk.every
@ -25,6 +27,8 @@ import io.mockk.runs
import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService 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.accountdata.UserAccountDataEvent
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
class FakeSessionAccountDataService : SessionAccountDataService by mockk(relaxed = true) { class FakeSessionAccountDataService : SessionAccountDataService by mockk(relaxed = true) {
@ -32,6 +36,13 @@ class FakeSessionAccountDataService : SessionAccountDataService by mockk(relaxed
every { getUserAccountDataEvent(type) } returns content?.let { UserAccountDataEvent(type, it) } every { getUserAccountDataEvent(type) } returns content?.let { UserAccountDataEvent(type, it) }
} }
fun givenGetLiveUserAccountDataEventReturns(type: String, content: Content?): LiveData<Optional<UserAccountDataEvent>> {
return MutableLiveData(content?.let { UserAccountDataEvent(type, it) }.toOptional())
.also {
every { getLiveUserAccountDataEvent(type) } returns it
}
}
fun givenUpdateUserAccountDataEventSucceeds() { fun givenUpdateUserAccountDataEventSucceeds() {
coEvery { updateUserAccountData(any(), any()) } just runs coEvery { updateUserAccountData(any(), any()) } just runs
} }

View File

@ -16,7 +16,6 @@
package im.vector.app.test.fakes package im.vector.app.test.fakes
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import im.vector.app.features.settings.BackgroundSyncMode import im.vector.app.features.settings.BackgroundSyncMode
import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorPreferences
import io.mockk.every import io.mockk.every
@ -78,10 +77,4 @@ class FakeVectorPreferences {
fun givenIsBackgroundSyncEnabled(isEnabled: Boolean) { fun givenIsBackgroundSyncEnabled(isEnabled: Boolean) {
every { instance.isBackgroundSyncEnabled() } returns isEnabled every { instance.isBackgroundSyncEnabled() } returns isEnabled
} }
fun givenChangeOnPreference(key: String) {
every { instance.subscribeToChanges(any()) } answers {
firstArg<OnSharedPreferenceChangeListener>().onSharedPreferenceChanged(mockk(), key)
}
}
} }