diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCase.kt index 43426de56c..ccc73e896b 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCase.kt @@ -28,15 +28,16 @@ class SetMatrixClientInfoUseCase @Inject constructor( private val activeSessionHolder: ActiveSessionHolder, ) { - // TODO add unit tests suspend fun execute(clientInfo: MatrixClientInfoContent): Result = runCatching { activeSessionHolder.getSafeActiveSession() ?.let { session -> - val deviceId = session.sessionParams.deviceId - if (deviceId != null) { + val deviceId = session.sessionParams.deviceId.orEmpty() + if (deviceId.isNotEmpty()) { val type = MATRIX_CLIENT_INFO_KEY_PREFIX + deviceId session.accountDataService() .updateUserAccountData(type, clientInfo.toContent()) + } else { + throw IllegalStateException("device id is empty") } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/UpdateMatrixClientInfoUseCase.kt b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/UpdateMatrixClientInfoUseCase.kt index ca953ce5d2..f19503dcc5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/UpdateMatrixClientInfoUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/v2/details/extended/UpdateMatrixClientInfoUseCase.kt @@ -39,8 +39,10 @@ class UpdateMatrixClientInfoUseCase @Inject constructor( name = appNameProvider.getAppName(), version = buildMeta.versionName ) - val sessionId = activeSessionHolder.getActiveSession().sessionParams.deviceId - val storedClientInfo = sessionId?.let { getMatrixClientInfoUseCase.execute(it) } + val deviceId = activeSessionHolder.getActiveSession().sessionParams.deviceId.orEmpty() + val storedClientInfo = deviceId + .takeUnless { it.isEmpty() } + ?.let { getMatrixClientInfoUseCase.execute(it) } if (clientInfo != storedClientInfo) { setMatrixClientInfoUseCase.execute(clientInfo) } diff --git a/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCaseTest.kt new file mode 100644 index 0000000000..9e04d6984e --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/settings/devices/v2/details/extended/SetMatrixClientInfoUseCaseTest.kt @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.devices.v2.details.extended + +import MATRIX_CLIENT_INFO_KEY_PREFIX +import im.vector.app.test.fakes.FakeActiveSessionHolder +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.shouldBe +import org.amshove.kluent.shouldBeEqualTo +import org.amshove.kluent.shouldBeInstanceOf +import org.junit.Test +import org.matrix.android.sdk.api.session.events.model.toContent + +private const val A_DEVICE_ID = "device-id" + +class SetMatrixClientInfoUseCaseTest { + + private val fakeActiveSessionHolder = FakeActiveSessionHolder() + + private val setMatrixClientInfoUseCase = SetMatrixClientInfoUseCase( + activeSessionHolder = fakeActiveSessionHolder.instance + ) + + @Test + fun `given client info and no error when setting the info then account data is correctly updated`() = runTest { + // Given + val type = MATRIX_CLIENT_INFO_KEY_PREFIX + A_DEVICE_ID + val clientInfo = givenClientInfo() + val content = clientInfo.toContent() + fakeActiveSessionHolder.fakeSession + .givenSessionId(A_DEVICE_ID) + fakeActiveSessionHolder.fakeSession + .fakeSessionAccountDataService + .givenUpdateUserAccountDataEventSucceeds() + + // When + val result = setMatrixClientInfoUseCase.execute(clientInfo) + + // Then + result.isSuccess shouldBe true + fakeActiveSessionHolder.fakeSession + .fakeSessionAccountDataService + .verifyUpdateUserAccountDataEventSucceeds(type, content) + } + + @Test + fun `given client info and error during update when setting the info then result is failure`() = runTest { + // Given + val type = MATRIX_CLIENT_INFO_KEY_PREFIX + A_DEVICE_ID + val clientInfo = givenClientInfo() + val content = clientInfo.toContent() + fakeActiveSessionHolder.fakeSession + .givenSessionId(A_DEVICE_ID) + val error = Exception() + fakeActiveSessionHolder.fakeSession + .fakeSessionAccountDataService + .givenUpdateUserAccountDataEventFailsWithError(error) + + // When + val result = setMatrixClientInfoUseCase.execute(clientInfo) + + // Then + result.isFailure shouldBe true + result.exceptionOrNull() shouldBeEqualTo error + fakeActiveSessionHolder.fakeSession + .fakeSessionAccountDataService + .verifyUpdateUserAccountDataEventSucceeds(type, content) + } + + @Test + fun `given client info and null device id when setting the info then result is failure`() = runTest { + // Given + val type = MATRIX_CLIENT_INFO_KEY_PREFIX + A_DEVICE_ID + val clientInfo = givenClientInfo() + val content = clientInfo.toContent() + fakeActiveSessionHolder.fakeSession + .givenSessionId(null) + + // When + val result = setMatrixClientInfoUseCase.execute(clientInfo) + + // Then + result.isFailure shouldBe true + result.exceptionOrNull() shouldBeInstanceOf IllegalStateException::class + fakeActiveSessionHolder.fakeSession + .fakeSessionAccountDataService + .verifyUpdateUserAccountDataEventSucceeds(type, content, inverse = true) + } + + private fun givenClientInfo() = MatrixClientInfoContent( + name = "name", + version = "version", + url = null, + ) +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt index 29b634eb0c..9fc876e666 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSession.kt @@ -82,7 +82,7 @@ class FakeSession( every { this@FakeSession.sessionParams } returns sessionParams } - fun givenSessionId(sessionId: String): SessionParams { + fun givenSessionId(sessionId: String?): SessionParams { val sessionParams = mockk() every { sessionParams.deviceId } returns sessionId givenSessionParams(sessionParams) diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt index 5b9c918b64..34a0d8edb3 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeSessionAccountDataService.kt @@ -16,8 +16,12 @@ package im.vector.app.test.fakes +import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.every +import io.mockk.just import io.mockk.mockk +import io.mockk.runs import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.events.model.Content @@ -27,4 +31,16 @@ class FakeSessionAccountDataService : SessionAccountDataService by mockk() { fun givenGetUserAccountDataEventReturns(type: String, content: Content) { every { getUserAccountDataEvent(type) } returns UserAccountDataEvent(type, content) } + + fun givenUpdateUserAccountDataEventSucceeds() { + coEvery { updateUserAccountData(any(), any()) } just runs + } + + fun givenUpdateUserAccountDataEventFailsWithError(error: Exception) { + coEvery { updateUserAccountData(any(), any()) } throws error + } + + fun verifyUpdateUserAccountDataEventSucceeds(type: String, content: Content, inverse: Boolean = false) { + coVerify(inverse = inverse) { updateUserAccountData(type, content) } + } }