diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepository.kt index 11397577c09..c43644ac9f9 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepository.kt @@ -25,7 +25,6 @@ import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.conversation.ConversationDetails import com.wire.kalium.logic.data.conversation.ConversationRepository import com.wire.kalium.logic.data.event.Event -import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.toApi import com.wire.kalium.logic.data.id.toDao import com.wire.kalium.logic.data.user.Connection @@ -54,6 +53,7 @@ import com.wire.kalium.network.api.base.authenticated.connection.ConnectionApi import com.wire.kalium.network.api.base.authenticated.connection.ConnectionDTO import com.wire.kalium.network.api.base.authenticated.connection.ConnectionStateDTO import com.wire.kalium.persistence.dao.ConnectionDAO +import com.wire.kalium.persistence.dao.ConnectionEntity import com.wire.kalium.persistence.dao.UserDAO import com.wire.kalium.persistence.dao.conversation.ConversationDAO import com.wire.kalium.persistence.dao.conversation.ConversationEntity @@ -74,7 +74,7 @@ interface ConnectionRepository { suspend fun observeConnectionRequestsForNotification(): Flow> suspend fun setConnectionAsNotified(userId: UserId) suspend fun setAllConnectionsAsNotified() - suspend fun deleteConnection(conversationId: ConversationId): Either + suspend fun deleteConnection(connection: Connection): Either } @Suppress("LongParameterList", "TooManyFunctions") @@ -249,8 +249,9 @@ internal class ConnectionDataSource( } } - override suspend fun deleteConnection(conversationId: ConversationId) = wrapStorageRequest { - connectionDAO.deleteConnectionDataAndConversation(conversationId.toDao()) + override suspend fun deleteConnection(connection: Connection) = wrapStorageRequest { + connectionDAO.deleteConnectionDataAndConversation(connection.qualifiedConversationId.toDao()) + userDAO.upsertConnectionStatuses(mapOf(connection.qualifiedToId.toDao() to ConnectionEntity.State.CANCELLED)) } /** @@ -260,6 +261,6 @@ internal class ConnectionDataSource( private suspend fun handleUserConnectionStatusPersistence(connection: Connection): Either = when (connection.status) { ACCEPTED, MISSING_LEGALHOLD_CONSENT, NOT_CONNECTED, PENDING, SENT, BLOCKED, IGNORED -> persistConnection(connection) - CANCELLED -> deleteConnection(connection.qualifiedConversationId) + CANCELLED -> deleteConnection(connection) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiver.kt index c303e6d026a..ef5c173011b 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiver.kt @@ -76,7 +76,7 @@ class FederationEventReceiverImpl internal constructor( if (conversationDetails is ConversationDetails.Connection && conversationDetails.otherUser?.id?.domain == event.domain ) { - connectionRepository.deleteConnection(conversationDetails.conversationId) + connectionRepository.deleteConnection(conversationDetails.connection) } } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepositoryTest.kt index f326bcd5317..69b3097ea32 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/connection/ConnectionRepositoryTest.kt @@ -25,6 +25,7 @@ import com.wire.kalium.logic.data.id.toDao import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.id.SelfTeamIdProvider +import com.wire.kalium.logic.framework.TestConnection import com.wire.kalium.logic.framework.TestConversation import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either @@ -44,6 +45,7 @@ import com.wire.kalium.network.api.base.model.UserProfileDTO import com.wire.kalium.network.exceptions.KaliumException import com.wire.kalium.network.utils.NetworkResponse import com.wire.kalium.persistence.dao.ConnectionDAO +import com.wire.kalium.persistence.dao.ConnectionEntity import com.wire.kalium.persistence.dao.QualifiedIDEntity import com.wire.kalium.persistence.dao.UserDAO import com.wire.kalium.persistence.dao.UserIDEntity @@ -284,12 +286,16 @@ class ConnectionRepositoryTest { @Test fun givenConversationId_WhenDeletingConnection_thenDeleteConnectionDataAndConversationShouldBeTriggered() = runTest { // given - val conversationId = com.wire.kalium.logic.data.id.QualifiedID("conversation_id", "domain_id") + val conversationId = TestConversation.ID val (arrangement, connectionRepository) = Arrangement().arrange() arrangement.withDeleteConnectionDataAndConversation(conversationId.toDao()) + val connection = TestConnection.CONNECTION.copy( + conversationId = conversationId.value, + qualifiedConversationId = conversationId, + ) // when - val result = connectionRepository.deleteConnection(conversationId) + val result = connectionRepository.deleteConnection(connection) // then result.shouldSucceed() @@ -297,6 +303,10 @@ class ConnectionRepositoryTest { .suspendFunction(arrangement.connectionDAO::deleteConnectionDataAndConversation) .with(eq(conversationId.toDao())) .wasInvoked(once) + verify(arrangement.userDAO) + .suspendFunction(arrangement.userDAO::upsertConnectionStatuses) + .with(eq(mapOf(connection.qualifiedToId.toDao() to ConnectionEntity.State.CANCELLED))) + .wasInvoked(once) } private class Arrangement : diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiverTest.kt index 64348b1639d..b7cef84273e 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FederationEventReceiverTest.kt @@ -19,9 +19,10 @@ package com.wire.kalium.logic.sync.receiver import com.wire.kalium.logic.data.event.Event import com.wire.kalium.logic.data.id.ConversationId -import com.wire.kalium.logic.data.id.QualifiedID import com.wire.kalium.logic.data.id.toDao +import com.wire.kalium.logic.data.user.Connection import com.wire.kalium.logic.data.user.UserId +import com.wire.kalium.logic.framework.TestConnection import com.wire.kalium.logic.framework.TestConversationDetails import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either @@ -51,17 +52,24 @@ class FederationEventReceiverTest { @Test fun givenConversationsWithFederatedUsers_whenReceivingFederationDeleteEvent_thenAllConversationsWithThemShouldBeCleared() = runTest { // Given + fun createConnection(conversationId: ConversationId, otherUserId: UserId) = TestConversationDetails.CONNECTION.copy( + conversationId = conversationId, + otherUser = TestUser.OTHER.copy(id = otherUserId), + connection = TestConnection.CONNECTION.copy( + qualifiedConversationId = conversationId, + conversationId = conversationId.value, + ) + ) val defederatedConnections = List(defederatedUsersCount) { - TestConversationDetails.CONNECTION.copy( + createConnection( conversationId = ConversationId("def_connection$it", defederatedDomain), - otherUser = TestUser.OTHER.copy(id = QualifiedID("connectionDefId$it", defederatedDomain)) + otherUserId = UserId("connectionDefId$it", defederatedDomain) ) } - val otherConnections = List(defederatedUsersCount) { - TestConversationDetails.CONNECTION.copy( + createConnection( conversationId = ConversationId("other_connection$it", otherDomain), - otherUser = TestUser.OTHER.copy(id = QualifiedID("connectionOtherId$it", otherDomain)) + otherUserId = UserId("connectionOtherId$it", otherDomain) ) } @@ -109,7 +117,7 @@ class FederationEventReceiverTest { verify(arrangement.connectionRepository) .suspendFunction(arrangement.connectionRepository::deleteConnection) - .with(matching { it.domain == defederatedDomain }) + .with(matching { it.qualifiedConversationId.domain == defederatedDomain }) .wasInvoked(exactly = defederatedConnections.size.time) verify(arrangement.connectionRepository) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/ConnectionRepositoryArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/ConnectionRepositoryArrangement.kt index 152bd4ca321..5823802a1fb 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/ConnectionRepositoryArrangement.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/repository/ConnectionRepositoryArrangement.kt @@ -21,14 +21,10 @@ import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.connection.ConnectionRepository import com.wire.kalium.logic.data.conversation.ConversationDetails -import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.user.Connection -import com.wire.kalium.logic.data.user.ConnectionState -import com.wire.kalium.logic.feature.connection.AcceptConnectionRequestUseCaseTest import com.wire.kalium.logic.functional.Either import io.mockative.Mock import io.mockative.any -import io.mockative.eq import io.mockative.given import io.mockative.matchers.Matcher import io.mockative.mock @@ -38,7 +34,7 @@ internal interface ConnectionRepositoryArrangement { val connectionRepository: ConnectionRepository fun withGetConnections(result: Either>>) - fun withDeleteConnection(result: Either, conversationId: Matcher = any()) + fun withDeleteConnection(result: Either, connection: Matcher = any()) fun withConnectionList(connectionsFlow: Flow>) fun withUpdateConnectionStatus(result: Either) } @@ -58,11 +54,11 @@ internal open class ConnectionRepositoryArrangementImpl : ConnectionRepositoryAr override fun withDeleteConnection( result: Either, - conversationId: Matcher, + connection: Matcher, ) { given(connectionRepository) .suspendFunction(connectionRepository::deleteConnection) - .whenInvokedWith(conversationId) + .whenInvokedWith(connection) .thenReturn(result) }