From fc8114368741b4c8a4667c8011564818fb92d73b Mon Sep 17 00:00:00 2001 From: ohassine Date: Wed, 20 Nov 2024 11:53:23 +0100 Subject: [PATCH 01/10] feat: add use case to check if backend supports personal to team migration --- .../server/ServerConfigRepository.kt | 7 +- ...lToTeamAccountSupportedByBackendUseCase.kt | 42 ++++++ .../kalium/logic/feature/user/UserScope.kt | 7 + ...eamAccountSupportedByBackendUseCaseTest.kt | 121 ++++++++++++++++++ .../kalium/persistence/ServerConfiguration.sq | 3 + .../daokaliumdb/ServerConfigurationDAO.kt | 5 + 6 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt create mode 100644 logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt index 54f10b8df38..bbbf3a3156c 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt @@ -39,7 +39,7 @@ import com.wire.kalium.util.KaliumDispatcherImpl import io.ktor.http.Url import kotlinx.coroutines.withContext -internal interface ServerConfigRepository { +interface ServerConfigRepository { suspend fun getOrFetchMetadata(serverLinks: ServerConfig.Links): Either suspend fun storeConfig(links: ServerConfig.Links, metadata: ServerConfig.MetaData): Either @@ -62,6 +62,7 @@ internal interface ServerConfigRepository { * Return the server links and metadata for the given userId */ suspend fun configForUser(userId: UserId): Either + suspend fun commonApiVersion(domain: String): Either } @Suppress("LongParameterList", "TooManyFunctions") @@ -134,6 +135,10 @@ internal class ServerConfigDataSource( wrapStorageRequest { dao.configForUser(userId.toDao()) } .map { serverConfigMapper.fromEntity(it) } + override suspend fun commonApiVersion(domain: String): Either = wrapStorageRequest { + dao.getCommonApiVersion(domain) + } + private suspend fun fetchMetadata(serverLinks: ServerConfig.Links): Either = wrapApiRequest { versionApi.fetchApiVersion(Url(serverLinks.api)) } .flatMap { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt new file mode 100644 index 00000000000..fc5668a861e --- /dev/null +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt @@ -0,0 +1,42 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.personaltoteamaccount + +import com.wire.kalium.logic.configuration.server.ServerConfigRepository +import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.functional.fold + +interface IsPersonalToTeamAccountSupportedByBackendUseCase { + suspend operator fun invoke(): Boolean +} + +class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( + val serverConfigRepository: ServerConfigRepository, + val userId: UserId +) : IsPersonalToTeamAccountSupportedByBackendUseCase { + override suspend fun invoke(): Boolean { + return serverConfigRepository.commonApiVersion(userId.domain).fold( + { false }, + { it >= MIN_API_VERSION } + ) + } + + companion object { + const val MIN_API_VERSION = 7 + } +} diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt index 82c9a0bd336..ea49ee51c42 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt @@ -67,6 +67,8 @@ import com.wire.kalium.logic.feature.featureConfig.FeatureFlagSyncWorkerImpl import com.wire.kalium.logic.feature.featureConfig.FeatureFlagsSyncWorker import com.wire.kalium.logic.feature.featureConfig.SyncFeatureConfigsUseCase import com.wire.kalium.logic.feature.message.MessageSender +import com.wire.kalium.logic.feature.personaltoteamaccount.IsPersonalToTeamAccountSupportedByBackendUseCase +import com.wire.kalium.logic.feature.personaltoteamaccount.IsPersonalToTeamAccountSupportedByBackendUseCaseImpl import com.wire.kalium.logic.feature.publicuser.GetAllContactsUseCase import com.wire.kalium.logic.feature.publicuser.GetAllContactsUseCaseImpl import com.wire.kalium.logic.feature.publicuser.GetKnownUserUseCase @@ -223,4 +225,9 @@ class UserScope internal constructor( kaliumLogger = userScopedLogger, ) } + val isPersonalToTeamAccountSupportedByBackend: IsPersonalToTeamAccountSupportedByBackendUseCase + get() = IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( + serverConfigRepository = serverConfigRepository, + userId = selfUserId + ) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt new file mode 100644 index 00000000000..936a458b915 --- /dev/null +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt @@ -0,0 +1,121 @@ +/* + * Wire + * Copyright (C) 2024 Wire Swiss GmbH + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/. + */ +package com.wire.kalium.logic.feature.personaltoteamaccount + +import com.wire.kalium.logic.CoreFailure +import com.wire.kalium.logic.configuration.server.ServerConfigRepository +import com.wire.kalium.logic.framework.TestUser +import com.wire.kalium.logic.functional.Either +import io.mockative.Mock +import io.mockative.coEvery +import io.mockative.coVerify +import io.mockative.mock +import io.mockative.once +import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { + + @Test + fun `given API version below minimum when invoking then returns false`() = runTest { + // Given + val (arrangement, useCase) = Arrangement() + .withRepositoryReturning(Either.Right(6)) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertFalse(result) + coVerify { + arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) + }.wasInvoked(once) + } + + @Test + fun `given API version equal to minimum when invoking then returns true`() = runBlocking { + // Given + val (arrangement, useCase) = Arrangement() + .withRepositoryReturning(Either.Right(7)) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertTrue(result) + coVerify { + arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) + }.wasInvoked(once) + } + + @Test + fun `given API version above minimum when invoking then returns true`() = runBlocking { + // Given + val (arrangement, useCase) = Arrangement() + .withRepositoryReturning(Either.Right(8)) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertTrue(result) + coVerify { + arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) + }.wasInvoked(once) + } + + @Test + fun `given error fetching API version when invoking then returns false`() = runTest { + // Given + val (arrangement, useCase) = Arrangement() + .withRepositoryReturning(Either.Left(CoreFailure.SyncEventOrClientNotFound)) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertFalse(result) + coVerify { + arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) + }.wasInvoked(once) + } + + private class Arrangement { + + @Mock + val serverConfigRepository = mock(ServerConfigRepository::class) + + suspend fun withRepositoryReturning(value: Either) = apply { + coEvery { + serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) + }.returns(value) + } + + fun arrange() = this to IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( + serverConfigRepository = serverConfigRepository, + userId = TestUser.USER_ID + ) + } +} diff --git a/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq b/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq index b09efc6e29a..48a8d2fe6fe 100644 --- a/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq +++ b/persistence/src/commonMain/db_global/com/wire/kalium/persistence/ServerConfiguration.sq @@ -35,6 +35,9 @@ UPDATE ServerConfiguration SET commonApiVersion = ? WHERE id = ?; updateApiVersionAndDomain: UPDATE ServerConfiguration SET commonApiVersion = ?, domain = ? WHERE id = ?; +getCommonApiVersionByDomain: +SELECT commonApiVersion FROM ServerConfiguration WHERE domain = ?; + updateLastBlackListCheckByIds: UPDATE ServerConfiguration SET lastBlackListCheck = ? WHERE id IN ?; diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt index 707e857eb1c..7774eae162a 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/daokaliumdb/ServerConfigurationDAO.kt @@ -126,6 +126,7 @@ interface ServerConfigurationDAO { fun configById(id: String): ServerConfigEntity? suspend fun configByLinks(links: ServerConfigEntity.Links): ServerConfigEntity? suspend fun updateApiVersion(id: String, commonApiVersion: Int) + suspend fun getCommonApiVersion(domain: String): Int suspend fun updateApiVersionAndDomain(id: String, domain: String, commonApiVersion: Int) suspend fun configForUser(userId: UserIDEntity): ServerConfigEntity? suspend fun setFederationToTrue(id: String) @@ -213,6 +214,10 @@ internal class ServerConfigurationDAOImpl internal constructor( queries.updateApiVersion(commonApiVersion, id) } + override suspend fun getCommonApiVersion(domain: String): Int = withContext(queriesContext) { + queries.getCommonApiVersionByDomain(domain).executeAsOne() + } + override suspend fun updateApiVersionAndDomain(id: String, domain: String, commonApiVersion: Int) = withContext(queriesContext) { queries.updateApiVersionAndDomain(commonApiVersion, domain, id) From e4a7f66cf26ac858db7afea5f7177f38822f35f0 Mon Sep 17 00:00:00 2001 From: ohassine Date: Wed, 20 Nov 2024 12:01:17 +0100 Subject: [PATCH 02/10] feat: detekt --- .../IsPersonalToTeamAccountSupportedByBackendUseCase.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt index fc5668a861e..b283a590845 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt @@ -21,6 +21,9 @@ import com.wire.kalium.logic.configuration.server.ServerConfigRepository import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.functional.fold +/** + * Use case to check if the backend supports personal to team account migration. + */ interface IsPersonalToTeamAccountSupportedByBackendUseCase { suspend operator fun invoke(): Boolean } From 3a2940068eb18316e410ed9666a840cf2c1ea40f Mon Sep 17 00:00:00 2001 From: ohassine Date: Wed, 20 Nov 2024 13:47:17 +0100 Subject: [PATCH 03/10] chore: unit test --- .../IsPersonalToTeamAccountSupportedByBackendUseCase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt index b283a590845..45d968729b7 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt @@ -28,7 +28,7 @@ interface IsPersonalToTeamAccountSupportedByBackendUseCase { suspend operator fun invoke(): Boolean } -class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( +internal class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( val serverConfigRepository: ServerConfigRepository, val userId: UserId ) : IsPersonalToTeamAccountSupportedByBackendUseCase { From 63633ba3af18beb8c72a145ad8931c2c43678c45 Mon Sep 17 00:00:00 2001 From: ohassine Date: Wed, 20 Nov 2024 15:37:48 +0100 Subject: [PATCH 04/10] chore: address comment --- .../IsPersonalToTeamAccountSupportedByBackendUseCase.kt | 5 +---- ...sPersonalToTeamAccountSupportedByBackendUseCaseTest.kt | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt index 45d968729b7..674b914cece 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt @@ -20,6 +20,7 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.functional.fold +import com.wire.kalium.network.api.base.authenticated.UpgradePersonalToTeamApi.Companion.MIN_API_VERSION /** * Use case to check if the backend supports personal to team account migration. @@ -38,8 +39,4 @@ internal class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( { it >= MIN_API_VERSION } ) } - - companion object { - const val MIN_API_VERSION = 7 - } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt index 936a458b915..87bc7c18ce2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt @@ -35,7 +35,7 @@ import kotlin.test.assertTrue class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { @Test - fun `given API version below minimum when invoking then returns false`() = runTest { + fun givenAPIVersionBelowMinimum_whenInvoking_thenReturnsFalse() = runTest { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturning(Either.Right(6)) @@ -52,7 +52,7 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { } @Test - fun `given API version equal to minimum when invoking then returns true`() = runBlocking { + fun givenAPIVersionEqualToMinimum_whenInvoking_thenReturnsTrue() = runBlocking { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturning(Either.Right(7)) @@ -69,7 +69,7 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { } @Test - fun `given API version above minimum when invoking then returns true`() = runBlocking { + fun givenAPIVersionAboveMinimum_whenInvoking_thenReturnsTrue() = runBlocking { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturning(Either.Right(8)) @@ -86,7 +86,7 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { } @Test - fun `given error fetching API version when invoking then returns false`() = runTest { + fun givenErrorFetchingAPIVersion_whenInvoking_thenReturnsFalse() = runTest { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturning(Either.Left(CoreFailure.SyncEventOrClientNotFound)) From 39d87105fe33188f51abb10ddd7b63702944d1dd Mon Sep 17 00:00:00 2001 From: ohassine Date: Wed, 20 Nov 2024 17:43:48 +0100 Subject: [PATCH 05/10] chore: cleanup --- .../server/ServerConfigRepository.kt | 11 +++++--- ...lToTeamAccountSupportedByBackendUseCase.kt | 3 +-- ...eamAccountSupportedByBackendUseCaseTest.kt | 25 +++++++++++++++---- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt index bbbf3a3156c..faef6688735 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/configuration/server/ServerConfigRepository.kt @@ -31,8 +31,9 @@ import com.wire.kalium.logic.functional.fold import com.wire.kalium.logic.functional.map import com.wire.kalium.logic.wrapApiRequest import com.wire.kalium.logic.wrapStorageRequest -import com.wire.kalium.network.api.unbound.configuration.ApiVersionDTO +import com.wire.kalium.network.api.base.authenticated.UpgradePersonalToTeamApi.Companion.MIN_API_VERSION import com.wire.kalium.network.api.base.unbound.versioning.VersionApi +import com.wire.kalium.network.api.unbound.configuration.ApiVersionDTO import com.wire.kalium.persistence.daokaliumdb.ServerConfigurationDAO import com.wire.kalium.util.KaliumDispatcher import com.wire.kalium.util.KaliumDispatcherImpl @@ -40,6 +41,8 @@ import io.ktor.http.Url import kotlinx.coroutines.withContext interface ServerConfigRepository { + val minimumApiVersionForPersonalToTeamAccountMigration: Int + suspend fun getOrFetchMetadata(serverLinks: ServerConfig.Links): Either suspend fun storeConfig(links: ServerConfig.Links, metadata: ServerConfig.MetaData): Either @@ -73,6 +76,8 @@ internal class ServerConfigDataSource( private val dispatchers: KaliumDispatcher = KaliumDispatcherImpl ) : ServerConfigRepository { + override val minimumApiVersionForPersonalToTeamAccountMigration = MIN_API_VERSION + override suspend fun getOrFetchMetadata(serverLinks: ServerConfig.Links): Either = wrapStorageRequest { dao.configByLinks(serverConfigMapper.toEntity(serverLinks)) }.fold({ fetchApiVersionAndStore(serverLinks) @@ -128,8 +133,8 @@ internal class ServerConfigDataSource( } override suspend fun updateConfigApiVersion(serverConfig: ServerConfig): Either = - fetchMetadata(serverConfig.links) - .flatMap { wrapStorageRequest { dao.updateApiVersion(serverConfig.id, it.commonApiVersion.version) } } + fetchMetadata(serverConfig.links) + .flatMap { wrapStorageRequest { dao.updateApiVersion(serverConfig.id, it.commonApiVersion.version) } } override suspend fun configForUser(userId: UserId): Either = wrapStorageRequest { dao.configForUser(userId.toDao()) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt index 674b914cece..3d90ea5f4b9 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt @@ -20,7 +20,6 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.functional.fold -import com.wire.kalium.network.api.base.authenticated.UpgradePersonalToTeamApi.Companion.MIN_API_VERSION /** * Use case to check if the backend supports personal to team account migration. @@ -36,7 +35,7 @@ internal class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( override suspend fun invoke(): Boolean { return serverConfigRepository.commonApiVersion(userId.domain).fold( { false }, - { it >= MIN_API_VERSION } + { it >= serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration } ) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt index 87bc7c18ce2..3f6193d0599 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt @@ -24,6 +24,7 @@ import com.wire.kalium.logic.functional.Either import io.mockative.Mock import io.mockative.coEvery import io.mockative.coVerify +import io.mockative.every import io.mockative.mock import io.mockative.once import kotlinx.coroutines.runBlocking @@ -38,7 +39,8 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { fun givenAPIVersionBelowMinimum_whenInvoking_thenReturnsFalse() = runTest { // Given val (arrangement, useCase) = Arrangement() - .withRepositoryReturning(Either.Right(6)) + .withRepositoryReturningMinimumApiVersion() + .withRepositoryReturningCommonApiVersion(Either.Right(6)) .arrange() // When @@ -55,7 +57,8 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { fun givenAPIVersionEqualToMinimum_whenInvoking_thenReturnsTrue() = runBlocking { // Given val (arrangement, useCase) = Arrangement() - .withRepositoryReturning(Either.Right(7)) + .withRepositoryReturningMinimumApiVersion() + .withRepositoryReturningCommonApiVersion(Either.Right(7)) .arrange() // When @@ -72,7 +75,8 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { fun givenAPIVersionAboveMinimum_whenInvoking_thenReturnsTrue() = runBlocking { // Given val (arrangement, useCase) = Arrangement() - .withRepositoryReturning(Either.Right(8)) + .withRepositoryReturningMinimumApiVersion() + .withRepositoryReturningCommonApiVersion(Either.Right(8)) .arrange() // When @@ -89,7 +93,8 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { fun givenErrorFetchingAPIVersion_whenInvoking_thenReturnsFalse() = runTest { // Given val (arrangement, useCase) = Arrangement() - .withRepositoryReturning(Either.Left(CoreFailure.SyncEventOrClientNotFound)) + .withRepositoryReturningMinimumApiVersion() + .withRepositoryReturningCommonApiVersion(Either.Left(CoreFailure.SyncEventOrClientNotFound)) .arrange() // When @@ -107,15 +112,25 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { @Mock val serverConfigRepository = mock(ServerConfigRepository::class) - suspend fun withRepositoryReturning(value: Either) = apply { + suspend fun withRepositoryReturningCommonApiVersion(value: Either) = apply { coEvery { serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) }.returns(value) } + fun withRepositoryReturningMinimumApiVersion() = apply { + every { + serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration + }.returns(MIN_API_VERSION) + } + fun arrange() = this to IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( serverConfigRepository = serverConfigRepository, userId = TestUser.USER_ID ) } + + companion object { + private const val MIN_API_VERSION = 7 + } } From a1dd30d26ae7df1472195d28da61a5e2df8cca43 Mon Sep 17 00:00:00 2001 From: ohassine Date: Thu, 21 Nov 2024 10:42:11 +0100 Subject: [PATCH 06/10] chore: address comments --- ...=> CanMigrateFromPersonalToTeamUseCase.kt} | 21 ++++++++++----- .../kalium/logic/feature/user/UserScope.kt | 11 ++++---- ...anMigrateFromPersonalToTeamUseCaseTest.kt} | 27 ++++++++++++++----- 3 files changed, 42 insertions(+), 17 deletions(-) rename logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/{IsPersonalToTeamAccountSupportedByBackendUseCase.kt => CanMigrateFromPersonalToTeamUseCase.kt} (62%) rename logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/{IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt => CanMigrateFromPersonalToTeamUseCaseTest.kt} (80%) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt similarity index 62% rename from logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt rename to logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt index 3d90ea5f4b9..273f58ace79 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt @@ -19,23 +19,32 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.data.user.UserRepository import com.wire.kalium.logic.functional.fold /** - * Use case to check if the backend supports personal to team account migration. + * Use case to check if the user can migrate from personal to team account. + * The user can migrate if the user is not in a team and the server supports the migration. */ -interface IsPersonalToTeamAccountSupportedByBackendUseCase { +interface CanMigrateFromPersonalToTeamUseCase { suspend operator fun invoke(): Boolean } -internal class IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( +internal class CanMigrateFromPersonalToTeamUseCaseImpl( val serverConfigRepository: ServerConfigRepository, - val userId: UserId -) : IsPersonalToTeamAccountSupportedByBackendUseCase { + val userId: UserId, + val userRepository: UserRepository +) : CanMigrateFromPersonalToTeamUseCase { override suspend fun invoke(): Boolean { return serverConfigRepository.commonApiVersion(userId.domain).fold( { false }, - { it >= serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration } + { + val minApi = serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration + if (userRepository.getSelfUser()?.teamId == null && it >= minApi) { + return true + } + false + } ) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt index ea49ee51c42..0941f007816 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt @@ -67,8 +67,8 @@ import com.wire.kalium.logic.feature.featureConfig.FeatureFlagSyncWorkerImpl import com.wire.kalium.logic.feature.featureConfig.FeatureFlagsSyncWorker import com.wire.kalium.logic.feature.featureConfig.SyncFeatureConfigsUseCase import com.wire.kalium.logic.feature.message.MessageSender -import com.wire.kalium.logic.feature.personaltoteamaccount.IsPersonalToTeamAccountSupportedByBackendUseCase -import com.wire.kalium.logic.feature.personaltoteamaccount.IsPersonalToTeamAccountSupportedByBackendUseCaseImpl +import com.wire.kalium.logic.feature.personaltoteamaccount.CanMigrateFromPersonalToTeamUseCase +import com.wire.kalium.logic.feature.personaltoteamaccount.CanMigrateFromPersonalToTeamUseCaseImpl import com.wire.kalium.logic.feature.publicuser.GetAllContactsUseCase import com.wire.kalium.logic.feature.publicuser.GetAllContactsUseCaseImpl import com.wire.kalium.logic.feature.publicuser.GetKnownUserUseCase @@ -225,9 +225,10 @@ class UserScope internal constructor( kaliumLogger = userScopedLogger, ) } - val isPersonalToTeamAccountSupportedByBackend: IsPersonalToTeamAccountSupportedByBackendUseCase - get() = IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( + val isPersonalToTeamAccountSupportedByBackend: CanMigrateFromPersonalToTeamUseCase + get() = CanMigrateFromPersonalToTeamUseCaseImpl( serverConfigRepository = serverConfigRepository, - userId = selfUserId + userId = selfUserId, + userRepository = userRepository ) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt similarity index 80% rename from logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt rename to logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt index 3f6193d0599..13259809863 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/IsPersonalToTeamAccountSupportedByBackendUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt @@ -19,6 +19,8 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.configuration.server.ServerConfigRepository +import com.wire.kalium.logic.data.id.TeamId +import com.wire.kalium.logic.data.user.UserRepository import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either import io.mockative.Mock @@ -33,13 +35,14 @@ import kotlin.test.Test import kotlin.test.assertFalse import kotlin.test.assertTrue -class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { +class CanMigrateFromPersonalToTeamUseCaseTest { @Test - fun givenAPIVersionBelowMinimum_whenInvoking_thenReturnsFalse() = runTest { + fun givenAPIVersionBelowMinimumAndUserNotInATeam_whenInvoking_thenReturnsFalse() = runTest { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() + .withTeamId(null) .withRepositoryReturningCommonApiVersion(Either.Right(6)) .arrange() @@ -54,10 +57,11 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { } @Test - fun givenAPIVersionEqualToMinimum_whenInvoking_thenReturnsTrue() = runBlocking { + fun givenAPIVersionEqualToMinimumAndUserNotInATeam_whenInvoking_thenReturnsTrue() = runBlocking { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() + .withTeamId(null) .withRepositoryReturningCommonApiVersion(Either.Right(7)) .arrange() @@ -72,10 +76,11 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { } @Test - fun givenAPIVersionAboveMinimum_whenInvoking_thenReturnsTrue() = runBlocking { + fun givenAPIVersionAboveMinimumAndUserInATeam_whenInvoking_thenReturnsFalse() = runBlocking { // Given val (arrangement, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() + .withTeamId(TeamId("teamId")) .withRepositoryReturningCommonApiVersion(Either.Right(8)) .arrange() @@ -83,7 +88,7 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { val result = useCase.invoke() // Then - assertTrue(result) + assertFalse(result) coVerify { arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) }.wasInvoked(once) @@ -112,20 +117,30 @@ class IsPersonalToTeamAccountSupportedByBackendUseCaseTest { @Mock val serverConfigRepository = mock(ServerConfigRepository::class) + @Mock + val userRepository = mock(UserRepository::class) + suspend fun withRepositoryReturningCommonApiVersion(value: Either) = apply { coEvery { serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) }.returns(value) } + suspend fun withTeamId(result: TeamId?) = apply { + coEvery { + userRepository.getSelfUser() + }.returns(TestUser.SELF.copy(teamId = result)) + } + fun withRepositoryReturningMinimumApiVersion() = apply { every { serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration }.returns(MIN_API_VERSION) } - fun arrange() = this to IsPersonalToTeamAccountSupportedByBackendUseCaseImpl( + fun arrange() = this to CanMigrateFromPersonalToTeamUseCaseImpl( serverConfigRepository = serverConfigRepository, + userRepository = userRepository, userId = TestUser.USER_ID ) } From 6aac45d4e47874aafb004c06c5ccb14dd5fa8d8f Mon Sep 17 00:00:00 2001 From: ohassine Date: Thu, 21 Nov 2024 11:50:16 +0100 Subject: [PATCH 07/10] chore: address comments --- .../kalium/logic/feature/UserSessionScope.kt | 1 + .../CanMigrateFromPersonalToTeamUseCase.kt | 18 +--- .../kalium/logic/feature/user/UserScope.kt | 24 +++-- ...CanMigrateFromPersonalToTeamUseCaseTest.kt | 91 ++++++++----------- 4 files changed, 56 insertions(+), 78 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt index ae927be25bb..75811b8e482 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt @@ -1889,6 +1889,7 @@ class UserSessionScope internal constructor( isE2EIEnabled, certificateRevocationListRepository, incrementalSyncRepository, + sessionManager, checkRevocationList, syncFeatureConfigsUseCase, userScopedLogger diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt index 273f58ace79..1b8945affec 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt @@ -18,9 +18,8 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository -import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.UserRepository -import com.wire.kalium.logic.functional.fold +import com.wire.kalium.network.session.SessionManager /** * Use case to check if the user can migrate from personal to team account. @@ -31,20 +30,13 @@ interface CanMigrateFromPersonalToTeamUseCase { } internal class CanMigrateFromPersonalToTeamUseCaseImpl( + val sessionManager: SessionManager, val serverConfigRepository: ServerConfigRepository, - val userId: UserId, val userRepository: UserRepository ) : CanMigrateFromPersonalToTeamUseCase { override suspend fun invoke(): Boolean { - return serverConfigRepository.commonApiVersion(userId.domain).fold( - { false }, - { - val minApi = serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration - if (userRepository.getSelfUser()?.teamId == null && it >= minApi) { - return true - } - false - } - ) + val commonApiVersion = sessionManager.serverConfig().metaData.commonApiVersion.version + val minApi = serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration + return userRepository.getSelfUser()?.teamId == null && commonApiVersion >= minApi } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt index 0941f007816..4d1838a9ba1 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt @@ -83,6 +83,7 @@ import com.wire.kalium.logic.feature.user.typingIndicator.ObserveTypingIndicator import com.wire.kalium.logic.feature.user.typingIndicator.PersistTypingIndicatorStatusConfigUseCase import com.wire.kalium.logic.feature.user.typingIndicator.PersistTypingIndicatorStatusConfigUseCaseImpl import com.wire.kalium.logic.sync.SyncManager +import com.wire.kalium.network.session.SessionManager import com.wire.kalium.persistence.dao.MetadataDAO @Suppress("LongParameterList") @@ -111,6 +112,7 @@ class UserScope internal constructor( private val isE2EIEnabledUseCase: IsE2EIEnabledUseCase, private val certificateRevocationListRepository: CertificateRevocationListRepository, private val incrementalSyncRepository: IncrementalSyncRepository, + private val sessionManager: SessionManager, private val checkRevocationList: RevocationListChecker, private val syncFeatureConfigs: SyncFeatureConfigsUseCase, private val userScopedLogger: KaliumLogger @@ -210,13 +212,14 @@ class UserScope internal constructor( kaliumLogger = userScopedLogger, ) - val syncCertificateRevocationListUseCase: SyncCertificateRevocationListUseCase get() = - SyncCertificateRevocationListUseCase( - certificateRevocationListRepository = certificateRevocationListRepository, - incrementalSyncRepository = incrementalSyncRepository, - revocationListChecker = checkRevocationList, - kaliumLogger = userScopedLogger, - ) + val syncCertificateRevocationListUseCase: SyncCertificateRevocationListUseCase + get() = + SyncCertificateRevocationListUseCase( + certificateRevocationListRepository = certificateRevocationListRepository, + incrementalSyncRepository = incrementalSyncRepository, + revocationListChecker = checkRevocationList, + kaliumLogger = userScopedLogger, + ) val featureFlagsSyncWorker: FeatureFlagsSyncWorker by lazy { FeatureFlagSyncWorkerImpl( @@ -225,10 +228,11 @@ class UserScope internal constructor( kaliumLogger = userScopedLogger, ) } - val isPersonalToTeamAccountSupportedByBackend: CanMigrateFromPersonalToTeamUseCase - get() = CanMigrateFromPersonalToTeamUseCaseImpl( + val isPersonalToTeamAccountSupportedByBackend: CanMigrateFromPersonalToTeamUseCase by lazy { + CanMigrateFromPersonalToTeamUseCaseImpl( + sessionManager = sessionManager, serverConfigRepository = serverConfigRepository, - userId = selfUserId, userRepository = userRepository ) + } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt index 13259809863..72f45a154de 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt @@ -17,18 +17,17 @@ */ package com.wire.kalium.logic.feature.personaltoteamaccount -import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.configuration.server.ServerConfigRepository import com.wire.kalium.logic.data.id.TeamId import com.wire.kalium.logic.data.user.UserRepository import com.wire.kalium.logic.framework.TestUser -import com.wire.kalium.logic.functional.Either +import com.wire.kalium.network.api.unbound.configuration.ApiVersionDTO +import com.wire.kalium.network.session.SessionManager +import com.wire.kalium.network.utils.TestRequestHandler.Companion.TEST_BACKEND_CONFIG import io.mockative.Mock import io.mockative.coEvery -import io.mockative.coVerify import io.mockative.every import io.mockative.mock -import io.mockative.once import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import kotlin.test.Test @@ -43,7 +42,7 @@ class CanMigrateFromPersonalToTeamUseCaseTest { val (arrangement, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() .withTeamId(null) - .withRepositoryReturningCommonApiVersion(Either.Right(6)) + .withServerConfig(6) .arrange() // When @@ -51,29 +50,24 @@ class CanMigrateFromPersonalToTeamUseCaseTest { // Then assertFalse(result) - coVerify { - arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) - }.wasInvoked(once) } @Test - fun givenAPIVersionEqualToMinimumAndUserNotInATeam_whenInvoking_thenReturnsTrue() = runBlocking { - // Given - val (arrangement, useCase) = Arrangement() - .withRepositoryReturningMinimumApiVersion() - .withTeamId(null) - .withRepositoryReturningCommonApiVersion(Either.Right(7)) - .arrange() - - // When - val result = useCase.invoke() - - // Then - assertTrue(result) - coVerify { - arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) - }.wasInvoked(once) - } + fun givenAPIVersionEqualToMinimumAndUserNotInATeam_whenInvoking_thenReturnsTrue() = + runBlocking { + // Given + val (arrangement, useCase) = Arrangement() + .withRepositoryReturningMinimumApiVersion() + .withServerConfig(7) + .withTeamId(null) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertTrue(result) + } @Test fun givenAPIVersionAboveMinimumAndUserInATeam_whenInvoking_thenReturnsFalse() = runBlocking { @@ -81,7 +75,7 @@ class CanMigrateFromPersonalToTeamUseCaseTest { val (arrangement, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() .withTeamId(TeamId("teamId")) - .withRepositoryReturningCommonApiVersion(Either.Right(8)) + .withServerConfig(9) .arrange() // When @@ -89,27 +83,6 @@ class CanMigrateFromPersonalToTeamUseCaseTest { // Then assertFalse(result) - coVerify { - arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) - }.wasInvoked(once) - } - - @Test - fun givenErrorFetchingAPIVersion_whenInvoking_thenReturnsFalse() = runTest { - // Given - val (arrangement, useCase) = Arrangement() - .withRepositoryReturningMinimumApiVersion() - .withRepositoryReturningCommonApiVersion(Either.Left(CoreFailure.SyncEventOrClientNotFound)) - .arrange() - - // When - val result = useCase.invoke() - - // Then - assertFalse(result) - coVerify { - arrangement.serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) - }.wasInvoked(once) } private class Arrangement { @@ -118,13 +91,10 @@ class CanMigrateFromPersonalToTeamUseCaseTest { val serverConfigRepository = mock(ServerConfigRepository::class) @Mock - val userRepository = mock(UserRepository::class) + val sessionManager = mock(SessionManager::class) - suspend fun withRepositoryReturningCommonApiVersion(value: Either) = apply { - coEvery { - serverConfigRepository.commonApiVersion(TestUser.USER_ID.domain) - }.returns(value) - } + @Mock + val userRepository = mock(UserRepository::class) suspend fun withTeamId(result: TeamId?) = apply { coEvery { @@ -138,10 +108,21 @@ class CanMigrateFromPersonalToTeamUseCaseTest { }.returns(MIN_API_VERSION) } + fun withServerConfig(apiVersion: Int) = apply { + val backendConfig = TEST_BACKEND_CONFIG.copy( + metaData = TEST_BACKEND_CONFIG.metaData.copy( + commonApiVersion = ApiVersionDTO.Valid(apiVersion) + ) + ) + every { + sessionManager.serverConfig() + }.returns(backendConfig) + } + fun arrange() = this to CanMigrateFromPersonalToTeamUseCaseImpl( + sessionManager = sessionManager, serverConfigRepository = serverConfigRepository, - userRepository = userRepository, - userId = TestUser.USER_ID + userRepository = userRepository ) } From 0b937572fd7415f3d30e69fb500e3570caebd264 Mon Sep 17 00:00:00 2001 From: ohassine Date: Thu, 21 Nov 2024 13:57:26 +0100 Subject: [PATCH 08/10] chore: cleanup --- .../CanMigrateFromPersonalToTeamUseCase.kt | 3 +++ .../kotlin/com/wire/kalium/logic/network/SessionManagerImpl.kt | 1 + 2 files changed, 4 insertions(+) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt index 1b8945affec..b698bea111f 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt @@ -15,6 +15,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ + +@file:Suppress("konsist.useCasesShouldNotAccessNetworkLayerDirectly") + package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/network/SessionManagerImpl.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/network/SessionManagerImpl.kt index fb655297cb8..7249c4da12f 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/network/SessionManagerImpl.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/network/SessionManagerImpl.kt @@ -50,6 +50,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.withContext import kotlin.coroutines.CoroutineContext +// TODO: Move this class to logic module @OptIn(ExperimentalCoroutinesApi::class) @Suppress("LongParameterList") class SessionManagerImpl internal constructor( From 646017f2dbad2fad84f6d837436682d5aab07def Mon Sep 17 00:00:00 2001 From: ohassine Date: Thu, 21 Nov 2024 14:41:55 +0100 Subject: [PATCH 09/10] chore: cleanup --- .../kotlin/com/wire/kalium/logic/feature/user/UserScope.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt index 4d1838a9ba1..e7b03086a33 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt @@ -15,7 +15,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. */ -@file:Suppress("konsist.useCasesShouldNotAccessDaoLayerDirectly") +@file:Suppress("konsist.useCasesShouldNotAccessDaoLayerDirectly", "konsist.useCasesShouldNotAccessNetworkLayerDirectly") package com.wire.kalium.logic.feature.user From 953dfc944344df6e0af477af89dd9cf79a6126cc Mon Sep 17 00:00:00 2001 From: ohassine Date: Thu, 21 Nov 2024 15:14:06 +0100 Subject: [PATCH 10/10] chore: use selfTeamIdProvider --- .../kalium/logic/feature/UserSessionScope.kt | 1 + .../CanMigrateFromPersonalToTeamUseCase.kt | 10 ++-- .../kalium/logic/feature/user/UserScope.kt | 4 +- ...CanMigrateFromPersonalToTeamUseCaseTest.kt | 49 +++++++++++++------ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt index 75811b8e482..451a14b6779 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/UserSessionScope.kt @@ -1890,6 +1890,7 @@ class UserSessionScope internal constructor( certificateRevocationListRepository, incrementalSyncRepository, sessionManager, + selfTeamId, checkRevocationList, syncFeatureConfigsUseCase, userScopedLogger diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt index b698bea111f..be386f4e509 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCase.kt @@ -21,7 +21,8 @@ package com.wire.kalium.logic.feature.personaltoteamaccount import com.wire.kalium.logic.configuration.server.ServerConfigRepository -import com.wire.kalium.logic.data.user.UserRepository +import com.wire.kalium.logic.data.id.SelfTeamIdProvider +import com.wire.kalium.logic.functional.fold import com.wire.kalium.network.session.SessionManager /** @@ -35,11 +36,14 @@ interface CanMigrateFromPersonalToTeamUseCase { internal class CanMigrateFromPersonalToTeamUseCaseImpl( val sessionManager: SessionManager, val serverConfigRepository: ServerConfigRepository, - val userRepository: UserRepository + val selfTeamIdProvider: SelfTeamIdProvider ) : CanMigrateFromPersonalToTeamUseCase { override suspend fun invoke(): Boolean { val commonApiVersion = sessionManager.serverConfig().metaData.commonApiVersion.version val minApi = serverConfigRepository.minimumApiVersionForPersonalToTeamAccountMigration - return userRepository.getSelfUser()?.teamId == null && commonApiVersion >= minApi + return selfTeamIdProvider().fold( + { false }, + { teamId -> teamId == null && commonApiVersion >= minApi } + ) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt index e7b03086a33..9bae507ae54 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/UserScope.kt @@ -31,6 +31,7 @@ import com.wire.kalium.logic.data.e2ei.CertificateRevocationListRepository import com.wire.kalium.logic.data.e2ei.E2EIRepository import com.wire.kalium.logic.data.e2ei.RevocationListChecker import com.wire.kalium.logic.data.id.CurrentClientIdProvider +import com.wire.kalium.logic.data.id.SelfTeamIdProvider import com.wire.kalium.logic.data.properties.UserPropertyRepository import com.wire.kalium.logic.data.session.SessionRepository import com.wire.kalium.logic.data.sync.IncrementalSyncRepository @@ -113,6 +114,7 @@ class UserScope internal constructor( private val certificateRevocationListRepository: CertificateRevocationListRepository, private val incrementalSyncRepository: IncrementalSyncRepository, private val sessionManager: SessionManager, + private val selfTeamIdProvider: SelfTeamIdProvider, private val checkRevocationList: RevocationListChecker, private val syncFeatureConfigs: SyncFeatureConfigsUseCase, private val userScopedLogger: KaliumLogger @@ -232,7 +234,7 @@ class UserScope internal constructor( CanMigrateFromPersonalToTeamUseCaseImpl( sessionManager = sessionManager, serverConfigRepository = serverConfigRepository, - userRepository = userRepository + selfTeamIdProvider = selfTeamIdProvider ) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt index 72f45a154de..9a806ec5816 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/personaltoteamaccount/CanMigrateFromPersonalToTeamUseCaseTest.kt @@ -17,10 +17,11 @@ */ package com.wire.kalium.logic.feature.personaltoteamaccount +import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.configuration.server.ServerConfigRepository +import com.wire.kalium.logic.data.id.SelfTeamIdProvider import com.wire.kalium.logic.data.id.TeamId -import com.wire.kalium.logic.data.user.UserRepository -import com.wire.kalium.logic.framework.TestUser +import com.wire.kalium.logic.functional.Either import com.wire.kalium.network.api.unbound.configuration.ApiVersionDTO import com.wire.kalium.network.session.SessionManager import com.wire.kalium.network.utils.TestRequestHandler.Companion.TEST_BACKEND_CONFIG @@ -28,7 +29,6 @@ import io.mockative.Mock import io.mockative.coEvery import io.mockative.every import io.mockative.mock -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import kotlin.test.Test import kotlin.test.assertFalse @@ -39,9 +39,9 @@ class CanMigrateFromPersonalToTeamUseCaseTest { @Test fun givenAPIVersionBelowMinimumAndUserNotInATeam_whenInvoking_thenReturnsFalse() = runTest { // Given - val (arrangement, useCase) = Arrangement() + val (_, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() - .withTeamId(null) + .withTeamId(Either.Right(null)) .withServerConfig(6) .arrange() @@ -54,12 +54,12 @@ class CanMigrateFromPersonalToTeamUseCaseTest { @Test fun givenAPIVersionEqualToMinimumAndUserNotInATeam_whenInvoking_thenReturnsTrue() = - runBlocking { + runTest { // Given - val (arrangement, useCase) = Arrangement() + val (_, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() .withServerConfig(7) - .withTeamId(null) + .withTeamId(Either.Right(null)) .arrange() // When @@ -70,11 +70,28 @@ class CanMigrateFromPersonalToTeamUseCaseTest { } @Test - fun givenAPIVersionAboveMinimumAndUserInATeam_whenInvoking_thenReturnsFalse() = runBlocking { + fun givenAPIVersionAboveMinimumAndUserInATeam_whenInvoking_thenReturnsFalse() = runTest { // Given - val (arrangement, useCase) = Arrangement() + val (_, useCase) = Arrangement() .withRepositoryReturningMinimumApiVersion() - .withTeamId(TeamId("teamId")) + .withTeamId(Either.Right(TeamId("teamId"))) + .withServerConfig(9) + .arrange() + + // When + val result = useCase.invoke() + + // Then + assertFalse(result) + } + + + @Test + fun givenSelfTeamIdProviderFailure_whenInvoking_thenReturnsFalse() = runTest { + // Given + val (_, useCase) = Arrangement() + .withRepositoryReturningMinimumApiVersion() + .withTeamId(Either.Left(CoreFailure.MissingClientRegistration)) .withServerConfig(9) .arrange() @@ -94,12 +111,12 @@ class CanMigrateFromPersonalToTeamUseCaseTest { val sessionManager = mock(SessionManager::class) @Mock - val userRepository = mock(UserRepository::class) + val selfTeamIdProvider = mock(SelfTeamIdProvider::class) - suspend fun withTeamId(result: TeamId?) = apply { + suspend fun withTeamId(result: Either) = apply { coEvery { - userRepository.getSelfUser() - }.returns(TestUser.SELF.copy(teamId = result)) + selfTeamIdProvider() + }.returns(result) } fun withRepositoryReturningMinimumApiVersion() = apply { @@ -122,7 +139,7 @@ class CanMigrateFromPersonalToTeamUseCaseTest { fun arrange() = this to CanMigrateFromPersonalToTeamUseCaseImpl( sessionManager = sessionManager, serverConfigRepository = serverConfigRepository, - userRepository = userRepository + selfTeamIdProvider = selfTeamIdProvider ) }