From 1f0190884282e494ff9d86e6feee541f304b8631 Mon Sep 17 00:00:00 2001 From: Jacob Persson <7156+typfel@users.noreply.github.com> Date: Mon, 26 Jun 2023 16:51:03 +0200 Subject: [PATCH] feat(mls-migration): force migration when migration deadline arrives #10 (#1831) * feat: end migration regardless when migration deadline arrives * refactor: generalise methods for fetching conversations ids * refactor: better naming --- .../data/conversation/ConversationMapper.kt | 2 +- .../conversation/ConversationRepository.kt | 27 ++++---- .../conversation/SyncConversationsUseCase.kt | 4 +- .../mlsmigration/MLSMigrationWorker.kt | 4 ++ .../logic/feature/mlsmigration/MLSMigrator.kt | 17 ++++- .../MLSMigrationRepositoryTest.kt | 5 ++ .../EndCallOnConversationChangeUseCaseTest.kt | 4 +- ...nversationVerificationStatusUseCaseTest.kt | 2 +- .../SyncConversationsUseCaseTest.kt | 4 +- .../feature/mlsmigration/MLSMigratorTest.kt | 6 +- .../user/UploadUserAvatarUseCaseTest.kt | 4 +- .../network/api/v0/authenticated/SelfApiV0.kt | 2 +- .../wire/kalium/persistence/Conversations.sq | 9 +-- .../com/wire/kalium/persistence/Messages.sq | 2 +- .../dao/conversation/ConversationDAO.kt | 11 +-- .../dao/conversation/ConversationDAOImpl.kt | 16 ++--- .../dao/conversation/ConversationEntity.kt | 1 - .../persistence/dao/ConversationDAOTest.kt | 68 +++++++++++-------- .../kalium/persistence/dao/MemberDAOTest.kt | 2 +- 19 files changed, 113 insertions(+), 77 deletions(-) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationMapper.kt index fc40b1283c2..2ab311c93b5 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationMapper.kt @@ -465,7 +465,7 @@ private fun ConversationEntity.AccessRole.toDAO(): Conversation.AccessRole = whe ConversationEntity.AccessRole.EXTERNAL -> Conversation.AccessRole.EXTERNAL } -private fun Conversation.Type.toDAO(): ConversationEntity.Type = when (this) { +internal fun Conversation.Type.toDAO(): ConversationEntity.Type = when (this) { Conversation.Type.SELF -> ConversationEntity.Type.SELF Conversation.Type.ONE_ON_ONE -> ConversationEntity.Type.ONE_ON_ONE Conversation.Type.GROUP -> ConversationEntity.Type.GROUP diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepository.kt index 2c5b21c3679..9576507ac0b 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepository.kt @@ -114,8 +114,12 @@ interface ConversationRepository { suspend fun getConversationList(): Either>> suspend fun observeConversationList(): Flow> - suspend fun getProteusTeamConversations(teamId: TeamId): Either> - suspend fun getProteusTeamConversationsReadyForFinalisation(teamId: TeamId): Either> + suspend fun getConversationIds( + type: Conversation.Type, + protocol: Conversation.Protocol, + teamId: TeamId? = null + ): Either> + suspend fun getTeamConversationIdsReadyToCompleteMigration(teamId: TeamId): Either> suspend fun observeConversationListDetails(): Flow> suspend fun observeConversationDetailsById(conversationID: ConversationId): Flow> suspend fun fetchConversation(conversationID: ConversationId): Either @@ -129,7 +133,6 @@ interface ConversationRepository { suspend fun getRecipientById(conversationId: ConversationId, userIDList: List): Either> suspend fun getConversationRecipientsForCalling(conversationId: ConversationId): Either> suspend fun getConversationProtocolInfo(conversationId: ConversationId): Either - suspend fun getGroupConversationIdsByProtocol(protocol: Conversation.Protocol): Either> suspend fun observeConversationMembers(conversationID: ConversationId): Flow> /** @@ -398,15 +401,18 @@ internal class ConversationDataSource internal constructor( return conversationDAO.getAllConversations().map { it.map(conversationMapper::fromDaoModel) } } - override suspend fun getProteusTeamConversations(teamId: TeamId): Either> = + override suspend fun getConversationIds( + type: Conversation.Type, + protocol: Conversation.Protocol, + teamId: TeamId? + ): Either> = wrapStorageRequest { - conversationDAO.getAllProteusTeamConversations(teamId.value) + conversationDAO.getConversationIds(type.toDAO(), protocol.toDao(), teamId?.value) .map { it.toModel() } } - - override suspend fun getProteusTeamConversationsReadyForFinalisation(teamId: TeamId): Either> = + override suspend fun getTeamConversationIdsReadyToCompleteMigration(teamId: TeamId): Either> = wrapStorageRequest { - conversationDAO.getAllProteusTeamConversationsReadyToBeFinalised(teamId.value) + conversationDAO.getTeamConversationIdsReadyToCompleteMigration(teamId.value) .map { it.toModel() } } @@ -508,11 +514,6 @@ internal class ConversationDataSource internal constructor( } } - override suspend fun getGroupConversationIdsByProtocol(protocol: Conversation.Protocol): Either> = - wrapStorageRequest { - conversationDAO.getGroupConversationIdsByProtocol(protocol.toDao()).map(QualifiedIDEntity::toModel) - } - override suspend fun observeConversationMembers(conversationID: ConversationId): Flow> = memberDAO.observeConversationMembers(conversationID.toDao()).map { members -> members.map(memberMapper::fromDaoModel) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCase.kt index 511cc5dc065..bf3d4cfca30 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCase.kt @@ -38,7 +38,7 @@ internal class SyncConversationsUseCaseImpl( private val systemMessageInserter: SystemMessageInserter ) : SyncConversationsUseCase { override suspend operator fun invoke(): Either = - conversationRepository.getGroupConversationIdsByProtocol(Conversation.Protocol.PROTEUS) + conversationRepository.getConversationIds(Conversation.Type.GROUP, Conversation.Protocol.PROTEUS) .flatMap { proteusConversationIds -> conversationRepository.fetchConversations() .flatMap { @@ -49,7 +49,7 @@ internal class SyncConversationsUseCaseImpl( private suspend fun reportConversationsWithPotentialHistoryLoss( proteusConversationIds: List ): Either = - conversationRepository.getGroupConversationIdsByProtocol(Conversation.Protocol.MLS) + conversationRepository.getConversationIds(Conversation.Type.GROUP, Conversation.Protocol.MLS) .flatMap { mlsConversationIds -> val conversationsWithUpgradedProtocol = mlsConversationIds.intersect(proteusConversationIds) for (conversationId in conversationsWithUpgradedProtocol) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrationWorker.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrationWorker.kt index 7e82eedf842..ef963629473 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrationWorker.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrationWorker.kt @@ -47,8 +47,12 @@ class MLSMigrationWorkerImpl( kaliumLogger.i("Running proteus to MLS migration") updateSupportedProtocols().flatMap { mlsMigrator.migrateProteusConversations().flatMap { + if (configuration.hasMigrationEnded()) { + mlsMigrator.finaliseAllProteusConversations() + } else { mlsMigrator.finaliseProteusConversations() } + } } } else { kaliumLogger.i("MLS migration is not enabled") diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrator.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrator.kt index 317bb05913c..6db698e4d90 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrator.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigrator.kt @@ -38,6 +38,7 @@ import com.wire.kalium.logic.kaliumLogger interface MLSMigrator { suspend fun migrateProteusConversations(): Either suspend fun finaliseProteusConversations(): Either + suspend fun finaliseAllProteusConversations(): Either } internal class MLSMigratorImpl( private val selfUserId: UserId, @@ -52,7 +53,7 @@ internal class MLSMigratorImpl( selfTeamIdProvider().flatMap { it?.let { Either.Right(it) } ?: Either.Left(StorageFailure.DataNotFound) }.flatMap { teamId -> - conversationRepository.getProteusTeamConversations(teamId) + conversationRepository.getConversationIds(Conversation.Type.GROUP, Protocol.PROTEUS, teamId) .flatMap { it.foldToEitherWhileRight(Unit) { conversationId, _ -> migrate(conversationId) @@ -60,13 +61,25 @@ internal class MLSMigratorImpl( } } + override suspend fun finaliseAllProteusConversations(): Either = + selfTeamIdProvider().flatMap { + it?.let { Either.Right(it) } ?: Either.Left(StorageFailure.DataNotFound) + }.flatMap { teamId -> + conversationRepository.getConversationIds(Conversation.Type.GROUP, Protocol.MIXED, teamId) + .flatMap { + it.foldToEitherWhileRight(Unit) { conversationId, _ -> + finalise(conversationId) + } + } + } + override suspend fun finaliseProteusConversations(): Either = selfTeamIdProvider().flatMap { it?.let { Either.Right(it) } ?: Either.Left(StorageFailure.DataNotFound) }.flatMap { teamId -> userRepository.fetchAllOtherUsers() .flatMap { - conversationRepository.getProteusTeamConversationsReadyForFinalisation(teamId) + conversationRepository.getTeamConversationIdsReadyToCompleteMigration(teamId) .flatMap { it.foldToEitherWhileRight(Unit) { conversationId, _ -> finalise(conversationId) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/mlsmigration/MLSMigrationRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/mlsmigration/MLSMigrationRepositoryTest.kt index 8ba0932d2c4..c3f493cba6a 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/mlsmigration/MLSMigrationRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/mlsmigration/MLSMigrationRepositoryTest.kt @@ -25,6 +25,7 @@ import com.wire.kalium.logic.util.shouldSucceed import com.wire.kalium.network.api.base.authenticated.conversation.ConvProtocol import com.wire.kalium.network.api.base.authenticated.featureConfigs.AppLockConfigDTO import com.wire.kalium.network.api.base.authenticated.featureConfigs.ClassifiedDomainsConfigDTO +import com.wire.kalium.network.api.base.authenticated.featureConfigs.E2EIConfigDTO import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureConfigApi import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureConfigData import com.wire.kalium.network.api.base.authenticated.featureConfigs.FeatureConfigResponse @@ -167,6 +168,10 @@ class MLSMigrationRepositoryTest { emptyList(), 1 ), FeatureFlagStatusDTO.ENABLED), + FeatureConfigData.E2EI( + E2EIConfigDTO(null), + FeatureFlagStatusDTO.ENABLED + ), FeatureConfigData.MLSMigration( MLSMigrationConfigDTO(Instant.DISTANT_FUTURE, Instant.DISTANT_FUTURE), FeatureFlagStatusDTO.ENABLED diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt index b9dd3f418be..73cfedcc12e 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/call/usecase/EndCallOnConversationChangeUseCaseTest.kt @@ -11,6 +11,7 @@ import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.TeamId import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.OtherUser +import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.data.user.UserAssetId import com.wire.kalium.logic.data.user.UserAvailabilityStatus import com.wire.kalium.logic.data.user.UserId @@ -166,7 +167,8 @@ class EndCallOnConversationChangeUseCaseTest { userType = UserType.INTERNAL, botService = null, deleted = true, - defederated = false + defederated = false, + supportedProtocols = setOf(SupportedProtocol.PROTEUS) ) private val groupConversationDetail = ConversationDetails.Group( diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/GetConversationVerificationStatusUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/GetConversationVerificationStatusUseCaseTest.kt index 0884aa79500..2ea64bed982 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/GetConversationVerificationStatusUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/GetConversationVerificationStatusUseCaseTest.kt @@ -130,7 +130,7 @@ class GetConversationVerificationStatusUseCaseTest { val MLS_CONVERSATION1 = TestConversation.GROUP( Conversation.ProtocolInfo.MLS( GROUP_ID1, - Conversation.ProtocolInfo.MLS.GroupState.PENDING_JOIN, + Conversation.ProtocolInfo.MLSCapable.GroupState.PENDING_JOIN, epoch = 1UL, keyingMaterialLastUpdate = DateTimeUtil.currentInstant(), cipherSuite = Conversation.CipherSuite.MLS_128_DHKEMX25519_AES128GCM_SHA256_Ed25519 diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCaseTest.kt index 27ae39c2743..04944ae120a 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/SyncConversationsUseCaseTest.kt @@ -105,8 +105,8 @@ class SyncConversationsUseCaseTest { protocol: Conversation.Protocol? = null ) = apply { given(conversationRepository) - .suspendFunction(conversationRepository::getGroupConversationIdsByProtocol) - .whenInvokedWith(protocol?.let { eq(it) } ?: any()) + .suspendFunction(conversationRepository::getConversationIds) + .whenInvokedWith(eq(Conversation.Type.GROUP), protocol?.let { eq(it) } ?: any(), eq(null)) .thenReturn(Either.Right(conversationIds)) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt index 4fa75594216..6ede1daf13c 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/mlsmigration/MLSMigratorTest.kt @@ -174,14 +174,14 @@ class MLSMigratorTest { fun withGetProteusTeamConversationsReturning(conversationsIds: List) = apply { given(conversationRepository) - .suspendFunction(conversationRepository::getProteusTeamConversations) - .whenInvokedWith(anything()) + .suspendFunction(conversationRepository::getConversationIds) + .whenInvokedWith(eq(Conversation.Type.GROUP), eq(Conversation.Protocol.PROTEUS), anything()) .thenReturn(Either.Right(conversationsIds)) } fun withGetProteusTeamConversationsReadyForFinalisationReturning(conversationsIds: List) = apply { given(conversationRepository) - .suspendFunction(conversationRepository::getProteusTeamConversationsReadyForFinalisation) + .suspendFunction(conversationRepository::getTeamConversationIdsReadyToCompleteMigration) .whenInvokedWith(anything()) .thenReturn(Either.Right(conversationsIds)) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UploadUserAvatarUseCaseTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UploadUserAvatarUseCaseTest.kt index dfafc2ad21c..ddbb9b65fe6 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UploadUserAvatarUseCaseTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/user/UploadUserAvatarUseCaseTest.kt @@ -24,6 +24,7 @@ import com.wire.kalium.logic.data.asset.KaliumFileSystem import com.wire.kalium.logic.data.asset.UploadedAssetId import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.SelfUser +import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.data.user.UserAssetId import com.wire.kalium.logic.data.user.UserAvailabilityStatus import com.wire.kalium.logic.data.user.UserId @@ -130,7 +131,8 @@ class UploadUserAvatarUseCaseTest { UserAssetId("value1", "domain"), UserAssetId("value2", "domain"), UserAvailabilityStatus.NONE, - null + null, + setOf(SupportedProtocol.PROTEUS) ) fun withStoredData(data: ByteArray, dataNamePath: Path): Arrangement { diff --git a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/SelfApiV0.kt b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/SelfApiV0.kt index 51299e91be1..327150778dc 100644 --- a/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/SelfApiV0.kt +++ b/network/src/commonMain/kotlin/com/wire/kalium/network/api/v0/authenticated/SelfApiV0.kt @@ -90,7 +90,7 @@ internal open class SelfApiV0 internal constructor( override suspend fun updateSupportedProtocols(protocols: List): NetworkResponse = getApiNotSupportError(::updateSupportedProtocols.name, 4) - private companion object { + companion object { const val PATH_SELF = "self" const val PATH_HANDLE = "handle" const val PATH_ACCESS = "access" diff --git a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq index 0a6b820691a..ee17caa00dd 100644 --- a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq +++ b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Conversations.sq @@ -240,16 +240,13 @@ ORDER BY lastModifiedDate DESC, name COLLATE NOCASE ASC; selectAllConversations: SELECT * FROM ConversationDetails WHERE type IS NOT 'CONNECTION_PENDING' ORDER BY last_modified_date DESC, name ASC; -selectAllTeamProteusConversations: -SELECT qualified_id FROM Conversation WHERE type IS 'GROUP' AND protocol IS 'PROTEUS' AND team_id = ?; - selectAllTeamProteusConversationsReadyForMigration: SELECT qualified_id, (SELECT count(*) FROM Member WHERE conversation = qualified_id) AS memberCount, (SELECT count(*) FROM Member LEFT JOIN User ON User.qualified_id = Member.user WHERE Member.conversation = Conversation.qualified_id AND (User.supported_protocols = 'MLS' OR User.supported_protocols = 'MLS,PROTEUS' OR User.supported_protocols = 'PROTEUS,MLS')) AS mlsCapableMemberCount FROM Conversation -WHERE type IS 'GROUP' AND protocol IS 'PROTEUS' AND team_id = ? AND memberCount = mlsCapableMemberCount; +WHERE type IS 'GROUP' AND protocol IS 'MIXED' AND team_id = ? AND memberCount = mlsCapableMemberCount; selectByQualifiedId: SELECT * FROM ConversationDetails WHERE qualifiedId = ?; @@ -273,8 +270,8 @@ SELECT * FROM ConversationDetails WHERE mls_group_state = ? AND (protocol IS "ML getConversationIdByGroupId: SELECT qualified_id FROM Conversation WHERE mls_group_id = ?; -selectGroupConversationIdsByProtocol: -SELECT qualified_id FROM Conversation WHERE protocol = ? AND type IS 'GROUP'; +selectConversationIds: +SELECT qualified_id FROM Conversation WHERE protocol = :protocol AND type = :type AND (:teamId IS NULL OR team_id = :teamId); updateConversationMutingStatus: UPDATE Conversation diff --git a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq index a0d8b69875e..8bd4fa39f45 100644 --- a/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq +++ b/persistence/src/commonMain/db_user/com/wire/kalium/persistence/Messages.sq @@ -1,4 +1,4 @@ -import com.wire.kalium.persistence.dao.ConversationEntity; +import com.wire.kalium.persistence.dao.conversation.ConversationEntity; import com.wire.kalium.persistence.dao.QualifiedIDEntity; import com.wire.kalium.persistence.dao.message.MessageEntity.ContentType; import com.wire.kalium.persistence.dao.message.MessageEntity.FederationType; diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAO.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAO.kt index 43fec88e0f1..6796c21c3b5 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAO.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAO.kt @@ -41,8 +41,12 @@ interface ConversationDAO { suspend fun updateAllConversationsNotificationDate() suspend fun getAllConversations(): Flow> suspend fun getAllConversationDetails(): Flow> - suspend fun getAllProteusTeamConversations(teamId: String): List - suspend fun getAllProteusTeamConversationsReadyToBeFinalised(teamId: String): List + suspend fun getConversationIds( + type: ConversationEntity.Type, + protocol: ConversationEntity.Protocol, + teamId: String? = null + ): List + suspend fun getTeamConversationIdsReadyToCompleteMigration(teamId: String): List suspend fun observeGetConversationByQualifiedID(qualifiedID: QualifiedIDEntity): Flow suspend fun observeGetConversationBaseInfoByQualifiedID(qualifiedID: QualifiedIDEntity): Flow suspend fun getConversationBaseInfoByQualifiedID(qualifiedID: QualifiedIDEntity): ConversationEntity? @@ -51,7 +55,6 @@ interface ConversationDAO { suspend fun getConversationProtocolInfo(qualifiedID: QualifiedIDEntity): ConversationEntity.ProtocolInfo? suspend fun getConversationByGroupID(groupID: String): Flow suspend fun getConversationIdByGroupID(groupID: String): QualifiedIDEntity? - suspend fun getGroupConversationIdsByProtocol(protocol: ConversationEntity.Protocol): List suspend fun getConversationsByGroupState(groupState: ConversationEntity.GroupState): List suspend fun deleteConversationByQualifiedID(qualifiedID: QualifiedIDEntity) @@ -75,7 +78,7 @@ interface ConversationDAO { suspend fun whoDeletedMeInConversation(conversationId: QualifiedIDEntity, selfUserIdString: String): UserIDEntity? suspend fun updateConversationName(conversationId: QualifiedIDEntity, conversationName: String, timestamp: String) suspend fun updateConversationType(conversationID: QualifiedIDEntity, type: ConversationEntity.Type) - suspend fun updateConversationProtocol(conversationId: QualifiedIDEntity, protocol: com.wire.kalium.persistence.dao.ConversationEntity.Protocol): Boolean + suspend fun updateConversationProtocol(conversationId: QualifiedIDEntity, protocol: ConversationEntity.Protocol): Boolean suspend fun revokeOneOnOneConversationsWithDeletedUser(userId: UserIDEntity) suspend fun getConversationIdsByUserId(userId: UserIDEntity): List suspend fun updateConversationReceiptMode(conversationID: QualifiedIDEntity, receiptMode: ConversationEntity.ReceiptMode) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAOImpl.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAOImpl.kt index 0f05319f76a..1f58ef77702 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAOImpl.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationDAOImpl.kt @@ -148,14 +148,17 @@ internal class ConversationDAOImpl internal constructor( .map { list -> list.map { it.let { conversationMapper.toModel(it) } } } } - override suspend fun getAllProteusTeamConversations(teamId: String): List { + override suspend fun getConversationIds( + type: ConversationEntity.Type, + protocol: ConversationEntity.Protocol, + teamId: String? + ): List { return withContext(coroutineContext) { - conversationQueries.selectAllTeamProteusConversations(teamId) - .executeAsList() + conversationQueries.selectConversationIds(protocol, type, teamId).executeAsList() } } - override suspend fun getAllProteusTeamConversationsReadyToBeFinalised(teamId: String): List { + override suspend fun getTeamConversationIdsReadyToCompleteMigration(teamId: String): List { return withContext(coroutineContext) { conversationQueries.selectAllTeamProteusConversationsReadyForMigration(teamId) .executeAsList() @@ -216,11 +219,6 @@ internal class ConversationDAOImpl internal constructor( conversationQueries.getConversationIdByGroupId(groupID).executeAsOneOrNull() } - override suspend fun getGroupConversationIdsByProtocol(protocol: ConversationEntity.Protocol): List = - withContext(coroutineContext) { - conversationQueries.selectGroupConversationIdsByProtocol(protocol).executeAsList() - } - override suspend fun getConversationsByGroupState(groupState: ConversationEntity.GroupState): List = withContext(coroutineContext) { conversationQueries.selectByGroupState(groupState) diff --git a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationEntity.kt b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationEntity.kt index 199f100f44b..a601fd3887a 100644 --- a/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationEntity.kt +++ b/persistence/src/commonMain/kotlin/com/wire/kalium/persistence/dao/conversation/ConversationEntity.kt @@ -17,7 +17,6 @@ */ package com.wire.kalium.persistence.dao.conversation -import com.wire.kalium.persistence.dao.ConversationEntity import com.wire.kalium.persistence.dao.QualifiedIDEntity import com.wire.kalium.persistence.dao.UserIDEntity import kotlinx.datetime.Instant diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt index b67c51b7d44..48a8340e323 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/ConversationDAOTest.kt @@ -160,23 +160,48 @@ class ConversationDAOTest : BaseDatabaseTest() { } @Test - fun givenExistingGroupConversations_whenGetGroupConversationIdsByProtocol_ThenConversationIdsWithGivenProtocolIsReturned() = runTest { + fun givenExistingConversations_WhenGetConversationIds_ThenConversationsWithGivenProtocolIsReturned() = runTest { conversationDAO.insertConversation(conversationEntity4) conversationDAO.insertConversation(conversationEntity5) insertTeamUserAndMember(team, user2, conversationEntity5.id) val result = - conversationDAO.getGroupConversationIdsByProtocol(ConversationEntity.Protocol.PROTEUS) + conversationDAO.getConversationIds(ConversationEntity.Type.GROUP, ConversationEntity.Protocol.PROTEUS) assertEquals(listOf(conversationEntity5.id), result) } @Test - fun givenExistingSelfAndOneToOneConversations_whenGetGroupConversationIdsByProtocol_ThenAnEmptyListIsReturned() = runTest { + fun givenExistingConversations_WhenGetConversationIds_ThenConversationsWithGivenTeamIdIsReturned() = runTest { + conversationDAO.insertConversation(conversationEntity1) + conversationDAO.insertConversation(conversationEntity4) + conversationDAO.insertConversation(conversationEntity5) + insertTeamUserAndMember(team, user2, conversationEntity5.id) + + val result = + conversationDAO.getConversationIds(ConversationEntity.Type.GROUP, ConversationEntity.Protocol.PROTEUS, teamId) + + assertEquals(listOf(conversationEntity5.id), result) + } + + @Test + fun givenExistingConversations_WhenGetConversationIdsWithoutTeamId_ThenConversationsWithAllTeamIdsAreReturned() = runTest { + conversationDAO.insertConversation(conversationEntity4.copy( protocolInfo = ConversationEntity.ProtocolInfo.Proteus)) + conversationDAO.insertConversation(conversationEntity5.copy( teamId = null)) + insertTeamUserAndMember(team, user2, conversationEntity5.id) + + val result = + conversationDAO.getConversationIds(ConversationEntity.Type.GROUP, ConversationEntity.Protocol.PROTEUS) + + assertEquals(setOf(conversationEntity4.id, conversationEntity5.id), result.toSet()) + } + + @Test + fun givenExistingConversations_WhenGetConversationIds_ThenConversationsWithGivenTypeIsReturned() = runTest { conversationDAO.insertConversation(conversationEntity1.copy(type = ConversationEntity.Type.SELF)) conversationDAO.insertConversation(conversationEntity5.copy(type = ConversationEntity.Type.ONE_ON_ONE)) insertTeamUserAndMember(team, user2, conversationEntity5.id) val result = - conversationDAO.getGroupConversationIdsByProtocol(ConversationEntity.Protocol.PROTEUS) - assertEquals(emptyList(), result) + conversationDAO.getConversationIds(ConversationEntity.Type.SELF, ConversationEntity.Protocol.PROTEUS) + assertEquals(listOf(conversationEntity1.id), result) } @Test @@ -190,35 +215,22 @@ class ConversationDAOTest : BaseDatabaseTest() { } @Test - fun givenExistingConversations_ThenAllProteusTeamConversationsCanBeRetrieved() = runTest { - conversationDAO.insertConversation(conversationEntity1) - conversationDAO.insertConversation(conversationEntity4) - conversationDAO.insertConversation(conversationEntity5) - insertTeamUserAndMember(team, user2, conversationEntity5.id) - - val result = - conversationDAO.getAllProteusTeamConversations(teamId) - - assertEquals(listOf(conversationEntity5.id), result) - } - - @Test - fun givenAllMembersAreMlsCapable_WhenGetAllProteusTeamConversationsReadyToBeFinalised_ThenConversationIsReturned() = runTest { + fun givenAllMembersAreMlsCapable_WhenGetTeamConversationIdsReadyToBeFinalised_ThenConversationIsReturned() = runTest { val allProtocols = setOf(SupportedProtocolEntity.PROTEUS, SupportedProtocolEntity.MLS) val selfUser = user1.copy(id = selfUserId, supportedProtocols = allProtocols) userDAO.insertUser(selfUser) - conversationDAO.insertConversation(conversationEntity5) - insertTeamUserAndMember(team, user2.copy(supportedProtocols = allProtocols), conversationEntity5.id) - insertTeamUserAndMember(team, user3.copy(supportedProtocols = allProtocols), conversationEntity5.id) + conversationDAO.insertConversation(conversationEntity6) + insertTeamUserAndMember(team, user2.copy(supportedProtocols = allProtocols), conversationEntity6.id) + insertTeamUserAndMember(team, user3.copy(supportedProtocols = allProtocols), conversationEntity6.id) - val result = conversationDAO.getAllProteusTeamConversationsReadyToBeFinalised(teamId) + val result = conversationDAO.getTeamConversationIdsReadyToCompleteMigration(teamId) - assertEquals(listOf(conversationEntity5.id), result) + assertEquals(listOf(conversationEntity6.id), result) } @Test - fun givenOnlySomeMembersAreMlsCapable_WhenGetAllProteusTeamConversationsReadyToBeFinalised_ThenConversationIsNotReturned() = runTest { + fun givenOnlySomeMembersAreMlsCapable_WhenGetTeamConversationIdsReadyToBeFinalised_ThenConversationIsNotReturned() = runTest { val allProtocols = setOf(SupportedProtocolEntity.PROTEUS, SupportedProtocolEntity.MLS) val selfUser = user1.copy(id = selfUserId, supportedProtocols = allProtocols) userDAO.insertUser(selfUser) @@ -227,7 +239,7 @@ class ConversationDAOTest : BaseDatabaseTest() { insertTeamUserAndMember(team, user2.copy(supportedProtocols = allProtocols), conversationEntity5.id) insertTeamUserAndMember(team, user3.copy(supportedProtocols = setOf(SupportedProtocolEntity.PROTEUS)), conversationEntity5.id) - val result = conversationDAO.getAllProteusTeamConversationsReadyToBeFinalised(teamId) + val result = conversationDAO.getTeamConversationIdsReadyToCompleteMigration(teamId) assertTrue(result.isEmpty()) } @@ -1129,7 +1141,7 @@ class ConversationDAOTest : BaseDatabaseTest() { QualifiedIDEntity("4", "wire.com"), "conversation4", ConversationEntity.Type.GROUP, - null, + teamId, ConversationEntity.ProtocolInfo.MLS( "group4", ConversationEntity.GroupState.ESTABLISHED, @@ -1171,7 +1183,7 @@ class ConversationDAOTest : BaseDatabaseTest() { QualifiedIDEntity("6", "wire.com"), "conversation6", ConversationEntity.Type.GROUP, - null, + teamId, ConversationEntity.ProtocolInfo.Mixed( "group6", ConversationEntity.GroupState.ESTABLISHED, diff --git a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/MemberDAOTest.kt b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/MemberDAOTest.kt index 0e99db24be8..003a3b2a248 100644 --- a/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/MemberDAOTest.kt +++ b/persistence/src/commonTest/kotlin/com/wire/kalium/persistence/dao/MemberDAOTest.kt @@ -116,7 +116,7 @@ class MemberDAOTest : BaseDatabaseTest() { memberDAO.insertMembers( listOf(member1, member2), - (conversationEntity5.protocolInfo as ConversationEntity.ProtocolInfo.MLS).groupId + (conversationEntity5.protocolInfo as ConversationEntity.ProtocolInfo.MLSCapable).groupId ) assertEquals(listOf(member1, member2), memberDAO.observeConversationMembers(conversationEntity5.id).first())