From 5ced831d532cc3390cc267d38864a79a1f917b2b Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 28 Sep 2022 15:57:22 -0400 Subject: [PATCH 01/33] Adds push notifications switch --- .../src/main/res/values/strings.xml | 2 + .../stylable_session_overview_entry_view.xml | 6 ++ .../SessionOverviewEntrySwitchView.kt | 73 +++++++++++++++++++ .../res/layout/fragment_session_overview.xml | 10 +++ .../view_session_overview_entry_switch.xml | 51 +++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt create mode 100644 vector/src/main/res/layout/view_session_overview_entry_switch.xml diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index c4360441531..dd6b51bca97 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -3291,6 +3291,8 @@ Clear Filter Session details Application, device, and activity information. + Push notifications + Receive push notifications on this session. Session name Session ID Last activity diff --git a/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml b/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml index d3884f247d9..6428cd6eac1 100644 --- a/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml +++ b/library/ui-styles/src/main/res/values/stylable_session_overview_entry_view.xml @@ -6,4 +6,10 @@ + + + + + + diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt new file mode 100644 index 00000000000..c0bc7ad4581 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -0,0 +1,73 @@ +/* + * 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 android.content.Context +import android.content.res.TypedArray +import android.util.AttributeSet +import android.view.LayoutInflater +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.res.use +import im.vector.app.R +import im.vector.app.core.extensions.setAttributeBackground +import im.vector.app.databinding.ViewSessionOverviewEntryBinding +import im.vector.app.databinding.ViewSessionOverviewEntrySwitchBinding + +class SessionOverviewEntrySwitchView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0 +) : ConstraintLayout(context, attrs, defStyleAttr) { + + private val binding = ViewSessionOverviewEntrySwitchBinding.inflate( + LayoutInflater.from(context), + this + ) + + init { + initBackground() + context.obtainStyledAttributes( + attrs, + R.styleable.SessionOverviewEntrySwitchView, + 0, + 0 + ).use { + setTitle(it) + setDescription(it) + setSwitchedEnabled(it) + } + } + + private fun initBackground() { + binding.root.setAttributeBackground(android.R.attr.selectableItemBackground) + } + + private fun setTitle(typedArray: TypedArray) { + val title = typedArray.getString(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchTitle) + binding.sessionsOverviewEntryTitle.text = title + } + + private fun setDescription(typedArray: TypedArray) { + val description = typedArray.getString(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchDescription) + binding.sessionsOverviewEntryDescription.text = description + } + + private fun setSwitchedEnabled(typedArray: TypedArray) { + val enabled = typedArray.getBoolean(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchEnabled, true) + binding.sessionsOverviewEntrySwitch.isChecked = enabled + } +} diff --git a/vector/src/main/res/layout/fragment_session_overview.xml b/vector/src/main/res/layout/fragment_session_overview.xml index f4573ef85e3..32229d523c6 100644 --- a/vector/src/main/res/layout/fragment_session_overview.xml +++ b/vector/src/main/res/layout/fragment_session_overview.xml @@ -31,6 +31,16 @@ app:sessionOverviewEntryDescription="@string/device_manager_session_details_description" app:sessionOverviewEntryTitle="@string/device_manager_session_details_title" /> + + diff --git a/vector/src/main/res/layout/view_session_overview_entry_switch.xml b/vector/src/main/res/layout/view_session_overview_entry_switch.xml new file mode 100644 index 00000000000..34d68abf6ee --- /dev/null +++ b/vector/src/main/res/layout/view_session_overview_entry_switch.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + From e1b78b97ac30145f1765980ead76ffe630dc4f78 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 28 Sep 2022 17:28:44 -0400 Subject: [PATCH 02/33] Adds functionality to Push notification toggle --- .../sdk/api/session/pushers/PushersService.kt | 8 +++ .../session/pushers/DefaultPushersService.kt | 19 +++++++ .../internal/session/pushers/PushersModule.kt | 3 + .../session/pushers/TogglePusherTask.kt | 55 +++++++++++++++++++ .../v2/overview/SessionOverviewAction.kt | 8 ++- .../SessionOverviewEntrySwitchView.kt | 9 +++ .../v2/overview/SessionOverviewFragment.kt | 18 +++++- .../v2/overview/SessionOverviewViewModel.kt | 26 ++++++++- .../v2/overview/SessionOverviewViewState.kt | 2 + 9 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index d7958ea3cdd..517809b906c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -67,6 +67,14 @@ interface PushersService { append: Boolean = true ) + /** + * Enables or disables a registered pusher + * + * @param pusher The pusher being toggled + * @param enable Whether the pusher should be enabled or disabled + */ + suspend fun togglePusher(pusher: Pusher, enable: Boolean) + /** * Directly ask the push gateway to send a push to this device. * If successful, the push gateway has accepted the request. In this case, the app should receive a Push with the provided eventId. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt index 082b5b63ebc..e89cfa508c6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersService.kt @@ -42,6 +42,7 @@ internal class DefaultPushersService @Inject constructor( private val getPusherTask: GetPushersTask, private val pushGatewayNotifyTask: PushGatewayNotifyTask, private val addPusherTask: AddPusherTask, + private val togglePusherTask: TogglePusherTask, private val removePusherTask: RemovePusherTask, private val taskExecutor: TaskExecutor ) : PushersService { @@ -108,6 +109,24 @@ internal class DefaultPushersService @Inject constructor( ) } + override suspend fun togglePusher(pusher: Pusher, enable: Boolean) { + togglePusherTask.execute(TogglePusherTask.Params(pusher.toJsonPusher(), enable)) + } + + private fun Pusher.toJsonPusher() = JsonPusher( + pushKey = pushKey, + kind = kind, + appId = appId, + appDisplayName = appDisplayName, + deviceDisplayName = deviceDisplayName, + profileTag = profileTag, + lang = lang, + data = JsonPusherData(data.url, data.format), + append = false, + enabled = enabled, + deviceId = deviceId, + ) + private fun enqueueAddPusher(pusher: JsonPusher): UUID { val params = AddPusherWorker.Params(sessionId, pusher) val request = workManagerProvider.matrixOneTimeWorkRequestBuilder() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt index 4528c95e691..37c1c0c3ad7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/PushersModule.kt @@ -68,6 +68,9 @@ internal abstract class PushersModule { @Binds abstract fun bindAddPusherTask(task: DefaultAddPusherTask): AddPusherTask + @Binds + abstract fun bindTogglePusherTask(task: DefaultTogglePusherTask): TogglePusherTask + @Binds abstract fun bindRemovePusherTask(task: DefaultRemovePusherTask): RemovePusherTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt new file mode 100644 index 00000000000..14463ca89a7 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.session.pushers + +import com.zhuinden.monarchy.Monarchy +import org.matrix.android.sdk.api.session.pushers.PusherState +import org.matrix.android.sdk.internal.database.mapper.toEntity +import org.matrix.android.sdk.internal.database.model.PusherEntity +import org.matrix.android.sdk.internal.database.query.where +import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.network.GlobalErrorReceiver +import org.matrix.android.sdk.internal.network.RequestExecutor +import org.matrix.android.sdk.internal.network.executeRequest +import org.matrix.android.sdk.internal.task.Task +import org.matrix.android.sdk.internal.util.awaitTransaction +import javax.inject.Inject + +internal interface TogglePusherTask : Task { + data class Params(val pusher: JsonPusher, val enable: Boolean) +} + +internal class DefaultTogglePusherTask @Inject constructor( + private val pushersAPI: PushersAPI, + @SessionDatabase private val monarchy: Monarchy, + private val requestExecutor: RequestExecutor, + private val globalErrorReceiver: GlobalErrorReceiver +) : TogglePusherTask { + + override suspend fun execute(params: TogglePusherTask.Params) { + val pusher = params.pusher.copy(enabled = params.enable) + + requestExecutor.executeRequest(globalErrorReceiver) { + pushersAPI.setPusher(pusher) + } + + monarchy.awaitTransaction { realm -> + val entity = PusherEntity.where(realm, params.pusher.pushKey).findFirst() + entity?.apply { enabled = params.enable }?.let { realm.insertOrUpdate(it) } + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt index c028c08ec46..4b383f5144f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt @@ -18,4 +18,10 @@ package im.vector.app.features.settings.devices.v2.overview import im.vector.app.core.platform.VectorViewModelAction -sealed class SessionOverviewAction : VectorViewModelAction +sealed class SessionOverviewAction : VectorViewModelAction { + + data class TogglePushNotifications( + val deviceId: String, + val enabled: Boolean, + ) : SessionOverviewAction() +} diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt index c0bc7ad4581..eaebb28cb0c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -20,6 +20,7 @@ import android.content.Context import android.content.res.TypedArray import android.util.AttributeSet import android.view.LayoutInflater +import android.widget.CompoundButton import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.res.use import im.vector.app.R @@ -70,4 +71,12 @@ class SessionOverviewEntrySwitchView @JvmOverloads constructor( val enabled = typedArray.getBoolean(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchEnabled, true) binding.sessionsOverviewEntrySwitch.isChecked = enabled } + + fun setChecked(checked: Boolean) { + binding.sessionsOverviewEntrySwitch.isChecked = checked + } + + fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener) { + binding.sessionsOverviewEntrySwitch.setOnCheckedChangeListener(listener) + } } 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 3fea7a9316e..97c64774dd0 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 @@ -81,7 +81,8 @@ class SessionOverviewFragment : override fun invalidate() = withState(viewModel) { state -> updateToolbar(state.isCurrentSession) - updateEntryDetails(state.deviceId) + updateSessionInfo(state.deviceId) + updatePushNotificationToggle(state.deviceId, state.pushers.invoke()?.all { it.enabled } == true) if (state.deviceInfo is Success) { renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) } else { @@ -96,12 +97,25 @@ class SessionOverviewFragment : ?.setTitle(titleResId) } - private fun updateEntryDetails(deviceId: String) { + private fun updateSessionInfo(deviceId: String) { views.sessionOverviewEntryDetails.setOnClickListener { viewNavigator.navigateToSessionDetails(requireContext(), deviceId) } } + private fun updatePushNotificationToggle(deviceId: String, checked: Boolean) { + views.sessionOverviewPushNotifications.apply { + setOnCheckedChangeListener { _, _ -> } + setChecked(checked) + post { + setOnCheckedChangeListener { _, isChecked -> + viewModel.handle(SessionOverviewAction.TogglePushNotifications(deviceId, isChecked)) + } + } + } + + } + private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) { views.sessionOverviewInfo.isVisible = true val viewState = SessionInfoViewState( 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 bdcdc40c56d..2f52a06c2c2 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 @@ -26,12 +26,15 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.flow.flow class SessionOverviewViewModel @AssistedInject constructor( @Assisted val initialState: SessionOverviewViewState, - session: Session, + private val session: Session, private val getDeviceFullInfoUseCase: GetDeviceFullInfoUseCase, ) : VectorViewModel(initialState) { @@ -49,6 +52,7 @@ class SessionOverviewViewModel @AssistedInject constructor( } observeSessionInfo(initialState.deviceId) + observePushers(initialState.deviceId) } private fun observeSessionInfo(deviceId: String) { @@ -57,7 +61,25 @@ class SessionOverviewViewModel @AssistedInject constructor( .launchIn(viewModelScope) } + private fun observePushers(deviceId: String) { + session.flow() + .livePushers() + .map { it.filter { pusher -> pusher.deviceId == deviceId }} + .execute { copy(pushers = it) } + } + override fun handle(action: SessionOverviewAction) { - TODO("Implement when adding the first action") + when (action) { + is SessionOverviewAction.TogglePushNotifications -> handleTogglePusherAction(action) + } + } + + 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) + } + } } } 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 a447336c233..0b69b0401b5 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,11 +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 isCurrentSession: Boolean = false, val deviceInfo: Async = Uninitialized, + val pushers: Async> = Uninitialized, ) : MavericksState { constructor(args: SessionOverviewArgs) : this( deviceId = args.deviceId From 233d07e0d6ff45bb0115aa605e70c3f0dbda945d Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 12:03:18 -0400 Subject: [PATCH 03/33] Adds DefaultPushersServiceTest for togglePusher --- .../pushers/DefaultPushersServiceTest.kt | 66 +++++++++++++++++++ .../sdk/test/fakes/FakeAddPusherTask.kt | 22 +++++++ .../sdk/test/fakes/FakeGetPushersTask.kt | 22 +++++++ .../sdk/test/fakes/FakeRemovePusherTask.kt | 22 +++++++ .../sdk/test/fakes/FakeTaskExecutor.kt | 25 +++++++ .../sdk/test/fakes/FakeTogglePusherTask.kt | 35 ++++++++++ .../internal/FakePushGatewayNotifyTask.kt | 22 +++++++ .../sdk/test/fixtures/PusherFixture.kt | 50 ++++++++++++++ 8 files changed, 264 insertions(+) create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt new file mode 100644 index 00000000000..064742edadd --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt @@ -0,0 +1,66 @@ +/* + * 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 org.matrix.android.sdk.internal.session.pushers + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.junit.Test +import org.matrix.android.sdk.test.fakes.FakeAddPusherTask +import org.matrix.android.sdk.test.fakes.FakeGetPushersTask +import org.matrix.android.sdk.test.fakes.FakeMonarchy +import org.matrix.android.sdk.test.fakes.FakeRemovePusherTask +import org.matrix.android.sdk.test.fakes.FakeTaskExecutor +import org.matrix.android.sdk.test.fakes.FakeTogglePusherTask +import org.matrix.android.sdk.test.fakes.FakeWorkManagerProvider +import org.matrix.android.sdk.test.fakes.internal.FakePushGatewayNotifyTask +import org.matrix.android.sdk.test.fixtures.PusherFixture + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultPushersServiceTest { + + private val workManagerProvider = FakeWorkManagerProvider() + private val monarchy = FakeMonarchy() + private val sessionId = "" + private val getPushersTask = FakeGetPushersTask() + private val pushGatewayNotifyTask = FakePushGatewayNotifyTask() + private val addPusherTask = FakeAddPusherTask() + private val togglePusherTask = FakeTogglePusherTask() + private val removePusherTask = FakeRemovePusherTask() + private val taskExecutor = FakeTaskExecutor() + + private val pushersService = DefaultPushersService( + workManagerProvider.instance, + monarchy.instance, + sessionId, + getPushersTask, + pushGatewayNotifyTask, + addPusherTask, + togglePusherTask, + removePusherTask, + taskExecutor.instance, + ) + + @Test + fun `when togglePusher, then execute task`() = runTest { + val pusher = PusherFixture.aPusher() + val enable = true + + pushersService.togglePusher(pusher, enable) + + togglePusherTask.verifyExecution(pusher, enable) + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt new file mode 100644 index 00000000000..57c3bdb7976 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt @@ -0,0 +1,22 @@ +/* + * 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 org.matrix.android.sdk.test.fakes + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.pushers.AddPusherTask + +class FakeAddPusherTask : AddPusherTask by mockk() diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt new file mode 100644 index 00000000000..462fd2ba7c6 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt @@ -0,0 +1,22 @@ +/* + * 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 org.matrix.android.sdk.test.fakes + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.pushers.GetPushersTask + +class FakeGetPushersTask : GetPushersTask by mockk() diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt new file mode 100644 index 00000000000..266eacde116 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt @@ -0,0 +1,22 @@ +/* + * 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 org.matrix.android.sdk.test.fakes + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.pushers.RemovePusherTask + +class FakeRemovePusherTask : RemovePusherTask by mockk() diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt new file mode 100644 index 00000000000..bf6109b36dd --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt @@ -0,0 +1,25 @@ +/* + * 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 org.matrix.android.sdk.test.fakes + +import io.mockk.mockk +import org.matrix.android.sdk.internal.task.TaskExecutor + +internal class FakeTaskExecutor { + + val instance: TaskExecutor = mockk() +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt new file mode 100644 index 00000000000..44bf99098ea --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt @@ -0,0 +1,35 @@ +/* + * 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 org.matrix.android.sdk.test.fakes + +import io.mockk.coVerify +import io.mockk.mockk +import io.mockk.slot +import org.amshove.kluent.shouldBeEqualTo +import org.matrix.android.sdk.api.session.pushers.Pusher +import org.matrix.android.sdk.internal.session.pushers.TogglePusherTask + +class FakeTogglePusherTask : TogglePusherTask by mockk(relaxed = true) { + + fun verifyExecution(pusher: Pusher, enable: Boolean) { + val slot = slot() + coVerify { execute(capture(slot)) } + val params = slot.captured + params.pusher.pushKey shouldBeEqualTo pusher.pushKey + params.enable shouldBeEqualTo enable + } +} diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt new file mode 100644 index 00000000000..01b1b8e0bcd --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt @@ -0,0 +1,22 @@ +/* + * 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 org.matrix.android.sdk.test.fakes.internal + +import io.mockk.mockk +import org.matrix.android.sdk.internal.session.pushers.gateway.PushGatewayNotifyTask + +class FakePushGatewayNotifyTask : PushGatewayNotifyTask by mockk() diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt new file mode 100644 index 00000000000..50a84f951f7 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt @@ -0,0 +1,50 @@ +/* + * 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 org.matrix.android.sdk.test.fixtures + +import org.matrix.android.sdk.api.session.pushers.Pusher +import org.matrix.android.sdk.api.session.pushers.PusherData +import org.matrix.android.sdk.api.session.pushers.PusherState + +object PusherFixture { + + fun aPusher( + pushKey: String = "", + kind: String = "", + appId: String = "", + appDisplayName: String? = "", + deviceDisplayName: String? = "", + profileTag: String? = null, + lang: String? = "", + data: PusherData = PusherData("f.o/_matrix/push/v1/notify", ""), + enabled: Boolean = true, + deviceId: String? = "", + state: PusherState = PusherState.REGISTERED, + ) = Pusher( + pushKey, + kind, + appId, + appDisplayName, + deviceDisplayName, + profileTag, + lang, + data, + enabled, + deviceId, + state, + ) +} From da80c082507af81aec3c462b3f456b7c1658804f Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 12:17:50 -0400 Subject: [PATCH 04/33] Adds DefaultTogglePusherTaskTest --- .../pushers/DefaultTogglePusherTaskTest.kt | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt new file mode 100644 index 00000000000..de79f77e717 --- /dev/null +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt @@ -0,0 +1,64 @@ +/* + * 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 org.matrix.android.sdk.internal.session.pushers + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test +import org.matrix.android.sdk.internal.database.model.PusherEntity +import org.matrix.android.sdk.internal.database.model.PusherEntityFields +import org.matrix.android.sdk.test.fakes.FakeGlobalErrorReceiver +import org.matrix.android.sdk.test.fakes.FakeMonarchy +import org.matrix.android.sdk.test.fakes.FakePushersAPI +import org.matrix.android.sdk.test.fakes.FakeRequestExecutor +import org.matrix.android.sdk.test.fakes.givenEqualTo +import org.matrix.android.sdk.test.fakes.givenFindFirst +import org.matrix.android.sdk.test.fixtures.JsonPusherFixture.aJsonPusher +import org.matrix.android.sdk.test.fixtures.PusherEntityFixture.aPusherEntity + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultTogglePusherTaskTest { + + private val pushersAPI = FakePushersAPI() + private val monarchy = FakeMonarchy() + private val requestExecutor = FakeRequestExecutor() + private val globalErrorReceiver = FakeGlobalErrorReceiver() + + private val togglePusherTask = DefaultTogglePusherTask(pushersAPI, monarchy.instance, requestExecutor, globalErrorReceiver) + + @Test + fun `execution toggles enable on both local and remote`() = runTest { + val jsonPusher = aJsonPusher(enabled = false) + val params = TogglePusherTask.Params(aJsonPusher(), true) + + val pusherEntity = aPusherEntity(enabled = false) + monarchy.givenWhere() + .givenEqualTo(PusherEntityFields.PUSH_KEY, jsonPusher.pushKey) + .givenFindFirst(pusherEntity) + + togglePusherTask.execute(params) + + val expectedPayload = jsonPusher.copy(enabled = true) + pushersAPI.verifySetPusher(expectedPayload) + monarchy.verifyInsertOrUpdate { + withArg { actual -> + actual.enabled shouldBeEqualTo true + } + } + } +} From 670ccebd47ea8caae94be00217630c5420d542e3 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 14:42:40 -0400 Subject: [PATCH 05/33] Adds SessionOverviewViewModelTest for toggling pusher --- vector/build.gradle | 1 + .../overview/SessionOverviewViewModelTest.kt | 40 +++++++++++++-- .../app/test/fakes/FakePushersService.kt | 16 ++++++ .../vector/app/test/fixtures/PusherFixture.kt | 50 +++++++++++++++++++ 4 files changed, 102 insertions(+), 5 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/PusherFixture.kt diff --git a/vector/build.gradle b/vector/build.gradle index ac3699454c1..9c63190a9a9 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -290,6 +290,7 @@ dependencies { // Plant Timber tree for test testImplementation libs.tests.timberJunitRule testImplementation libs.airbnb.mavericksTesting + testImplementation libs.androidx.coreTesting testImplementation(libs.jetbrains.coroutinesTest) { exclude group: "org.jetbrains.kotlinx", module: "kotlinx-coroutines-debug" } 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 8d4e49ef851..21c882f4e7f 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 @@ -16,10 +16,13 @@ package im.vector.app.features.settings.devices.v2.overview +import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import com.airbnb.mvrx.Loading import com.airbnb.mvrx.Success import com.airbnb.mvrx.test.MvRxTestRule import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.test.fakes.FakeSession +import im.vector.app.test.fixtures.PusherFixture.aPusher import im.vector.app.test.test import im.vector.app.test.testDispatcher import io.mockk.every @@ -37,11 +40,14 @@ class SessionOverviewViewModelTest { @get:Rule val mvRxTestRule = MvRxTestRule(testDispatcher = testDispatcher) + @get:Rule + val instantTaskExecutorRule = InstantTaskExecutorRule() + private val args = SessionOverviewArgs( deviceId = A_SESSION_ID ) private val fakeSession = FakeSession() - private val getDeviceFullInfoUseCase = mockk() + private val getDeviceFullInfoUseCase = mockk(relaxed = true) private fun createViewModel() = SessionOverviewViewModel( initialState = SessionOverviewViewState(args), @@ -51,20 +57,18 @@ class SessionOverviewViewModelTest { @Test fun `given the viewModel has been initialized then viewState is updated with session info`() { - // Given val sessionParams = givenIdForSession(A_SESSION_ID) val deviceFullInfo = mockk() every { getDeviceFullInfoUseCase.execute(A_SESSION_ID) } returns flowOf(deviceFullInfo) val expectedState = SessionOverviewViewState( deviceId = A_SESSION_ID, isCurrentSession = true, - deviceInfo = Success(deviceFullInfo) + deviceInfo = Success(deviceFullInfo), + pushers = Loading(), ) - // When val viewModel = createViewModel() - // Then viewModel.test() .assertLatestState { state -> state == expectedState } .finish() @@ -78,4 +82,30 @@ class SessionOverviewViewModelTest { fakeSession.givenSessionParams(sessionParams) return sessionParams } + + @Test + fun `when viewModel init, then observe pushers and emit to state`() { + val pushers = listOf(aPusher(deviceId = A_SESSION_ID)) + fakeSession.pushersService().givenPushersLive(pushers) + + val viewModel = createViewModel() + + viewModel.test() + .assertLatestState { state -> state.pushers.invoke() == pushers } + .finish() + } + + @Test + fun `when handle TogglePushNotifications, then toggle enabled for device pushers`() { + val pushers = listOf( + aPusher(deviceId = A_SESSION_ID, enabled = false), + aPusher(deviceId = "another id", enabled = false) + ) + fakeSession.pushersService().givenPushersLive(pushers) + + val viewModel = createViewModel() + viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID, true)) + + fakeSession.pushersService().verifyOnlyTogglePusherCalled(pushers.first(), true) + } } 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 9e11b868718..60d50eab033 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 @@ -16,14 +16,30 @@ 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.mockk import io.mockk.slot import io.mockk.verify import org.matrix.android.sdk.api.session.pushers.HttpPusher +import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.pushers.PushersService class FakePushersService : PushersService by mockk(relaxed = true) { + fun givenPushersLive(pushers: List) { + every { getPushersLive() } returns liveData { emit(pushers) } + } + + fun verifyOnlyTogglePusherCalled(pusher: Pusher, enable: Boolean) { + coVerify(ordering = Ordering.ALL) { + getPushersLive() // verifies only getPushersLive and the following togglePusher was called + togglePusher(pusher, enable) + } + } + fun verifyEnqueueAddHttpPusher(): HttpPusher { val httpPusherSlot = slot() verify { enqueueAddHttpPusher(capture(httpPusherSlot)) } diff --git a/vector/src/test/java/im/vector/app/test/fixtures/PusherFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/PusherFixture.kt new file mode 100644 index 00000000000..300c66eca38 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/PusherFixture.kt @@ -0,0 +1,50 @@ +/* + * 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.fixtures + +import org.matrix.android.sdk.api.session.pushers.Pusher +import org.matrix.android.sdk.api.session.pushers.PusherData +import org.matrix.android.sdk.api.session.pushers.PusherState + +object PusherFixture { + + fun aPusher( + pushKey: String = "", + kind: String = "", + appId: String = "", + appDisplayName: String? = "", + deviceDisplayName: String? = "", + profileTag: String? = null, + lang: String? = "", + data: PusherData = PusherData("f.o/_matrix/push/v1/notify", ""), + enabled: Boolean = true, + deviceId: String? = "", + state: PusherState = PusherState.REGISTERED, + ) = Pusher( + pushKey, + kind, + appId, + appDisplayName, + deviceDisplayName, + profileTag, + lang, + data, + enabled, + deviceId, + state, + ) +} From 71558edde17b48f294ddfd8bdf5e9e7ad9300f39 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 14:48:33 -0400 Subject: [PATCH 06/33] Hides pusher toggle if there are no pushers of the device --- .../v2/overview/SessionOverviewFragment.kt | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) 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 97c64774dd0..c23367e15cc 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 @@ -36,6 +36,7 @@ import im.vector.app.core.resources.DrawableProvider import im.vector.app.databinding.FragmentSessionOverviewBinding import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState +import org.matrix.android.sdk.api.session.pushers.Pusher import javax.inject.Inject /** @@ -82,7 +83,7 @@ class SessionOverviewFragment : override fun invalidate() = withState(viewModel) { state -> updateToolbar(state.isCurrentSession) updateSessionInfo(state.deviceId) - updatePushNotificationToggle(state.deviceId, state.pushers.invoke()?.all { it.enabled } == true) + updatePushNotificationToggle(state.deviceId, state.pushers.invoke().orEmpty()) if (state.deviceInfo is Success) { renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) } else { @@ -103,17 +104,21 @@ class SessionOverviewFragment : } } - private fun updatePushNotificationToggle(deviceId: String, checked: Boolean) { + private fun updatePushNotificationToggle(deviceId: String, pushers: List) { views.sessionOverviewPushNotifications.apply { - setOnCheckedChangeListener { _, _ -> } - setChecked(checked) - post { - setOnCheckedChangeListener { _, isChecked -> - viewModel.handle(SessionOverviewAction.TogglePushNotifications(deviceId, isChecked)) + if (pushers.isEmpty()) { + isVisible = false + } else { + val allPushersAreEnabled = pushers.all { it.enabled } + setOnCheckedChangeListener { _, _ -> } + setChecked(allPushersAreEnabled) + post { + setOnCheckedChangeListener { _, isChecked -> + viewModel.handle(SessionOverviewAction.TogglePushNotifications(deviceId, isChecked)) + } } } } - } private fun renderSessionInfo(isCurrentSession: Boolean, deviceFullInfo: DeviceFullInfo) { From 3cc22c5366f9b108c5e1859f64a9247fc03d6e3b Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 14:49:45 -0400 Subject: [PATCH 07/33] Adds changelog file --- changelog.d/7261.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7261.wip diff --git a/changelog.d/7261.wip b/changelog.d/7261.wip new file mode 100644 index 00000000000..d7e454d9b66 --- /dev/null +++ b/changelog.d/7261.wip @@ -0,0 +1 @@ +Adds pusher toggle setting to (new) device manager From 66b8ebd7f994a1a8795aa9a5b740c7d608e6e889 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Thu, 29 Sep 2022 14:50:02 -0400 Subject: [PATCH 08/33] Edits changelog file --- changelog.d/7261.wip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/7261.wip b/changelog.d/7261.wip index d7e454d9b66..f7063fcc1b9 100644 --- a/changelog.d/7261.wip +++ b/changelog.d/7261.wip @@ -1 +1 @@ -Adds pusher toggle setting to (new) device manager +Adds pusher toggle setting to device manager v2 From ae2a02c4ef9edb770b7c70ced6881477fb4bf23c Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 3 Oct 2022 18:00:01 -0400 Subject: [PATCH 09/33] Fixes copyrights --- .../sdk/internal/session/pushers/DefaultPushersServiceTest.kt | 4 ++-- .../internal/session/pushers/DefaultTogglePusherTaskTest.kt | 4 ++-- .../org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt | 4 ++-- .../org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt index 064742edadd..a00ac3a17d5 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultPushersServiceTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt index de79f77e717..3c54f6f1e12 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/session/pushers/DefaultTogglePusherTaskTest.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt index 57c3bdb7976..16cdd7a6264 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeAddPusherTask.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt index 462fd2ba7c6..d5a41bb0e00 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeGetPushersTask.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, From 47e549193a9c76fb14937f2c3c0db8ab1d6b2510 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 3 Oct 2022 18:00:59 -0400 Subject: [PATCH 10/33] Unregisters checkedChangelistener in onDetachedFromWindow for switch view --- .../devices/v2/overview/SessionOverviewEntrySwitchView.kt | 7 ++++++- .../devices/v2/overview/SessionOverviewFragment.kt | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt index eaebb28cb0c..3b1d72fcc73 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -76,7 +76,12 @@ class SessionOverviewEntrySwitchView @JvmOverloads constructor( binding.sessionsOverviewEntrySwitch.isChecked = checked } - fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener) { + fun setOnCheckedChangeListener(listener: CompoundButton.OnCheckedChangeListener?) { binding.sessionsOverviewEntrySwitch.setOnCheckedChangeListener(listener) } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + binding.sessionsOverviewEntrySwitch.setOnCheckedChangeListener(null) + } } 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 c23367e15cc..143f5ac26ed 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 @@ -110,7 +110,7 @@ class SessionOverviewFragment : isVisible = false } else { val allPushersAreEnabled = pushers.all { it.enabled } - setOnCheckedChangeListener { _, _ -> } + setOnCheckedChangeListener(null) setChecked(allPushersAreEnabled) post { setOnCheckedChangeListener { _, isChecked -> From d91bbfd3c07b2b59b2b7855fbef6dde82e4f6b1c Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 3 Oct 2022 19:39:45 -0400 Subject: [PATCH 11/33] Links notification settings toggle to pusher service --- .../vector/app/core/pushers/PushersManager.kt | 13 +++++++ ...rSettingsNotificationPreferenceFragment.kt | 9 +++++ .../app/core/pushers/PushersManagerTest.kt | 34 +++++++++++++++++ .../overview/SessionOverviewViewModelTest.kt | 2 +- .../app/test/fakes/FakePushersService.kt | 13 ++++++- .../app/test/fixtures/CredentialsFixture.kt | 38 +++++++++++++++++++ .../app/test/fixtures/SessionParamsFixture.kt | 38 +++++++++++++++++++ 7 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/CredentialsFixture.kt create mode 100644 vector/src/test/java/im/vector/app/test/fixtures/SessionParamsFixture.kt diff --git a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt index 67e7868df74..9c52c3eb66a 100644 --- a/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt +++ b/vector/src/main/java/im/vector/app/core/pushers/PushersManager.kt @@ -23,6 +23,7 @@ import im.vector.app.core.resources.AppNameProvider import im.vector.app.core.resources.LocaleProvider import im.vector.app.core.resources.StringProvider import org.matrix.android.sdk.api.session.pushers.HttpPusher +import org.matrix.android.sdk.api.session.pushers.Pusher import java.util.UUID import javax.inject.Inject import kotlin.math.abs @@ -89,6 +90,18 @@ class PushersManager @Inject constructor( ) } + fun getPusherForCurrentSession(): Pusher? { + val session = activeSessionHolder.getSafeActiveSession() ?: return null + val deviceId = session.sessionParams.deviceId + return session.pushersService().getPushers().firstOrNull { it.deviceId == deviceId } + } + + suspend fun togglePusherForCurrentSession(enable: Boolean) { + val session = activeSessionHolder.getSafeActiveSession() ?: return + val pusher = getPusherForCurrentSession() ?: return + session.pushersService().togglePusher(pusher, enable) + } + suspend fun unregisterEmailPusher(email: String) { val currentSession = activeSessionHolder.getSafeActiveSession() ?: return currentSession.pushersService().removeEmailPusher(email) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt index 37d09d02c94..de96d687e4e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt @@ -54,6 +54,7 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.settings.VectorSettingsBaseFragment import im.vector.app.features.settings.VectorSettingsFragmentInteractionListener import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session @@ -61,6 +62,7 @@ import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.pushrules.RuleKind +import org.matrix.android.sdk.flow.flow import javax.inject.Inject // Referenced in vector_settings_preferences_root.xml @@ -104,6 +106,10 @@ class VectorSettingsNotificationPreferenceFragment : } findPreference(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)?.let { + pushersManager.getPusherForCurrentSession()?.let { pusher -> + it.isChecked = pusher.enabled + } + it.setTransactionalSwitchChangeListener(lifecycleScope) { isChecked -> if (isChecked) { unifiedPushHelper.register(requireActivity()) { @@ -117,6 +123,9 @@ class VectorSettingsNotificationPreferenceFragment : } findPreference(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY) ?.summary = unifiedPushHelper.getCurrentDistributorName() + lifecycleScope.launch { + pushersManager.togglePusherForCurrentSession(true) + } } } else { unifiedPushHelper.unregister(pushersManager) 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 e42f995ef6b..2deae45f5f0 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 @@ -24,9 +24,13 @@ import im.vector.app.test.fakes.FakeLocaleProvider import im.vector.app.test.fakes.FakePushersService import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeStringProvider +import im.vector.app.test.fixtures.CredentialsFixture +import im.vector.app.test.fixtures.PusherFixture +import im.vector.app.test.fixtures.SessionParamsFixture import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject +import kotlinx.coroutines.test.runTest import org.amshove.kluent.shouldBeEqualTo import org.junit.Before import org.junit.Test @@ -82,4 +86,34 @@ class PushersManagerTest { httpPusher.withEventIdOnly shouldBeEqualTo true httpPusher.url shouldBeEqualTo gateway } + + @Test + fun `when getPusherForCurrentSession, then return pusher`() { + val deviceId = "device_id" + val sessionParams = SessionParamsFixture.aSessionParams( + credentials = CredentialsFixture.aCredentials(deviceId = deviceId) + ) + session.givenSessionParams(sessionParams) + val expectedPusher = PusherFixture.aPusher(deviceId = deviceId) + pushersService.givenGetPushers(listOf(expectedPusher)) + + val pusher = pushersManager.getPusherForCurrentSession() + + pusher shouldBeEqualTo expectedPusher + } + + @Test + fun `when togglePusherForCurrentSession, then do service toggle pusher`() = runTest { + val deviceId = "device_id" + val sessionParams = SessionParamsFixture.aSessionParams( + credentials = CredentialsFixture.aCredentials(deviceId = deviceId) + ) + session.givenSessionParams(sessionParams) + val pusher = PusherFixture.aPusher(deviceId = deviceId) + pushersService.givenGetPushers(listOf(pusher)) + + pushersManager.togglePusherForCurrentSession(true) + + pushersService.verifyOnlyGetPushersAndTogglePusherCalled(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 21c882f4e7f..0b38054a07d 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 @@ -106,6 +106,6 @@ class SessionOverviewViewModelTest { val viewModel = createViewModel() viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID, true)) - fakeSession.pushersService().verifyOnlyTogglePusherCalled(pushers.first(), true) + fakeSession.pushersService().verifyOnlyGetPushersLiveAndTogglePusherCalled(pushers.first(), true) } } 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 60d50eab033..beddc00db99 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 @@ -29,17 +29,28 @@ import org.matrix.android.sdk.api.session.pushers.PushersService class FakePushersService : PushersService by mockk(relaxed = true) { + fun givenGetPushers(pushers: List) { + every { getPushers() } returns pushers + } + fun givenPushersLive(pushers: List) { every { getPushersLive() } returns liveData { emit(pushers) } } - fun verifyOnlyTogglePusherCalled(pusher: Pusher, enable: Boolean) { + fun verifyOnlyGetPushersLiveAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { coVerify(ordering = Ordering.ALL) { getPushersLive() // verifies only getPushersLive and the following togglePusher was called togglePusher(pusher, enable) } } + fun verifyOnlyGetPushersAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { + coVerify(ordering = Ordering.ALL) { + getPushers() // verifies only getPushersLive and the following togglePusher was called + togglePusher(pusher, enable) + } + } + fun verifyEnqueueAddHttpPusher(): HttpPusher { val httpPusherSlot = slot() verify { enqueueAddHttpPusher(capture(httpPusherSlot)) } diff --git a/vector/src/test/java/im/vector/app/test/fixtures/CredentialsFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/CredentialsFixture.kt new file mode 100644 index 00000000000..1a70806e767 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/CredentialsFixture.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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.fixtures + +import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.auth.data.DiscoveryInformation + +object CredentialsFixture { + fun aCredentials( + userId: String = "", + accessToken: String = "", + refreshToken: String? = null, + homeServer: String? = null, + deviceId: String? = null, + discoveryInformation: DiscoveryInformation? = null, + ) = Credentials( + userId, + accessToken, + refreshToken, + homeServer, + deviceId, + discoveryInformation, + ) +} diff --git a/vector/src/test/java/im/vector/app/test/fixtures/SessionParamsFixture.kt b/vector/src/test/java/im/vector/app/test/fixtures/SessionParamsFixture.kt new file mode 100644 index 00000000000..598a95707b7 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fixtures/SessionParamsFixture.kt @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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.fixtures + +import im.vector.app.test.fixtures.CredentialsFixture.aCredentials +import io.mockk.mockk +import org.matrix.android.sdk.api.auth.LoginType +import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.api.auth.data.SessionParams + +object SessionParamsFixture { + fun aSessionParams( + credentials: Credentials = aCredentials(), + homeServerConnectionConfig: HomeServerConnectionConfig = mockk(relaxed = true), + isTokenValid: Boolean = false, + loginType: LoginType = LoginType.UNKNOWN, + ) = SessionParams( + credentials, + homeServerConnectionConfig, + isTokenValid, + loginType, + ) +} From ac33ac1aa0246690ba7301e64a264a5eb8db5613 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 3 Oct 2022 19:44:40 -0400 Subject: [PATCH 12/33] Adds changelog file --- changelog.d/7281.wip | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/7281.wip diff --git a/changelog.d/7281.wip b/changelog.d/7281.wip new file mode 100644 index 00000000000..c457ffbdb9b --- /dev/null +++ b/changelog.d/7281.wip @@ -0,0 +1 @@ +Links "Enable Notifications for this session" setting to enabled value in pusher From 757ee1a623686cf2164da5507372bef7b0d9a7c8 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 4 Oct 2022 14:13:26 -0400 Subject: [PATCH 13/33] Adds error handling to VectorSettingsNotificationPreferenceFragment --- library/ui-strings/src/main/res/values/strings.xml | 1 + .../VectorSettingsNotificationPreferenceFragment.kt | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index dd6b51bca97..5b869069136 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -930,6 +930,7 @@ Configure Call Notifications Configure Silent Notifications Choose LED color, vibration, sound… + Something went wrong. Please check your network connection and try again. Encrypted messages in one-to-one chats Encrypted messages in group chats diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt index de96d687e4e..4c9e1bfe397 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt @@ -62,7 +62,6 @@ import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.pushers.Pusher import org.matrix.android.sdk.api.session.pushrules.RuleIds import org.matrix.android.sdk.api.session.pushrules.RuleKind -import org.matrix.android.sdk.flow.flow import javax.inject.Inject // Referenced in vector_settings_preferences_root.xml @@ -124,7 +123,14 @@ class VectorSettingsNotificationPreferenceFragment : findPreference(VectorPreferences.SETTINGS_NOTIFICATION_METHOD_KEY) ?.summary = unifiedPushHelper.getCurrentDistributorName() lifecycleScope.launch { - pushersManager.togglePusherForCurrentSession(true) + val result = runCatching { + pushersManager.togglePusherForCurrentSession(true) + } + + result.exceptionOrNull()?.let { _ -> + Toast.makeText(context, R.string.settings_error_toggle_pusher, Toast.LENGTH_SHORT).show() + it.isChecked = false + } } } } else { From 121415d425fd693dbfd6276fba71b0eac32e6121 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 4 Oct 2022 14:13:53 -0400 Subject: [PATCH 14/33] Removes comment in FakePushersService --- .../test/java/im/vector/app/test/fakes/FakePushersService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 beddc00db99..bd4eb27c399 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 @@ -39,14 +39,14 @@ class FakePushersService : PushersService by mockk(relaxed = true) { fun verifyOnlyGetPushersLiveAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { coVerify(ordering = Ordering.ALL) { - getPushersLive() // verifies only getPushersLive and the following togglePusher was called + getPushersLive() togglePusher(pusher, enable) } } fun verifyOnlyGetPushersAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { coVerify(ordering = Ordering.ALL) { - getPushers() // verifies only getPushersLive and the following togglePusher was called + getPushers() togglePusher(pusher, enable) } } From c0385403aa50934e79431038f67138d8861f1881 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 5 Oct 2022 18:04:12 -0400 Subject: [PATCH 15/33] Fixes post merge errors --- .../devices/v2/overview/SessionOverviewFragment.kt | 9 +++++++-- .../devices/v2/overview/SessionOverviewViewModel.kt | 11 ++++------- 2 files changed, 11 insertions(+), 9 deletions(-) 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 09cd27b3a45..bf3142e22e1 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 @@ -24,6 +24,7 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.appcompat.app.AppCompatActivity +import androidx.core.view.isGone import androidx.core.view.isVisible import com.airbnb.mvrx.Success import com.airbnb.mvrx.fragmentViewModel @@ -40,6 +41,7 @@ import im.vector.app.core.resources.DrawableProvider import im.vector.app.databinding.FragmentSessionOverviewBinding import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.crypto.recover.SetupMode +import im.vector.app.features.settings.devices.v2.DeviceFullInfo import im.vector.app.features.settings.devices.v2.list.SessionInfoViewState import im.vector.app.features.settings.devices.v2.more.SessionLearnMoreBottomSheet import im.vector.app.features.workers.signout.SignOutUiWorker @@ -172,12 +174,11 @@ class SessionOverviewFragment : override fun invalidate() = withState(viewModel) { state -> updateToolbar(state) - updateEntryDetails(state.deviceId) updateSessionInfo(state) updateLoading(state.isLoading) updatePushNotificationToggle(state.deviceId, state.pushers.invoke().orEmpty()) if (state.deviceInfo is Success) { - renderSessionInfo(state.isCurrentSession, state.deviceInfo.invoke()) + renderSessionInfo(state.isCurrentSessionTrusted, state.deviceInfo.invoke()) } else { hideSessionInfo() } @@ -302,4 +303,8 @@ class SessionOverviewFragment : ) SessionLearnMoreBottomSheet.show(childFragmentManager, args) } + + private fun hideSessionInfo() { + views.sessionOverviewInfo.isGone = true + } } 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 f1fe69410b9..a7b0435e29d 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 @@ -43,14 +43,13 @@ 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.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.flow.flow import timber.log.Timber import javax.net.ssl.HttpsURLConnection import kotlin.coroutines.Continuation -import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.flow.flow class SessionOverviewViewModel @AssistedInject constructor( @Assisted val initialState: SessionOverviewViewState, @@ -102,7 +101,7 @@ class SessionOverviewViewModel @AssistedInject constructor( private fun observePushers(deviceId: String) { session.flow() .livePushers() - .map { it.filter { pusher -> pusher.deviceId == deviceId }} + .map { it.filter { pusher -> pusher.deviceId == deviceId } } .execute { copy(pushers = it) } } @@ -113,6 +112,7 @@ class SessionOverviewViewModel @AssistedInject constructor( SessionOverviewAction.SsoAuthDone -> handleSsoAuthDone() is SessionOverviewAction.PasswordAuthDone -> handlePasswordAuthDone(action) SessionOverviewAction.ReAuthCancelled -> handleReAuthCancelled() + is SessionOverviewAction.TogglePushNotifications -> handleTogglePusherAction(action) } } @@ -209,9 +209,6 @@ class SessionOverviewViewModel @AssistedInject constructor( private fun handleReAuthCancelled() { pendingAuthHandler.reAuthCancelled() - when (action) { - is SessionOverviewAction.TogglePushNotifications -> handleTogglePusherAction(action) - } } private fun handleTogglePusherAction(action: SessionOverviewAction.TogglePushNotifications) { From 33986465d552b97b91524f6233112256eb808c35 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Fri, 7 Oct 2022 09:13:45 -0400 Subject: [PATCH 16/33] Fixes imports and improves string name --- library/ui-strings/src/main/res/values/strings.xml | 2 +- .../java/im/vector/app/core/pushers/PushersManagerTest.kt | 4 +--- .../devices/v2/overview/SessionOverviewViewModelTest.kt | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/library/ui-strings/src/main/res/values/strings.xml b/library/ui-strings/src/main/res/values/strings.xml index 7e8569a57bc..01a3234fded 100644 --- a/library/ui-strings/src/main/res/values/strings.xml +++ b/library/ui-strings/src/main/res/values/strings.xml @@ -931,7 +931,6 @@ Configure Call Notifications Configure Silent Notifications Choose LED color, vibration, sound… - Something went wrong. Please check your network connection and try again. Encrypted messages in one-to-one chats Encrypted messages in group chats @@ -1661,6 +1660,7 @@ Create New Room Create New Space No network. Please check your Internet connection. + Something went wrong. Please check your network connection and try again. "Change network" "Please wait…" Updating your data… 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 baea54c98e3..750e50d578a 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 @@ -24,13 +24,11 @@ import im.vector.app.test.fakes.FakeLocaleProvider import im.vector.app.test.fakes.FakePushersService import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fakes.FakeStringProvider -import im.vector.app.test.fixtures.CryptoDeviceInfoFixture.aCryptoDeviceInfo import im.vector.app.test.fixtures.CredentialsFixture +import im.vector.app.test.fixtures.CryptoDeviceInfoFixture.aCryptoDeviceInfo import im.vector.app.test.fixtures.PusherFixture import im.vector.app.test.fixtures.SessionParamsFixture -import io.mockk.every import io.mockk.mockk -import io.mockk.mockkObject import kotlinx.coroutines.test.runTest import org.amshove.kluent.shouldBeEqualTo import org.junit.Test 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 09829636bca..af6be31eb04 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 @@ -30,9 +30,9 @@ 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.FakeVerificationService -import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fixtures.PusherFixture.aPusher import im.vector.app.test.test import im.vector.app.test.testDispatcher From c3a70b5964538fe70e7519abe998cde0161157d5 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 09:50:19 -0400 Subject: [PATCH 17/33] Fixes legal copies --- .../org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt | 4 ++-- .../org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt | 4 ++-- .../org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt | 4 ++-- .../sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt | 4 ++-- .../org/matrix/android/sdk/test/fixtures/PusherFixture.kt | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt index 266eacde116..55a7607a032 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeRemovePusherTask.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt index bf6109b36dd..543dda8a4f9 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTaskExecutor.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt index 44bf99098ea..b1e059a40ed 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/FakeTogglePusherTask.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt index 01b1b8e0bcd..46a106dcb26 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fakes/internal/FakePushGatewayNotifyTask.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt index 50a84f951f7..0ac7885062b 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/test/fixtures/PusherFixture.kt @@ -1,11 +1,11 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright 2022 The Matrix.org Foundation C.I.C. * * 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 + * 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, From a951a80a4f72cba018be7029deaeebe33bc56b65 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 09:52:23 -0400 Subject: [PATCH 18/33] Fixes kdoc punctuation --- .../matrix/android/sdk/api/session/pushers/PushersService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index 517809b906c..6a27f7af613 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -68,7 +68,7 @@ interface PushersService { ) /** - * Enables or disables a registered pusher + * Enables or disables a registered pusher. * * @param pusher The pusher being toggled * @param enable Whether the pusher should be enabled or disabled From e999aab0c48fc2f80595cb96eaacc7d3fd670cf7 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 10:58:47 -0400 Subject: [PATCH 19/33] Fixes string error --- .../VectorSettingsNotificationPreferenceFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt index 4c9e1bfe397..0202acecc7d 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt @@ -128,7 +128,7 @@ class VectorSettingsNotificationPreferenceFragment : } result.exceptionOrNull()?.let { _ -> - Toast.makeText(context, R.string.settings_error_toggle_pusher, Toast.LENGTH_SHORT).show() + Toast.makeText(context, R.string.error_check_network, Toast.LENGTH_SHORT).show() it.isChecked = false } } From b4c15d38c8139b20699065c6837a63f57495ee45 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 11:00:02 -0400 Subject: [PATCH 20/33] Removes unused imports --- .../android/sdk/internal/session/pushers/TogglePusherTask.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt index 14463ca89a7..87836e1c769 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/pushers/TogglePusherTask.kt @@ -17,14 +17,11 @@ package org.matrix.android.sdk.internal.session.pushers import com.zhuinden.monarchy.Monarchy -import org.matrix.android.sdk.api.session.pushers.PusherState -import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.PusherEntity import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.RequestExecutor -import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import org.matrix.android.sdk.internal.util.awaitTransaction import javax.inject.Inject From 91e902f525ddf4cb33dfb4ec93b3d3223b380795 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 12:46:37 -0400 Subject: [PATCH 21/33] Fixes lint errors --- .../devices/v2/overview/SessionOverviewViewModelTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 769b8fb5043..77fd734daf2 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 @@ -30,9 +30,9 @@ 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.FakeVerificationService -import im.vector.app.test.fakes.FakeSession import im.vector.app.test.fixtures.PusherFixture.aPusher import im.vector.app.test.test import im.vector.app.test.testDispatcher From a996c8c387d04c873134a0c5db5d33356115ae81 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 12:48:31 -0400 Subject: [PATCH 22/33] Fixes test errors --- .../settings/devices/v2/overview/SessionOverviewViewModelTest.kt | 1 - 1 file changed, 1 deletion(-) 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 77fd734daf2..647e5a2d2c5 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 @@ -83,7 +83,6 @@ class SessionOverviewViewModelTest { private val getDeviceFullInfoUseCase = mockk(relaxed = true) private val fakeActiveSessionHolder = FakeActiveSessionHolder() private val fakeStringProvider = FakeStringProvider() - private val getDeviceFullInfoUseCase = mockk() private val checkIfCurrentSessionCanBeVerifiedUseCase = mockk() private val signoutSessionUseCase = mockk() private val interceptSignoutFlowResponseUseCase = mockk() From be16bad6ffc80111c2b3993e55d7a6719d0ec819 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 14:42:00 -0400 Subject: [PATCH 23/33] Fixes test errors --- .../v2/overview/SessionOverviewFragment.kt | 2 +- .../overview/SessionOverviewViewModelTest.kt | 115 +----------------- 2 files changed, 6 insertions(+), 111 deletions(-) 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 2e5ef4f6b93..7510880087f 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 @@ -245,7 +245,7 @@ class SessionOverviewFragment : isLearnMoreLinkVisible = true, isLastSeenDetailsVisible = true, ) - views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider) + views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider, stringProvider) } private fun updateLoading(isLoading: Boolean) { 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 ed080eb2138..5c6e910f6e2 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 @@ -91,6 +91,7 @@ class SessionOverviewViewModelTest { private fun createViewModel() = SessionOverviewViewModel( initialState = SessionOverviewViewState(args), + session = fakeSession, stringProvider = fakeStringProvider.instance, getDeviceFullInfoUseCase = getDeviceFullInfoUseCase, checkIfCurrentSessionCanBeVerifiedUseCase = checkIfCurrentSessionCanBeVerifiedUseCase, @@ -117,13 +118,11 @@ class SessionOverviewViewModelTest { @Test fun `given the viewModel has been initialized then viewState is updated with session info`() { - val sessionParams = givenIdForSession(A_SESSION_ID) val deviceFullInfo = mockk() every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) givenCurrentSessionIsTrusted() val expectedState = SessionOverviewViewState( - deviceId = A_SESSION_ID, - isCurrentSession = true, + deviceId = A_SESSION_ID_1, deviceInfo = Success(deviceFullInfo), isCurrentSessionTrusted = true, pushers = Loading(), @@ -207,110 +206,6 @@ class SessionOverviewViewModelTest { .finish() } - @Test - fun `given another session and no reAuth is needed when handling signout action then signout process is performed`() { - // Given - val deviceFullInfo = mockk() - every { deviceFullInfo.isCurrentDevice } returns false - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) - givenSignoutSuccess(A_SESSION_ID_1) - every { refreshDevicesUseCase.execute() } just runs - val signoutAction = SessionOverviewAction.SignoutOtherSession - givenCurrentSessionIsTrusted() - val expectedViewState = SessionOverviewViewState( - deviceId = A_SESSION_ID_1, - isCurrentSessionTrusted = true, - deviceInfo = Success(deviceFullInfo), - isLoading = false, - ) - - // When - val viewModel = createViewModel() - val viewModelTest = viewModel.test() - viewModel.handle(signoutAction) - - // Then - viewModelTest - .assertStatesChanges( - expectedViewState, - { copy(isLoading = true) }, - { copy(isLoading = false) } - ) - .assertEvent { it is SessionOverviewViewEvent.SignoutSuccess } - .finish() - verify { - refreshDevicesUseCase.execute() - } - } - - @Test - fun `given another session and server error during signout when handling signout action then signout process is performed`() { - // Given - val deviceFullInfo = mockk() - every { deviceFullInfo.isCurrentDevice } returns false - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) - val serverError = Failure.OtherServerError(errorBody = "", httpCode = HttpsURLConnection.HTTP_UNAUTHORIZED) - givenSignoutError(A_SESSION_ID_1, serverError) - val signoutAction = SessionOverviewAction.SignoutOtherSession - givenCurrentSessionIsTrusted() - val expectedViewState = SessionOverviewViewState( - deviceId = A_SESSION_ID_1, - isCurrentSessionTrusted = true, - deviceInfo = Success(deviceFullInfo), - isLoading = false, - ) - fakeStringProvider.given(R.string.authentication_error, AUTH_ERROR_MESSAGE) - - // When - val viewModel = createViewModel() - val viewModelTest = viewModel.test() - viewModel.handle(signoutAction) - - // Then - viewModelTest - .assertStatesChanges( - expectedViewState, - { copy(isLoading = true) }, - { copy(isLoading = false) } - ) - .assertEvent { it is SessionOverviewViewEvent.SignoutError && it.error.message == AUTH_ERROR_MESSAGE } - .finish() - } - - @Test - fun `given another session and unexpected error during signout when handling signout action then signout process is performed`() { - // Given - val deviceFullInfo = mockk() - every { deviceFullInfo.isCurrentDevice } returns false - every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) - val error = Exception() - givenSignoutError(A_SESSION_ID_1, error) - val signoutAction = SessionOverviewAction.SignoutOtherSession - givenCurrentSessionIsTrusted() - val expectedViewState = SessionOverviewViewState( - deviceId = A_SESSION_ID_1, - isCurrentSessionTrusted = true, - deviceInfo = Success(deviceFullInfo), - isLoading = false, - ) - fakeStringProvider.given(R.string.matrix_error, AN_ERROR_MESSAGE) - - // When - val viewModel = createViewModel() - val viewModelTest = viewModel.test() - viewModel.handle(signoutAction) - - // Then - viewModelTest - .assertStatesChanges( - expectedViewState, - { copy(isLoading = true) }, - { copy(isLoading = false) } - ) - .assertEvent { it is SessionOverviewViewEvent.SignoutError && it.error.message == AN_ERROR_MESSAGE } - .finish() - } - @Test fun `given another session and reAuth is needed during signout when handling signout action then requestReAuth is sent and pending auth is stored`() { // Given @@ -458,7 +353,7 @@ class SessionOverviewViewModelTest { @Test fun `when viewModel init, then observe pushers and emit to state`() { - val pushers = listOf(aPusher(deviceId = A_SESSION_ID)) + val pushers = listOf(aPusher(deviceId = A_SESSION_ID_1)) fakeSession.pushersService().givenPushersLive(pushers) val viewModel = createViewModel() @@ -471,13 +366,13 @@ class SessionOverviewViewModelTest { @Test fun `when handle TogglePushNotifications, then toggle enabled for device pushers`() { val pushers = listOf( - aPusher(deviceId = A_SESSION_ID, enabled = false), + aPusher(deviceId = A_SESSION_ID_1, enabled = false), aPusher(deviceId = "another id", enabled = false) ) fakeSession.pushersService().givenPushersLive(pushers) val viewModel = createViewModel() - viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID, true)) + viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID_1, true)) fakeSession.pushersService().verifyOnlyGetPushersLiveAndTogglePusherCalled(pushers.first(), true) } From f397a6228abc20746a632a801ebcdcfb8df96a33 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 14:46:51 -0400 Subject: [PATCH 24/33] Fixes error --- .../settings/devices/v2/overview/SessionOverviewFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 2e5ef4f6b93..7510880087f 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 @@ -245,7 +245,7 @@ class SessionOverviewFragment : isLearnMoreLinkVisible = true, isLastSeenDetailsVisible = true, ) - views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider) + views.sessionOverviewInfo.render(viewState, dateFormatter, drawableProvider, colorProvider, stringProvider) } private fun updateLoading(isLoading: Boolean) { From 971fe8ef359dc29e979f685d5c40cf638aacdd9e Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 14:50:07 -0400 Subject: [PATCH 25/33] Fixes error --- .../v2/overview/SessionOverviewViewModelTest.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) 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 647e5a2d2c5..bb240471560 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 @@ -91,6 +91,7 @@ class SessionOverviewViewModelTest { private fun createViewModel() = SessionOverviewViewModel( initialState = SessionOverviewViewState(args), + session = fakeSession, stringProvider = fakeStringProvider.instance, getDeviceFullInfoUseCase = getDeviceFullInfoUseCase, checkIfCurrentSessionCanBeVerifiedUseCase = checkIfCurrentSessionCanBeVerifiedUseCase, @@ -117,13 +118,11 @@ class SessionOverviewViewModelTest { @Test fun `given the viewModel has been initialized then viewState is updated with session info`() { - val sessionParams = givenIdForSession(A_SESSION_ID) val deviceFullInfo = mockk() every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) givenCurrentSessionIsTrusted() val expectedState = SessionOverviewViewState( - deviceId = A_SESSION_ID, - isCurrentSession = true, + deviceId = A_SESSION_ID_1, deviceInfo = Success(deviceFullInfo), isCurrentSessionTrusted = true, pushers = Loading(), @@ -458,7 +457,7 @@ class SessionOverviewViewModelTest { @Test fun `when viewModel init, then observe pushers and emit to state`() { - val pushers = listOf(aPusher(deviceId = A_SESSION_ID)) + val pushers = listOf(aPusher(deviceId = A_SESSION_ID_1)) fakeSession.pushersService().givenPushersLive(pushers) val viewModel = createViewModel() @@ -471,13 +470,13 @@ class SessionOverviewViewModelTest { @Test fun `when handle TogglePushNotifications, then toggle enabled for device pushers`() { val pushers = listOf( - aPusher(deviceId = A_SESSION_ID, enabled = false), + aPusher(deviceId = A_SESSION_ID_1, enabled = false), aPusher(deviceId = "another id", enabled = false) ) fakeSession.pushersService().givenPushersLive(pushers) val viewModel = createViewModel() - viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID, true)) + viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID_1, true)) fakeSession.pushersService().verifyOnlyTogglePusherCalled(pushers.first(), true) } From e44bca3cea343d132effad02cf11d2bc41350e4c Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 14:50:57 -0400 Subject: [PATCH 26/33] Fixes error --- .../devices/v2/overview/SessionOverviewViewModelTest.kt | 3 --- 1 file changed, 3 deletions(-) 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 5c6e910f6e2..a92eccd38d0 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 @@ -21,7 +21,6 @@ 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 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.signout.InterceptSignoutFlowResponseUseCase @@ -56,10 +55,8 @@ import org.junit.Test 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.failure.Failure import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth -import javax.net.ssl.HttpsURLConnection import kotlin.coroutines.Continuation private const val A_SESSION_ID_1 = "session-id-1" From 1e3dbbab8d152b09658126bb6b6a10831ddf98ac Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 15:06:57 -0400 Subject: [PATCH 27/33] Fixes error --- .../settings/devices/v2/overview/SessionOverviewAction.kt | 1 - .../devices/v2/overview/SessionOverviewEntrySwitchView.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt index c61a4266567..9a92d5b6299 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewAction.kt @@ -30,4 +30,3 @@ sealed class SessionOverviewAction : VectorViewModelAction { val enabled: Boolean, ) : SessionOverviewAction() } - diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt index 3b1d72fcc73..bbefd31dfe9 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -25,7 +25,6 @@ import androidx.constraintlayout.widget.ConstraintLayout import androidx.core.content.res.use import im.vector.app.R import im.vector.app.core.extensions.setAttributeBackground -import im.vector.app.databinding.ViewSessionOverviewEntryBinding import im.vector.app.databinding.ViewSessionOverviewEntrySwitchBinding class SessionOverviewEntrySwitchView @JvmOverloads constructor( From 9de170a90c9858760bdbb7f82ba5f1a82532130b Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Sun, 9 Oct 2022 15:17:53 -0400 Subject: [PATCH 28/33] Fixes error --- .../matrix/android/sdk/api/session/pushers/PushersService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt index 517809b906c..6a27f7af613 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/pushers/PushersService.kt @@ -68,7 +68,7 @@ interface PushersService { ) /** - * Enables or disables a registered pusher + * Enables or disables a registered pusher. * * @param pusher The pusher being toggled * @param enable Whether the pusher should be enabled or disabled From b02b4a37eadaf1930ed9aa45a5fb058a748ec02b Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Mon, 10 Oct 2022 22:33:59 -0400 Subject: [PATCH 29/33] Adds lost tests --- .../overview/SessionOverviewViewModelTest.kt | 136 ++++++++++++++---- .../app/test/fakes/FakePushersService.kt | 11 -- 2 files changed, 110 insertions(+), 37 deletions(-) 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 ecf423d43c0..73c9c5aa955 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 @@ -21,6 +21,7 @@ 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 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.signout.InterceptSignoutFlowResponseUseCase @@ -55,8 +56,10 @@ import org.junit.Test 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.failure.Failure import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import javax.net.ssl.HttpsURLConnection import kotlin.coroutines.Continuation private const val A_SESSION_ID_1 = "session-id-1" @@ -203,6 +206,113 @@ class SessionOverviewViewModelTest { .finish() } + @Test + fun `given another session and no reAuth is needed when handling signout action then signout process is performed`() { + // Given + val deviceFullInfo = mockk() + every { deviceFullInfo.isCurrentDevice } returns false + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) + givenSignoutSuccess(A_SESSION_ID_1) + every { refreshDevicesUseCase.execute() } just runs + val signoutAction = SessionOverviewAction.SignoutOtherSession + givenCurrentSessionIsTrusted() + val expectedViewState = SessionOverviewViewState( + deviceId = A_SESSION_ID_1, + isCurrentSessionTrusted = true, + deviceInfo = Success(deviceFullInfo), + isLoading = false, + pushers = Loading(), + ) + + // When + val viewModel = createViewModel() + val viewModelTest = viewModel.test() + viewModel.handle(signoutAction) + + // Then + viewModelTest + .assertStatesChanges( + expectedViewState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvent { it is SessionOverviewViewEvent.SignoutSuccess } + .finish() + verify { + refreshDevicesUseCase.execute() + } + } + + @Test + fun `given another session and server error during signout when handling signout action then signout process is performed`() { + // Given + val deviceFullInfo = mockk() + every { deviceFullInfo.isCurrentDevice } returns false + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) + val serverError = Failure.OtherServerError(errorBody = "", httpCode = HttpsURLConnection.HTTP_UNAUTHORIZED) + givenSignoutError(A_SESSION_ID_1, serverError) + val signoutAction = SessionOverviewAction.SignoutOtherSession + givenCurrentSessionIsTrusted() + val expectedViewState = SessionOverviewViewState( + deviceId = A_SESSION_ID_1, + isCurrentSessionTrusted = true, + deviceInfo = Success(deviceFullInfo), + isLoading = false, + pushers = Loading(), + ) + fakeStringProvider.given(R.string.authentication_error, AUTH_ERROR_MESSAGE) + + // When + val viewModel = createViewModel() + val viewModelTest = viewModel.test() + viewModel.handle(signoutAction) + + // Then + viewModelTest + .assertStatesChanges( + expectedViewState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvent { it is SessionOverviewViewEvent.SignoutError && it.error.message == AUTH_ERROR_MESSAGE } + .finish() + } + + @Test + fun `given another session and unexpected error during signout when handling signout action then signout process is performed`() { + // Given + val deviceFullInfo = mockk() + every { deviceFullInfo.isCurrentDevice } returns false + every { getDeviceFullInfoUseCase.execute(A_SESSION_ID_1) } returns flowOf(deviceFullInfo) + val error = Exception() + givenSignoutError(A_SESSION_ID_1, error) + val signoutAction = SessionOverviewAction.SignoutOtherSession + givenCurrentSessionIsTrusted() + val expectedViewState = SessionOverviewViewState( + deviceId = A_SESSION_ID_1, + isCurrentSessionTrusted = true, + deviceInfo = Success(deviceFullInfo), + isLoading = false, + pushers = Loading(), + ) + fakeStringProvider.given(R.string.matrix_error, AN_ERROR_MESSAGE) + + // When + val viewModel = createViewModel() + val viewModelTest = viewModel.test() + viewModel.handle(signoutAction) + + // Then + viewModelTest + .assertStatesChanges( + expectedViewState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvent { it is SessionOverviewViewEvent.SignoutError && it.error.message == AN_ERROR_MESSAGE } + .finish() + } + @Test fun `given another session and reAuth is needed during signout when handling signout action then requestReAuth is sent and pending auth is stored`() { // Given @@ -373,30 +483,4 @@ class SessionOverviewViewModelTest { fakeSession.pushersService().verifyOnlyTogglePusherCalled(pushers.first(), true) } - - @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) - - val viewModel = createViewModel() - - viewModel.test() - .assertLatestState { state -> state.pushers.invoke() == pushers } - .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) - - val viewModel = createViewModel() - viewModel.handle(SessionOverviewAction.TogglePushNotifications(A_SESSION_ID_1, true)) - - fakeSession.pushersService().verifyOnlyGetPushersLiveAndTogglePusherCalled(pushers.first(), true) - } } 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 9af292bb4f5..d506f53e607 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 @@ -37,13 +37,6 @@ class FakePushersService : PushersService by mockk(relaxed = true) { every { getPushersLive() } returns liveData { emit(pushers) } } - fun verifyOnlyGetPushersLiveAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { - coVerify(ordering = Ordering.ALL) { - getPushersLive() - togglePusher(pusher, enable) - } - } - fun verifyOnlyGetPushersAndTogglePusherCalled(pusher: Pusher, enable: Boolean) { coVerify(ordering = Ordering.ALL) { getPushers() @@ -51,10 +44,6 @@ class FakePushersService : PushersService by mockk(relaxed = true) { } } - fun givenPushersLive(pushers: List) { - every { getPushersLive() } returns liveData { emit(pushers) } - } - fun verifyOnlyTogglePusherCalled(pusher: Pusher, enable: Boolean) { coVerify(ordering = Ordering.ALL) { getPushersLive() // verifies only getPushersLive and the following togglePusher was called From c6224b11aabcca1d129fd628fc77dc12867248b2 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 11 Oct 2022 16:04:51 -0400 Subject: [PATCH 30/33] Adds PusherEntity migration --- .../database/RealmSessionStoreMigration.kt | 4 ++- .../database/migration/MigrateSessionTo038.kt | 31 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo038.kt diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt index 2693ca474c2..aef482ae2ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/RealmSessionStoreMigration.kt @@ -54,6 +54,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo034 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo035 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo036 import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo037 +import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo038 import org.matrix.android.sdk.internal.util.Normalizer import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration import javax.inject.Inject @@ -62,7 +63,7 @@ internal class RealmSessionStoreMigration @Inject constructor( private val normalizer: Normalizer ) : MatrixRealmMigration( dbName = "Session", - schemaVersion = 37L, + schemaVersion = 38L, ) { /** * Forces all RealmSessionStoreMigration instances to be equal. @@ -109,5 +110,6 @@ internal class RealmSessionStoreMigration @Inject constructor( if (oldVersion < 35) MigrateSessionTo035(realm).perform() if (oldVersion < 36) MigrateSessionTo036(realm).perform() if (oldVersion < 37) MigrateSessionTo037(realm).perform() + if (oldVersion < 38) MigrateSessionTo038(realm).perform() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo038.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo038.kt new file mode 100644 index 00000000000..b5848f04cdb --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo038.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * 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 org.matrix.android.sdk.internal.database.migration + +import io.realm.DynamicRealm +import org.matrix.android.sdk.internal.database.model.PusherEntityFields +import org.matrix.android.sdk.internal.util.database.RealmMigrator + +internal class MigrateSessionTo038(realm: DynamicRealm) : RealmMigrator(realm, 38) { + + override fun doMigrate(realm: DynamicRealm) { + realm.schema.get("PusherEntity") + ?.addField(PusherEntityFields.ENABLED, Boolean::class.java) + ?.addField(PusherEntityFields.DEVICE_ID, String::class.java) + ?.transform { obj -> obj.set(PusherEntityFields.ENABLED, true) } + } +} From d1562d3e3e8c3491e873de2187adab3e80f7fea0 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 11 Oct 2022 16:08:04 -0400 Subject: [PATCH 31/33] Fixes session overview layout overlap --- vector/src/main/res/layout/fragment_session_overview.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/res/layout/fragment_session_overview.xml b/vector/src/main/res/layout/fragment_session_overview.xml index 80ad744d010..1c59abfd122 100644 --- a/vector/src/main/res/layout/fragment_session_overview.xml +++ b/vector/src/main/res/layout/fragment_session_overview.xml @@ -51,7 +51,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0" app:layout_constraintStart_toStartOf="parent" - app:layout_constraintTop_toBottomOf="@id/sessionOverviewEntryDetails" + app:layout_constraintTop_toBottomOf="@id/sessionOverviewPushNotifications" app:layout_constraintWidth="wrap_content" /> From 992d7d3505086c3f956c077512a670bcdbe09f0b Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Tue, 11 Oct 2022 16:25:29 -0400 Subject: [PATCH 32/33] Fixes switch being enabled by default --- .../devices/v2/overview/SessionOverviewEntrySwitchView.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt index bbefd31dfe9..e604c8a98fd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -67,7 +67,7 @@ class SessionOverviewEntrySwitchView @JvmOverloads constructor( } private fun setSwitchedEnabled(typedArray: TypedArray) { - val enabled = typedArray.getBoolean(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchEnabled, true) + val enabled = typedArray.getBoolean(R.styleable.SessionOverviewEntrySwitchView_sessionOverviewEntrySwitchEnabled, false) binding.sessionsOverviewEntrySwitch.isChecked = enabled } From 5a1eac66088bac922048d45baf8d58be90220b61 Mon Sep 17 00:00:00 2001 From: ericdecanini Date: Wed, 12 Oct 2022 08:24:14 -0400 Subject: [PATCH 33/33] Binds entire view to toggle switch --- .../devices/v2/overview/SessionOverviewEntrySwitchView.kt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt index e604c8a98fd..24c7725f29f 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/overview/SessionOverviewEntrySwitchView.kt @@ -49,6 +49,7 @@ class SessionOverviewEntrySwitchView @JvmOverloads constructor( setTitle(it) setDescription(it) setSwitchedEnabled(it) + setClickListener() } } @@ -71,6 +72,12 @@ class SessionOverviewEntrySwitchView @JvmOverloads constructor( binding.sessionsOverviewEntrySwitch.isChecked = enabled } + private fun setClickListener() { + binding.root.setOnClickListener { + setChecked(!binding.sessionsOverviewEntrySwitch.isChecked) + } + } + fun setChecked(checked: Boolean) { binding.sessionsOverviewEntrySwitch.isChecked = checked }