diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCase.kt index 17ae0baa5d..2e44bb33d6 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCase.kt @@ -17,21 +17,28 @@ package im.vector.app.features.settings.devices.v2.rename import im.vector.app.core.di.ActiveSessionHolder +import im.vector.app.core.extensions.andThen +import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase import org.matrix.android.sdk.api.util.awaitCallback import javax.inject.Inject -// TODO add unit tests class RenameSessionUseCase @Inject constructor( private val activeSessionHolder: ActiveSessionHolder, + private val refreshDevicesUseCase: RefreshDevicesUseCase, ) { suspend fun execute(deviceId: String, newName: String): Result { - return runCatching { - awaitCallback { matrixCallback -> - activeSessionHolder.getActiveSession() - .cryptoService() - .setDeviceName(deviceId, newName, matrixCallback) - } + return renameDevice(deviceId, newName) + .andThen { refreshDevices() } + } + + private suspend fun renameDevice(deviceId: String, newName: String) = runCatching { + awaitCallback { matrixCallback -> + activeSessionHolder.getActiveSession() + .cryptoService() + .setDeviceName(deviceId, newName, matrixCallback) } } + + private fun refreshDevices() = runCatching { refreshDevicesUseCase.execute() } } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCaseTest.kt new file mode 100644 index 0000000000..9ef4718559 --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/rename/RenameSessionUseCaseTest.kt @@ -0,0 +1,91 @@ +/* + * 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.rename + +import im.vector.app.features.settings.devices.v2.RefreshDevicesUseCase +import im.vector.app.test.fakes.FakeActiveSessionHolder +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.runs +import io.mockk.verify +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.shouldBe +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Test + +private const val A_DEVICE_ID = "device-id" +private const val A_DEVICE_NAME = "device-name" + +class RenameSessionUseCaseTest { + + private val fakeActiveSessionHolder = FakeActiveSessionHolder() + private val refreshDevicesUseCase = mockk() + + private val renameSessionUseCase = RenameSessionUseCase( + activeSessionHolder = fakeActiveSessionHolder.instance, + refreshDevicesUseCase = refreshDevicesUseCase + ) + + @Test + fun `given a device id and a new name when no error during rename then the device is renamed with success`() = runTest { + // Given + fakeActiveSessionHolder.fakeSession.fakeCryptoService.givenSetDeviceNameSucceeds() + every { refreshDevicesUseCase.execute() } just runs + + // When + val result = renameSessionUseCase.execute(A_DEVICE_ID, A_DEVICE_NAME) + + // Then + result.isSuccess shouldBe true + verify { + fakeActiveSessionHolder.fakeSession + .cryptoService() + .setDeviceName(A_DEVICE_ID, A_DEVICE_NAME, any()) + refreshDevicesUseCase.execute() + } + } + + @Test + fun `given a device id and a new name when an error occurs during rename then result is failure`() = runTest { + // Given + val error = Exception() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.givenSetDeviceNameFailsWithError(error) + + // When + val result = renameSessionUseCase.execute(A_DEVICE_ID, A_DEVICE_NAME) + + // Then + result.isFailure shouldBe true + result.exceptionOrNull() shouldBeEqualTo error + } + + @Test + fun `given a device id and a new name when an error occurs during devices refresh then result is failure`() = runTest { + // Given + val error = Exception() + fakeActiveSessionHolder.fakeSession.fakeCryptoService.givenSetDeviceNameSucceeds() + every { refreshDevicesUseCase.execute() } throws error + + // When + val result = renameSessionUseCase.execute(A_DEVICE_ID, A_DEVICE_NAME) + + // Then + result.isFailure shouldBe true + result.exceptionOrNull() shouldBeEqualTo error + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt index 538ce671d2..a83da8cb9d 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt @@ -17,7 +17,10 @@ package im.vector.app.test.fakes import androidx.lifecycle.MutableLiveData +import io.mockk.every import io.mockk.mockk +import io.mockk.slot +import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo @@ -50,4 +53,18 @@ class FakeCryptoService( override fun getLiveCryptoDeviceInfoWithId(deviceId: String) = cryptoDeviceInfoWithIdLiveData override fun getMyDevicesInfoLive(deviceId: String) = myDevicesInfoWithIdLiveData + + fun givenSetDeviceNameSucceeds() { + val matrixCallback = slot>() + every { setDeviceName(any(), any(), capture(matrixCallback)) } answers { + thirdArg>().onSuccess(Unit) + } + } + + fun givenSetDeviceNameFailsWithError(error: Exception) { + val matrixCallback = slot>() + every { setDeviceName(any(), any(), capture(matrixCallback)) } answers { + thirdArg>().onFailure(error) + } + } }