diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCase.kt index d5c356601e9..5f2ca1c35bf 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCase.kt @@ -20,8 +20,10 @@ package com.wire.kalium.logic.feature.user.migration import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.data.id.TeamId import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.NetworkFailure import com.wire.kalium.logic.data.user.UserRepository import com.wire.kalium.logic.functional.fold +import com.wire.kalium.network.exceptions.KaliumException /** * Use case to migrate user personal account to team account. @@ -33,7 +35,20 @@ interface MigrateFromPersonalToTeamUseCase { sealed class MigrateFromPersonalToTeamResult { data object Success : MigrateFromPersonalToTeamResult() - data class Error(val failure: CoreFailure) : MigrateFromPersonalToTeamResult() + data class Error(val failure: MigrateFromPersonalToTeamFailure) : + MigrateFromPersonalToTeamResult() +} + +sealed class MigrateFromPersonalToTeamFailure { + + data class UnknownError(val coreFailure: CoreFailure) : MigrateFromPersonalToTeamFailure() + class UserAlreadyInTeam : MigrateFromPersonalToTeamFailure() { + companion object { + const val ERROR_LABEL = "user-already-in-a-team" + } + } + + data object NoNetwork : MigrateFromPersonalToTeamFailure() } internal class MigrateFromPersonalToTeamUseCaseImpl internal constructor( @@ -44,14 +59,43 @@ internal class MigrateFromPersonalToTeamUseCaseImpl internal constructor( override suspend operator fun invoke( teamName: String, ): MigrateFromPersonalToTeamResult { - return userRepository.migrateUserToTeam(teamName) - .fold( - { error -> return MigrateFromPersonalToTeamResult.Error(error) }, - { user -> - userRepository.updateTeamId(selfUserId, TeamId(user.teamId)) - invalidateTeamId() - MigrateFromPersonalToTeamResult.Success + return userRepository.migrateUserToTeam(teamName).fold({ error -> + return when (error) { + is NetworkFailure.ServerMiscommunication -> { + if (error.kaliumException is KaliumException.InvalidRequestError) { + val response = error.kaliumException.errorResponse + if (response.label == MigrateFromPersonalToTeamFailure.UserAlreadyInTeam.ERROR_LABEL) { + MigrateFromPersonalToTeamResult.Error( + MigrateFromPersonalToTeamFailure.UserAlreadyInTeam() + ) + } else { + MigrateFromPersonalToTeamResult.Error( + MigrateFromPersonalToTeamFailure.UnknownError(error) + ) + } + } else { + MigrateFromPersonalToTeamResult.Error( + MigrateFromPersonalToTeamFailure.UnknownError(error) + ) + } } - ) + + is NetworkFailure.NoNetworkConnection -> { + MigrateFromPersonalToTeamResult.Error(MigrateFromPersonalToTeamFailure.NoNetwork) + } + + else -> { + MigrateFromPersonalToTeamResult.Error( + MigrateFromPersonalToTeamFailure.UnknownError( + error + ) + ) + } + } + }, { user -> + userRepository.updateTeamId(selfUserId, TeamId(user.teamId)) + invalidateTeamId() + MigrateFromPersonalToTeamResult.Success + }) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCaseTest.kt index d9efa29641f..23f8ce4db9f 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/migration/MigrateFromPersonalToTeamUseCaseTest.kt @@ -59,45 +59,45 @@ class MigrateFromPersonalToTeamUseCaseTest { } @Test - fun givenRepositoryFailsWithNoNetworkConnection_whenMigratingUserToTeam_thenShouldPropagateFailure() = + fun givenRepositoryFailsWithNoNetworkConnection_whenMigratingUserToTeam_thenShouldPropagateNoNetworkFailure() = runTest { - val coreFailure = NetworkFailure.NoNetworkConnection(null) - val (_, useCase) = Arrangement().withMigrationReturning(Either.Left(coreFailure)) + val (_, useCase) = Arrangement() + .withMigrationNoNetworkFailure() .arrange() val result = useCase(teamName = "teamName") assertIs(result) - assertIs(result.failure) + assertIs(result.failure) } @Test - fun givenRepositoryFailsWithUserAlreadyInTeam_whenMigratingUserToTeam_thenShouldPropagateFailure() = + fun givenRepositoryFailsWithUserAlreadyInTeam_whenMigratingUserToTeam_thenShouldPropagateUserAlreadyInTeamFailure() = runTest { - val (_, useCase) = Arrangement().withUserAlreadyInTeamRepository().arrange() + val (_, useCase) = Arrangement() + .withUserAlreadyInTeamFailure() + .arrange() val result = useCase(teamName = "teamName") assertIs(result) - assertIs(result.failure) - val serverMiscommunication = result.failure as NetworkFailure.ServerMiscommunication - val invalidRequestError = - serverMiscommunication.kaliumException as KaliumException.InvalidRequestError - val errorLabel = invalidRequestError.errorResponse.label - - assertEquals("user-already-in-a-team", errorLabel) + assertIs(result.failure) } @Test - fun givenRepositoryFailsWithNotFound_whenMigratingUserToTeam_thenShouldPropagateFailure() = + fun givenRepositoryFailsWithUnknownError_whenMigratingUserToTeam_thenShouldPropagateUnknownFailure() = runTest { - val (_, useCase) = Arrangement().withMigrationFailure().arrange() + val (_, useCase) = Arrangement() + .withMigrationUserNotFoundFailure() + .arrange() val result = useCase(teamName = "teamName") assertIs(result) - assertIs(result.failure) - val serverMiscommunication = result.failure as NetworkFailure.ServerMiscommunication + assertIs(result.failure) + val coreFailure = + (result.failure as MigrateFromPersonalToTeamFailure.UnknownError).coreFailure + val serverMiscommunication = coreFailure as NetworkFailure.ServerMiscommunication val invalidRequestError = serverMiscommunication.kaliumException as KaliumException.InvalidRequestError val errorLabel = invalidRequestError.errorResponse.label @@ -120,53 +120,51 @@ class MigrateFromPersonalToTeamUseCaseTest { ) } - suspend fun withUserAlreadyInTeamRepository() = apply { - coEvery { userRepository.migrateUserToTeam(any()) }.returns( - Either.Left( - NetworkFailure.ServerMiscommunication( - KaliumException.InvalidRequestError( - ErrorResponse( - HttpStatusCode.Forbidden.value, - message = "Switching teams is not allowed", - label = "user-already-in-a-team", - ) + suspend fun withUserAlreadyInTeamFailure() = withMigrationReturning( + Either.Left( + NetworkFailure.ServerMiscommunication( + KaliumException.InvalidRequestError( + ErrorResponse( + HttpStatusCode.Forbidden.value, + message = "Switching teams is not allowed", + label = "user-already-in-a-team", ) ) ) ) - } + ) - suspend fun withMigrationFailure() = apply { - coEvery { userRepository.migrateUserToTeam(any()) }.returns( - Either.Left( - NetworkFailure.ServerMiscommunication( - KaliumException.InvalidRequestError( - ErrorResponse( - HttpStatusCode.NotFound.value, - message = "User not found", - label = "not-found", - ) + + suspend fun withMigrationUserNotFoundFailure() = withMigrationReturning( + Either.Left( + NetworkFailure.ServerMiscommunication( + KaliumException.InvalidRequestError( + ErrorResponse( + HttpStatusCode.NotFound.value, + message = "User not found", + label = "not-found", ) ) ) ) - } + ) - suspend fun withMigrationReturning(result: Either) = - apply { - coEvery { userRepository.migrateUserToTeam(any()) }.returns(result) - } + suspend fun withMigrationNoNetworkFailure() = withMigrationReturning( + Either.Left(NetworkFailure.NoNetworkConnection(null)) + ) + + suspend fun withMigrationReturning(result: Either) = apply { + coEvery { userRepository.migrateUserToTeam(any()) }.returns(result) + } suspend fun withUpdateTeamIdReturning(result: Either) = apply { coEvery { userRepository.updateTeamId(any(), any()) }.returns(result) } - fun arrange() = this to MigrateFromPersonalToTeamUseCaseImpl( - selfUserId = TestUser.SELF.id, + fun arrange() = this to MigrateFromPersonalToTeamUseCaseImpl(selfUserId = TestUser.SELF.id, userRepository = userRepository, invalidateTeamId = { isCachedTeamIdInvalidated = true - } - ) + }) } }