diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationGroupRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationGroupRepository.kt index b3e6cc1a030..adbc6fa2021 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationGroupRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/ConversationGroupRepository.kt @@ -205,7 +205,8 @@ internal class ConversationGroupRepositoryImpl( eventMapper.conversationMemberJoin( LocalId.generate(), response.event, - true + true, + false ) ) } @@ -244,7 +245,7 @@ internal class ConversationGroupRepositoryImpl( conversationId: ConversationId ) = if (apiResult.value is ConversationMemberAddedResponse.Changed) { memberJoinEventHandler.handle( - eventMapper.conversationMemberJoin(LocalId.generate(), apiResult.value.event, true) + eventMapper.conversationMemberJoin(LocalId.generate(), apiResult.value.event, true, false) ).flatMap { if (failedUsersList.isNotEmpty()) { newGroupConversationSystemMessagesCreator.value.conversationFailedToAddMembers(conversationId, failedUsersList) @@ -319,7 +320,7 @@ internal class ConversationGroupRepositoryImpl( if (response is ConversationMemberAddedResponse.Changed) { val conversationId = response.event.qualifiedConversation.toModel() - memberJoinEventHandler.handle(eventMapper.conversationMemberJoin(LocalId.generate(), response.event, true)) + memberJoinEventHandler.handle(eventMapper.conversationMemberJoin(LocalId.generate(), response.event, true, false)) .flatMap { wrapStorageRequest { conversationDAO.getConversationProtocolInfo(conversationId.toDao()) } .flatMap { protocol -> @@ -367,6 +368,7 @@ internal class ConversationGroupRepositoryImpl( eventMapper.conversationMemberLeave( LocalId.generate(), response.event, + false, false ) ) @@ -406,7 +408,8 @@ internal class ConversationGroupRepositoryImpl( eventMapper.conversationMessageTimerUpdate( LocalId.generate(), it, - true + true, + false ) ) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepository.kt index 607a807ec17..af57f619cf1 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepository.kt @@ -326,7 +326,7 @@ internal class MLSConversationDataSource( private suspend fun processCommitBundleEvents(events: List) { events.forEach { eventContentDTO -> - val event = MapperProvider.eventMapper().fromEventContentDTO("", eventContentDTO, true) + val event = MapperProvider.eventMapper().fromEventContentDTO("", eventContentDTO, true, false) if (event is Event.Conversation) { commitBundleEventReceiver.onEvent(event) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt index 6b241eab0e0..f1259704942 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/Event.kt @@ -44,7 +44,7 @@ import com.wire.kalium.util.DateTimeUtil import com.wire.kalium.util.serialization.toJsonElement import kotlinx.serialization.json.JsonNull -sealed class Event(open val id: String, open val transient: Boolean) { +sealed class Event(open val id: String, open val transient: Boolean, open val live: Boolean) { private companion object { const val typeKey = "type" @@ -69,15 +69,17 @@ sealed class Event(open val id: String, open val transient: Boolean) { sealed class Conversation( id: String, override val transient: Boolean, + override val live: Boolean, open val conversationId: ConversationId - ) : Event(id, transient) { + ) : Event(id, transient, live) { data class AccessUpdate( override val id: String, override val conversationId: ConversationId, val data: ConversationResponse, val qualifiedFrom: UserId, - override val transient: Boolean - ) : Conversation(id, transient, conversationId) { + override val transient: Boolean, + override val live: Boolean + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.AccessUpdate", @@ -91,12 +93,13 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val senderUserId: UserId, val senderClientId: ClientId, val timestampIso: String, val content: String, val encryptedExternalContent: EncryptedData? - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.NewMessage", @@ -112,11 +115,12 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val subconversationId: SubconversationId?, val senderUserId: UserId, val timestampIso: String, val content: String - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.NewMLSMessage", @@ -131,10 +135,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val senderUserId: UserId, val timestampIso: String, val conversation: ConversationResponse - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.NewConversation", @@ -148,10 +153,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val addedBy: UserId, val members: List, val timestampIso: String - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.MemberJoin", @@ -167,10 +173,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val removedBy: UserId, val removedList: List, val timestampIso: String - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.MemberLeave", @@ -185,15 +192,17 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, open val timestampIso: String, - transient: Boolean, - ) : Conversation(id, transient, conversationId) { + override val transient: Boolean, + override val live: Boolean, + ) : Conversation(id, transient, live, conversationId) { class MemberChangedRole( override val id: String, override val conversationId: ConversationId, override val timestampIso: String, override val transient: Boolean, + override val live: Boolean, val member: Member?, - ) : MemberChanged(id, conversationId, timestampIso, transient) { + ) : MemberChanged(id, conversationId, timestampIso, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.MemberChangedRole", @@ -209,9 +218,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val conversationId: ConversationId, override val timestampIso: String, override val transient: Boolean, + override val live: Boolean, val mutedConversationStatus: MutedConversationStatus, val mutedConversationChangedTime: String - ) : MemberChanged(id, conversationId, timestampIso, transient) { + ) : MemberChanged(id, conversationId, timestampIso, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.MemberMutedStatusChanged", @@ -226,8 +236,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class IgnoredMemberChanged( override val id: String, override val conversationId: ConversationId, - override val transient: Boolean - ) : MemberChanged(id, conversationId, "", transient) { + override val transient: Boolean, + override val live: Boolean, + ) : MemberChanged(id, conversationId, "", transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.IgnoredMemberChanged", @@ -241,10 +252,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val senderUserId: UserId, val message: String, val timestampIso: String = DateTimeUtil.currentIsoDateTimeString() - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.MLSWelcome", idKey to id.obfuscateId(), @@ -258,9 +270,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val senderUserId: UserId, val timestampIso: String, - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.DeletedConversation", @@ -275,10 +288,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val conversationName: String, val senderUserId: UserId, val timestampIso: String, - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf( typeKey to "Conversation.RenamedConversation", idKey to id.obfuscateId(), @@ -293,9 +307,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val receiptMode: ReceiptMode, val senderUserId: UserId - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap() = mapOf( typeKey to "Conversation.ConversationReceiptMode", @@ -310,10 +325,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val messageTimer: Long?, val senderUserId: UserId, val timestampIso: String - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap() = mapOf( typeKey to "Conversation.ConversationMessageTimer", @@ -329,11 +345,12 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val key: String, val code: String, val uri: String, val isPasswordProtected: Boolean, - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf(typeKey to "Conversation.CodeUpdated") } @@ -341,7 +358,8 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, - ) : Conversation(id, transient, conversationId) { + override val live: Boolean, + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap(): Map = mapOf(typeKey to "Conversation.CodeDeleted") } @@ -349,9 +367,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val conversationId: ConversationId, override val transient: Boolean, + override val live: Boolean, val protocol: Protocol, val senderUserId: UserId - ) : Conversation(id, transient, conversationId) { + ) : Conversation(id, transient, live, conversationId) { override fun toLogMap() = mapOf( typeKey to "Conversation.ConversationProtocol", idKey to id.obfuscateId(), @@ -366,14 +385,16 @@ sealed class Event(open val id: String, open val transient: Boolean) { id: String, open val teamId: String, transient: Boolean, - ) : Event(id, transient) { + live: Boolean, + ) : Event(id, transient, live) { data class Update( override val id: String, override val transient: Boolean, + override val live: Boolean, override val teamId: String, val icon: String, val name: String, - ) : Team(id, teamId, transient) { + ) : Team(id, teamId, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Team.Update", idKey to id.obfuscateId(), @@ -387,8 +408,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val teamId: String, override val transient: Boolean, + override val live: Boolean, val memberId: String, - ) : Team(id, teamId, transient) { + ) : Team(id, teamId, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Team.MemberJoin", idKey to id.obfuscateId(), @@ -400,10 +422,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class MemberLeave( override val id: String, override val transient: Boolean, + override val live: Boolean, override val teamId: String, val memberId: String, val timestampIso: String, - ) : Team(id, teamId, transient) { + ) : Team(id, teamId, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Team.MemberLeave", idKey to id.obfuscateId(), @@ -417,9 +440,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { override val id: String, override val teamId: String, override val transient: Boolean, + override val live: Boolean, val memberId: String, val permissionCode: Int?, - ) : Team(id, teamId, transient) { + ) : Team(id, teamId, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Team.MemberUpdate", idKey to id.obfuscateId(), @@ -434,12 +458,14 @@ sealed class Event(open val id: String, open val transient: Boolean) { sealed class FeatureConfig( id: String, transient: Boolean, - ) : Event(id, transient) { + live: Boolean, + ) : Event(id, transient, live) { data class FileSharingUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: ConfigsStatusModel - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.FileSharingUpdated", idKey to id.obfuscateId(), @@ -450,8 +476,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class MLSUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: MLSModel - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.MLSUpdated", idKey to id.obfuscateId(), @@ -463,8 +490,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class ClassifiedDomainsUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: ClassifiedDomainsModel, - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.ClassifiedDomainsUpdated", idKey to id.obfuscateId(), @@ -476,8 +504,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class ConferenceCallingUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: ConferenceCallingModel, - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap() = mapOf( typeKey to "FeatureConfig.ConferenceCallingUpdated", idKey to id.obfuscateId(), @@ -488,8 +517,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class GuestRoomLinkUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: ConfigsStatusModel, - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.GuestRoomLinkUpdated", idKey to id.obfuscateId(), @@ -500,8 +530,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class SelfDeletingMessagesConfig( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: SelfDeletingMessagesModel, - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.SelfDeletingMessagesConfig", idKey to id.obfuscateId(), @@ -513,8 +544,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class MLSE2EIUpdated( override val id: String, override val transient: Boolean, + override val live: Boolean, val model: E2EIModel - ) : FeatureConfig(id, transient) { + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.MLSE2EIUpdated", idKey to id.obfuscateId(), @@ -526,7 +558,8 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class UnknownFeatureUpdated( override val id: String, override val transient: Boolean, - ) : FeatureConfig(id, transient) { + override val live: Boolean, + ) : FeatureConfig(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "FeatureConfig.UnknownFeatureUpdated", idKey to id.obfuscateId(), @@ -536,12 +569,14 @@ sealed class Event(open val id: String, open val transient: Boolean) { sealed class User( id: String, - transient: Boolean - ) : Event(id, transient) { + transient: Boolean, + live: Boolean, + ) : Event(id, transient, live) { data class Update( override val id: String, override val transient: Boolean, + override val live: Boolean, val userId: String, val accentId: Int?, val ssoIdDeleted: Boolean?, @@ -551,7 +586,7 @@ sealed class Event(open val id: String, open val transient: Boolean) { val previewAssetId: String?, val completeAssetId: String?, val supportedProtocols: Set? - ) : User(id, transient) { + ) : User(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.Update", idKey to id.obfuscateId(), @@ -561,9 +596,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class NewConnection( override val transient: Boolean, + override val live: Boolean, override val id: String, val connection: Connection - ) : User(id, transient) { + ) : User(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.NewConnection", idKey to id.obfuscateId(), @@ -573,9 +609,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class ClientRemove( override val transient: Boolean, + override val live: Boolean, override val id: String, val clientId: ClientId - ) : User(id, transient) { + ) : User(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.ClientRemove", idKey to id.obfuscateId(), @@ -585,10 +622,11 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class UserDelete( override val transient: Boolean, + override val live: Boolean, override val id: String, val userId: UserId, val timestampIso: String = DateTimeUtil.currentIsoDateTimeString() // TODO we are not receiving it from API - ) : User(id, transient) { + ) : User(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.UserDelete", idKey to id.obfuscateId(), @@ -599,9 +637,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class NewClient( override val transient: Boolean, + override val live: Boolean, override val id: String, val client: Client, - ) : User(id, transient) { + ) : User(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.NewClient", idKey to id.obfuscateId(), @@ -618,14 +657,16 @@ sealed class Event(open val id: String, open val transient: Boolean) { sealed class UserProperty( id: String, - transient: Boolean - ) : Event(id, transient) { + transient: Boolean, + live: Boolean, + ) : Event(id, transient, live) { data class ReadReceiptModeSet( override val id: String, override val transient: Boolean, + override val live: Boolean, val value: Boolean, - ) : UserProperty(id, transient) { + ) : UserProperty(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.UserProperty.ReadReceiptModeSet", idKey to id.obfuscateId(), @@ -637,8 +678,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class TypingIndicatorModeSet( override val id: String, override val transient: Boolean, + override val live: Boolean, val value: Boolean, - ) : UserProperty(id, transient) { + ) : UserProperty(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.UserProperty.TypingIndicatorModeSet", idKey to id.obfuscateId(), @@ -651,9 +693,10 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class Unknown( override val id: String, override val transient: Boolean, + override val live: Boolean, val unknownType: String, val cause: String? = null - ) : Event(id, transient) { + ) : Event(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "User.UnknownEvent", idKey to id.obfuscateId(), @@ -665,13 +708,15 @@ sealed class Event(open val id: String, open val transient: Boolean) { sealed class Federation( id: String, override val transient: Boolean, - ) : Event(id, transient) { + override val live: Boolean, + ) : Event(id, transient, live) { data class Delete( override val id: String, override val transient: Boolean, + override val live: Boolean, val domain: String, - ) : Federation(id, transient) { + ) : Federation(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Federation.Delete", idKey to id.obfuscateId(), @@ -683,8 +728,9 @@ sealed class Event(open val id: String, open val transient: Boolean) { data class ConnectionRemoved( override val id: String, override val transient: Boolean, + override val live: Boolean, val domains: List, - ) : Federation(id, transient) { + ) : Federation(id, transient, live) { override fun toLogMap(): Map = mapOf( typeKey to "Federation.ConnectionRemoved", idKey to id.obfuscateId(), diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt index 25561315b73..8a7ba9ed92c 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventMapper.kt @@ -59,59 +59,61 @@ class EventMapper( private val receiptModeMapper: ReceiptModeMapper = MapperProvider.receiptModeMapper(), private val clientMapper: ClientMapper = MapperProvider.clientMapper() ) { - fun fromDTO(eventResponse: EventResponse): List { + fun fromDTO(eventResponse: EventResponse, live: Boolean = false): List { // TODO(edge-case): Multiple payloads in the same event have the same ID, is this an issue when marking lastProcessedEventId? val id = eventResponse.id return eventResponse.payload?.map { eventContentDTO -> - fromEventContentDTO(id, eventContentDTO, eventResponse.transient) + fromEventContentDTO(id, eventContentDTO, eventResponse.transient, live) } ?: listOf() } @Suppress("ComplexMethod") - fun fromEventContentDTO(id: String, eventContentDTO: EventContentDTO, transient: Boolean): Event = + fun fromEventContentDTO(id: String, eventContentDTO: EventContentDTO, transient: Boolean, live: Boolean): Event = when (eventContentDTO) { - is EventContentDTO.Conversation.NewMessageDTO -> newMessage(id, eventContentDTO, transient) - is EventContentDTO.Conversation.NewConversationDTO -> newConversation(id, eventContentDTO, transient) - is EventContentDTO.Conversation.MemberJoinDTO -> conversationMemberJoin(id, eventContentDTO, transient) - is EventContentDTO.Conversation.MemberLeaveDTO -> conversationMemberLeave(id, eventContentDTO, transient) - is EventContentDTO.Conversation.MemberUpdateDTO -> memberUpdate(id, eventContentDTO, transient) - is EventContentDTO.Conversation.MLSWelcomeDTO -> welcomeMessage(id, eventContentDTO, transient) - is EventContentDTO.Conversation.NewMLSMessageDTO -> newMLSMessage(id, eventContentDTO, transient) - is EventContentDTO.User.NewConnectionDTO -> connectionUpdate(id, eventContentDTO, transient) - is EventContentDTO.User.ClientRemoveDTO -> clientRemove(id, eventContentDTO, transient) - is EventContentDTO.User.UserDeleteDTO -> userDelete(id, eventContentDTO, transient) - is EventContentDTO.FeatureConfig.FeatureConfigUpdatedDTO -> featureConfig(id, eventContentDTO, transient) - is EventContentDTO.User.NewClientDTO -> newClient(id, eventContentDTO, transient) - is EventContentDTO.Unknown -> unknown(id, transient, eventContentDTO) - is EventContentDTO.Conversation.AccessUpdate -> unknown(id, transient, eventContentDTO) - is EventContentDTO.Conversation.DeletedConversationDTO -> conversationDeleted(id, eventContentDTO, transient) - is EventContentDTO.Conversation.ConversationRenameDTO -> conversationRenamed(id, eventContentDTO, transient) - is EventContentDTO.Team.MemberJoin -> teamMemberJoined(id, eventContentDTO, transient) - is EventContentDTO.Team.MemberLeave -> teamMemberLeft(id, eventContentDTO, transient) - is EventContentDTO.Team.MemberUpdate -> teamMemberUpdate(id, eventContentDTO, transient) - is EventContentDTO.Team.Update -> teamUpdate(id, eventContentDTO, transient) - is EventContentDTO.User.UpdateDTO -> userUpdate(id, eventContentDTO, transient) - is EventContentDTO.UserProperty.PropertiesSetDTO -> updateUserProperties(id, eventContentDTO, transient) - is EventContentDTO.UserProperty.PropertiesDeleteDTO -> deleteUserProperties(id, eventContentDTO, transient) - is EventContentDTO.Conversation.ReceiptModeUpdate -> conversationReceiptModeUpdate(id, eventContentDTO, transient) - is EventContentDTO.Conversation.MessageTimerUpdate -> conversationMessageTimerUpdate(id, eventContentDTO, transient) - is EventContentDTO.Conversation.CodeDeleted -> conversationCodeDeleted(id, eventContentDTO, transient) - is EventContentDTO.Conversation.CodeUpdated -> conversationCodeUpdated(id, eventContentDTO, transient) - is EventContentDTO.Federation -> federationTerminated(id, eventContentDTO, transient) - is EventContentDTO.Conversation.ProtocolUpdate -> conversationProtocolUpdate(id, eventContentDTO, transient) + is EventContentDTO.Conversation.NewMessageDTO -> newMessage(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.NewConversationDTO -> newConversation(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.MemberJoinDTO -> conversationMemberJoin(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.MemberLeaveDTO -> conversationMemberLeave(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.MemberUpdateDTO -> memberUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.MLSWelcomeDTO -> welcomeMessage(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.NewMLSMessageDTO -> newMLSMessage(id, eventContentDTO, transient, live) + is EventContentDTO.User.NewConnectionDTO -> connectionUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.User.ClientRemoveDTO -> clientRemove(id, eventContentDTO, transient, live) + is EventContentDTO.User.UserDeleteDTO -> userDelete(id, eventContentDTO, transient, live) + is EventContentDTO.FeatureConfig.FeatureConfigUpdatedDTO -> featureConfig(id, eventContentDTO, transient, live) + is EventContentDTO.User.NewClientDTO -> newClient(id, eventContentDTO, transient, live) + is EventContentDTO.Unknown -> unknown(id, transient, live, eventContentDTO) + is EventContentDTO.Conversation.AccessUpdate -> unknown(id, transient, live, eventContentDTO) + is EventContentDTO.Conversation.DeletedConversationDTO -> conversationDeleted(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.ConversationRenameDTO -> conversationRenamed(id, eventContentDTO, transient, live) + is EventContentDTO.Team.MemberJoin -> teamMemberJoined(id, eventContentDTO, transient, live) + is EventContentDTO.Team.MemberLeave -> teamMemberLeft(id, eventContentDTO, transient, live) + is EventContentDTO.Team.MemberUpdate -> teamMemberUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.Team.Update -> teamUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.User.UpdateDTO -> userUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.UserProperty.PropertiesSetDTO -> updateUserProperties(id, eventContentDTO, transient, live) + is EventContentDTO.UserProperty.PropertiesDeleteDTO -> deleteUserProperties(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.ReceiptModeUpdate -> conversationReceiptModeUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.MessageTimerUpdate -> conversationMessageTimerUpdate(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.CodeDeleted -> conversationCodeDeleted(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.CodeUpdated -> conversationCodeUpdated(id, eventContentDTO, transient, live) + is EventContentDTO.Federation -> federationTerminated(id, eventContentDTO, transient, live) + is EventContentDTO.Conversation.ProtocolUpdate -> conversationProtocolUpdate(id, eventContentDTO, transient, live) } - private fun federationTerminated(id: String, eventContentDTO: EventContentDTO.Federation, transient: Boolean): Event = + private fun federationTerminated(id: String, eventContentDTO: EventContentDTO.Federation, transient: Boolean, live: Boolean): Event = when (eventContentDTO) { is EventContentDTO.Federation.FederationConnectionRemovedDTO -> Event.Federation.ConnectionRemoved( id, transient, + live, eventContentDTO.domains ) is EventContentDTO.Federation.FederationDeleteDTO -> Event.Federation.Delete( id, transient, + live, eventContentDTO.domain ) } @@ -119,17 +121,20 @@ class EventMapper( private fun conversationCodeDeleted( id: String, event: EventContentDTO.Conversation.CodeDeleted, - transient: Boolean + transient: Boolean, + live: Boolean ): Event.Conversation.CodeDeleted = Event.Conversation.CodeDeleted( id = id, transient = transient, + live = live, conversationId = event.qualifiedConversation.toModel() ) private fun conversationCodeUpdated( id: String, event: EventContentDTO.Conversation.CodeUpdated, - transient: Boolean + transient: Boolean, + live: Boolean ): Event.Conversation.CodeUpdated = Event.Conversation.CodeUpdated( id = id, key = event.data.key, @@ -137,18 +142,21 @@ class EventMapper( uri = event.data.uri, isPasswordProtected = event.data.hasPassword, conversationId = event.qualifiedConversation.toModel(), - transient = transient + transient = transient, + live = live, ) @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class) fun unknown( id: String, transient: Boolean, + live: Boolean, eventContentDTO: EventContentDTO, cause: String? = null ): Event.Unknown = Event.Unknown( id = id, transient = transient, + live = live, unknownType = when (eventContentDTO) { is EventContentDTO.Unknown -> eventContentDTO.type else -> try { @@ -163,11 +171,13 @@ class EventMapper( private fun conversationProtocolUpdate( id: String, eventContentDTO: EventContentDTO.Conversation.ProtocolUpdate, - transient: Boolean + transient: Boolean, + live: Boolean ): Event = Event.Conversation.ConversationProtocol( id = id, conversationId = eventContentDTO.qualifiedConversation.toModel(), transient = transient, + live = live, protocol = eventContentDTO.data.protocol.toModel(), senderUserId = eventContentDTO.qualifiedFrom.toModel() ) @@ -175,11 +185,13 @@ class EventMapper( fun conversationMessageTimerUpdate( id: String, eventContentDTO: EventContentDTO.Conversation.MessageTimerUpdate, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.ConversationMessageTimer( id = id, conversationId = eventContentDTO.qualifiedConversation.toModel(), transient = transient, + live = live, messageTimer = eventContentDTO.data.messageTimer, senderUserId = eventContentDTO.qualifiedFrom.toModel(), timestampIso = eventContentDTO.time @@ -188,11 +200,13 @@ class EventMapper( private fun conversationReceiptModeUpdate( id: String, eventContentDTO: EventContentDTO.Conversation.ReceiptModeUpdate, - transient: Boolean + transient: Boolean, + live: Boolean ): Event = Event.Conversation.ConversationReceiptMode( id = id, conversationId = eventContentDTO.qualifiedConversation.toModel(), transient = transient, + live = live, receiptMode = receiptModeMapper.fromApiToModel(eventContentDTO.data.receiptMode), senderUserId = eventContentDTO.qualifiedFrom.toModel() ) @@ -200,7 +214,8 @@ class EventMapper( private fun updateUserProperties( id: String, eventContentDTO: EventContentDTO.UserProperty.PropertiesSetDTO, - transient: Boolean + transient: Boolean, + live: Boolean ): Event { val fieldKeyValue = eventContentDTO.value val key = eventContentDTO.key @@ -210,18 +225,21 @@ class EventMapper( WIRE_RECEIPT_MODE.key -> ReadReceiptModeSet( id, transient, + live, fieldKeyValue.value == 1 ) WIRE_TYPING_INDICATOR_MODE.key -> TypingIndicatorModeSet( id, transient, + live, fieldKeyValue.value != 0 ) else -> unknown( id = id, transient = transient, + live = live, eventContentDTO = eventContentDTO, cause = "Unknown key: $key " ) @@ -230,6 +248,7 @@ class EventMapper( else -> unknown( id = id, transient = transient, + live = live, eventContentDTO = eventContentDTO, cause = "Unknown value type for key: ${eventContentDTO.key} " ) @@ -239,14 +258,16 @@ class EventMapper( private fun deleteUserProperties( id: String, eventContentDTO: EventContentDTO.UserProperty.PropertiesDeleteDTO, - transient: Boolean + transient: Boolean, + live: Boolean ): Event { return when (eventContentDTO.key) { - WIRE_RECEIPT_MODE.key -> ReadReceiptModeSet(id, transient, false) - WIRE_TYPING_INDICATOR_MODE.key -> TypingIndicatorModeSet(id, transient, true) + WIRE_RECEIPT_MODE.key -> ReadReceiptModeSet(id, transient, live, false) + WIRE_TYPING_INDICATOR_MODE.key -> TypingIndicatorModeSet(id, transient, live, true) else -> unknown( id = id, transient = transient, + live = live, eventContentDTO = eventContentDTO, cause = "Unknown key: ${eventContentDTO.key} " ) @@ -256,11 +277,13 @@ class EventMapper( private fun welcomeMessage( id: String, eventContentDTO: EventContentDTO.Conversation.MLSWelcomeDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.MLSWelcome( id, eventContentDTO.qualifiedConversation.toModel(), transient, + live, eventContentDTO.qualifiedFrom.toModel(), eventContentDTO.message, ) @@ -268,11 +291,13 @@ class EventMapper( private fun newMessage( id: String, eventContentDTO: EventContentDTO.Conversation.NewMessageDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.NewMessage( id, eventContentDTO.qualifiedConversation.toModel(), transient, + live, eventContentDTO.qualifiedFrom.toModel(), ClientId(eventContentDTO.data.sender), eventContentDTO.time, @@ -285,11 +310,13 @@ class EventMapper( private fun newMLSMessage( id: String, eventContentDTO: EventContentDTO.Conversation.NewMLSMessageDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.NewMLSMessage( id, eventContentDTO.qualifiedConversation.toModel(), transient, + live, eventContentDTO.subconversation?.let { SubconversationId(it) }, eventContentDTO.qualifiedFrom.toModel(), eventContentDTO.time, @@ -299,32 +326,42 @@ class EventMapper( private fun connectionUpdate( id: String, eventConnectionDTO: EventContentDTO.User.NewConnectionDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.User.NewConnection( transient, + live, id, connectionMapper.fromApiToModel(eventConnectionDTO.connection) ) - private fun userDelete(id: String, eventUserDelete: EventContentDTO.User.UserDeleteDTO, transient: Boolean): Event.User.UserDelete { - return Event.User.UserDelete(transient, id, eventUserDelete.userId.toModel()) + private fun userDelete( + id: String, + eventUserDelete: EventContentDTO.User.UserDeleteDTO, + transient: Boolean, + live: Boolean + ): Event.User.UserDelete { + return Event.User.UserDelete(transient, live, id, eventUserDelete.userId.toModel()) } private fun clientRemove( id: String, eventClientRemove: EventContentDTO.User.ClientRemoveDTO, - transient: Boolean + transient: Boolean, + live: Boolean ): Event.User.ClientRemove { - return Event.User.ClientRemove(transient, id, ClientId(eventClientRemove.client.clientId)) + return Event.User.ClientRemove(transient, live, id, ClientId(eventClientRemove.client.clientId)) } private fun newClient( id: String, eventNewClient: EventContentDTO.User.NewClientDTO, - transient: Boolean + transient: Boolean, + live: Boolean ): Event.User.NewClient { return Event.User.NewClient( transient = transient, + live = live, id = id, client = clientMapper.fromClientDto(eventNewClient.client) ) @@ -333,11 +370,13 @@ class EventMapper( private fun newConversation( id: String, eventContentDTO: EventContentDTO.Conversation.NewConversationDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.NewConversation( id, eventContentDTO.qualifiedConversation.toModel(), transient, + live, eventContentDTO.qualifiedFrom.toModel(), eventContentDTO.time, eventContentDTO.data @@ -346,33 +385,38 @@ class EventMapper( fun conversationMemberJoin( id: String, eventContentDTO: EventContentDTO.Conversation.MemberJoinDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.MemberJoin( id = id, conversationId = eventContentDTO.qualifiedConversation.toModel(), addedBy = eventContentDTO.qualifiedFrom.toModel(), members = eventContentDTO.members.users.map { memberMapper.fromApiModel(it) }, timestampIso = eventContentDTO.time, - transient = transient + transient = transient, + live = live, ) fun conversationMemberLeave( id: String, eventContentDTO: EventContentDTO.Conversation.MemberLeaveDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.MemberLeave( id = id, conversationId = eventContentDTO.qualifiedConversation.toModel(), removedBy = eventContentDTO.qualifiedFrom.toModel(), removedList = eventContentDTO.members.qualifiedUserIds.map { it.toModel() }, timestampIso = eventContentDTO.time, - transient = transient + transient = transient, + live = live, ) private fun memberUpdate( id: String, eventContentDTO: EventContentDTO.Conversation.MemberUpdateDTO, - transient: Boolean + transient: Boolean, + live: Boolean ): Event.Conversation.MemberChanged { return when { eventContentDTO.roleChange.role?.isNotEmpty() == true -> { @@ -381,6 +425,7 @@ class EventMapper( conversationId = eventContentDTO.qualifiedConversation.toModel(), timestampIso = eventContentDTO.time, transient = transient, + live = live, member = Conversation.Member( id = eventContentDTO.roleChange.qualifiedUserId.toModel(), role = roleMapper.fromApi(eventContentDTO.roleChange.role.orEmpty()) @@ -395,6 +440,7 @@ class EventMapper( timestampIso = eventContentDTO.time, mutedConversationChangedTime = eventContentDTO.roleChange.mutedRef.orEmpty(), transient = transient, + live = live, mutedConversationStatus = mapConversationMutedStatus(eventContentDTO.roleChange.mutedStatus) ) } @@ -403,7 +449,8 @@ class EventMapper( Event.Conversation.MemberChanged.IgnoredMemberChanged( id, eventContentDTO.qualifiedConversation.toModel(), - transient + transient, + live ) } } @@ -420,129 +467,150 @@ class EventMapper( private fun featureConfig( id: String, featureConfigUpdatedDTO: EventContentDTO.FeatureConfig.FeatureConfigUpdatedDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = when (featureConfigUpdatedDTO.data) { is FeatureConfigData.FileSharing -> Event.FeatureConfig.FileSharingUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.FileSharing) ) is FeatureConfigData.SelfDeletingMessages -> Event.FeatureConfig.SelfDeletingMessagesConfig( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.SelfDeletingMessages) ) is FeatureConfigData.MLS -> Event.FeatureConfig.MLSUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.MLS) ) is FeatureConfigData.ClassifiedDomains -> Event.FeatureConfig.ClassifiedDomainsUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.ClassifiedDomains) ) is FeatureConfigData.ConferenceCalling -> Event.FeatureConfig.ConferenceCallingUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.ConferenceCalling) ) is FeatureConfigData.ConversationGuestLinks -> Event.FeatureConfig.GuestRoomLinkUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.ConversationGuestLinks) ) is FeatureConfigData.E2EI -> Event.FeatureConfig.MLSE2EIUpdated( id, transient, + live, featureConfigMapper.fromDTO(featureConfigUpdatedDTO.data as FeatureConfigData.E2EI) ) - else -> Event.FeatureConfig.UnknownFeatureUpdated(id, transient) + else -> Event.FeatureConfig.UnknownFeatureUpdated(id, transient, live) } private fun conversationDeleted( id: String, deletedConversationDTO: EventContentDTO.Conversation.DeletedConversationDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.DeletedConversation( id = id, conversationId = deletedConversationDTO.qualifiedConversation.toModel(), senderUserId = deletedConversationDTO.qualifiedFrom.toModel(), transient = transient, + live = live, timestampIso = deletedConversationDTO.time ) fun conversationRenamed( id: String, event: EventContentDTO.Conversation.ConversationRenameDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Conversation.RenamedConversation( id = id, conversationId = event.qualifiedConversation.toModel(), senderUserId = event.qualifiedFrom.toModel(), conversationName = event.updateNameData.conversationName, transient = transient, + live = live, timestampIso = event.time, ) private fun teamMemberJoined( id: String, event: EventContentDTO.Team.MemberJoin, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Team.MemberJoin( id = id, teamId = event.teamId, transient = transient, + live = live, memberId = event.teamMember.nonQualifiedUserId ) private fun teamMemberLeft( id: String, event: EventContentDTO.Team.MemberLeave, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Team.MemberLeave( id = id, teamId = event.teamId, memberId = event.teamMember.nonQualifiedUserId, transient = transient, + live = live, timestampIso = event.time ) private fun teamMemberUpdate( id: String, event: EventContentDTO.Team.MemberUpdate, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Team.MemberUpdate( id = id, teamId = event.teamId, memberId = event.permissionsResponse.nonQualifiedUserId, transient = transient, + live = live, permissionCode = event.permissionsResponse.permissions.own ) private fun teamUpdate( id: String, event: EventContentDTO.Team.Update, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.Team.Update( id = id, teamId = event.teamId, icon = event.teamUpdate.icon, transient = transient, + live = live, name = event.teamUpdate.name ) private fun userUpdate( id: String, event: EventContentDTO.User.UpdateDTO, - transient: Boolean + transient: Boolean, + live: Boolean ) = Event.User.Update( id = id, userId = event.userData.nonQualifiedUserId, @@ -553,6 +621,7 @@ class EventMapper( email = event.userData.email, previewAssetId = event.userData.assets?.getPreviewAssetOrNull()?.key, transient = transient, + live = live, completeAssetId = event.userData.assets?.getCompleteAssetOrNull()?.key, supportedProtocols = event.userData.supportedProtocols?.toModel() ) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventRepository.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventRepository.kt index 655199e9d80..f94d546a33f 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventRepository.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/event/EventRepository.kt @@ -108,7 +108,7 @@ class EventDataSource( } is WebSocketEvent.BinaryPayloadReceived -> { - eventMapper.fromDTO(webSocketEvent.payload).asFlow().map { WebSocketEvent.BinaryPayloadReceived(it) } + eventMapper.fromDTO(webSocketEvent.payload, true).asFlow().map { WebSocketEvent.BinaryPayloadReceived(it) } } } }.flattenConcat() 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 d5add348cd3..a8c42ccbfc6 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 @@ -890,7 +890,8 @@ class UserSessionScope internal constructor( get() = OneOnOneResolverImpl( userRepository, oneOnOneProtocolSelector, - oneOnOneMigrator + oneOnOneMigrator, + incrementalSyncRepository ) private val slowSyncWorker: SlowSyncWorker by lazy { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/RenameConversationUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/RenameConversationUseCase.kt index 4d5f71a3377..4ec5e031b19 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/RenameConversationUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/RenameConversationUseCase.kt @@ -54,7 +54,7 @@ internal class RenameConversationUseCaseImpl( .onSuccess { response -> if (response is ConversationRenameResponse.Changed) renamedConversationEventHandler.handle( - eventMapper.conversationRenamed(LocalId.generate(), response.event, true) + eventMapper.conversationRenamed(LocalId.generate(), response.event, true, false) ) } .fold({ diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/guestroomlink/GenerateGuestRoomLinkUseCase.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/guestroomlink/GenerateGuestRoomLinkUseCase.kt index 9e482f86f34..42a6e7a77b4 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/guestroomlink/GenerateGuestRoomLinkUseCase.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/guestroomlink/GenerateGuestRoomLinkUseCase.kt @@ -51,6 +51,7 @@ class GenerateGuestRoomLinkUseCaseImpl internal constructor( id = uuid4().toString(), isPasswordProtected = it.data.hasPassword, transient = false, + live = false, key = it.data.key, uri = it.data.uri ) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolver.kt index 790ebd7b088..f6a899cb78e 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolver.kt @@ -20,6 +20,8 @@ package com.wire.kalium.logic.feature.conversation.mls import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.data.id.ConversationId +import com.wire.kalium.logic.data.sync.IncrementalSyncRepository +import com.wire.kalium.logic.data.sync.IncrementalSyncStatus import com.wire.kalium.logic.data.user.OtherUser import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.data.user.UserId @@ -31,10 +33,20 @@ import com.wire.kalium.logic.functional.flatMapLeft import com.wire.kalium.logic.functional.foldToEitherWhileRight import com.wire.kalium.logic.functional.map import com.wire.kalium.logic.kaliumLogger +import com.wire.kalium.util.KaliumDispatcher +import com.wire.kalium.util.KaliumDispatcherImpl +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.launch +import kotlin.time.Duration interface OneOnOneResolver { suspend fun resolveAllOneOnOneConversations(): Either + suspend fun scheduleResolveOneOnOneConversationWithUserId(userId: UserId, delay: Duration = Duration.ZERO): Job suspend fun resolveOneOnOneConversationWithUserId(userId: UserId): Either suspend fun resolveOneOnOneConversationWithUser(user: OtherUser): Either } @@ -43,8 +55,14 @@ internal class OneOnOneResolverImpl( private val userRepository: UserRepository, private val oneOnOneProtocolSelector: OneOnOneProtocolSelector, private val oneOnOneMigrator: OneOnOneMigrator, + private val incrementalSyncRepository: IncrementalSyncRepository, + kaliumDispatcher: KaliumDispatcher = KaliumDispatcherImpl ) : OneOnOneResolver { + @OptIn(ExperimentalCoroutinesApi::class) + private val dispatcher = kaliumDispatcher.default.limitedParallelism(1) + private val resolveActiveOneOnOneScope = CoroutineScope(dispatcher) + override suspend fun resolveAllOneOnOneConversations(): Either { val usersWithOneOnOne = userRepository.getUsersWithOneOnOneConversation() kaliumLogger.i("Resolving one-on-one protocol for ${usersWithOneOnOne.size} user(s)") @@ -53,6 +71,14 @@ internal class OneOnOneResolverImpl( } } + override suspend fun scheduleResolveOneOnOneConversationWithUserId(userId: UserId, delay: Duration) = + resolveActiveOneOnOneScope.launch { + kaliumLogger.d("Schedule resolving active one-on-one") + incrementalSyncRepository.incrementalSyncState.first { it is IncrementalSyncStatus.Live } + delay(delay) + resolveOneOnOneConversationWithUserId(userId) + } + override suspend fun resolveOneOnOneConversationWithUserId(userId: UserId): Either = userRepository.getKnownUser(userId).firstOrNull()?.let { resolveOneOnOneConversationWithUser(it) diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt index 1fea9ddfb3a..6f23f6943d6 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiver.kt @@ -26,7 +26,6 @@ import com.wire.kalium.logic.data.event.Event import com.wire.kalium.logic.data.event.EventLoggingStatus import com.wire.kalium.logic.data.event.logEventProcessing import com.wire.kalium.logic.data.logout.LogoutReason -import com.wire.kalium.logic.data.user.Connection import com.wire.kalium.logic.data.user.ConnectionState import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.user.UserRepository @@ -39,6 +38,8 @@ import com.wire.kalium.logic.functional.map import com.wire.kalium.logic.functional.onFailure import com.wire.kalium.logic.functional.onSuccess import com.wire.kalium.logic.kaliumLogger +import kotlin.time.Duration.Companion.ZERO +import kotlin.time.Duration.Companion.seconds internal interface UserEventReceiver : EventReceiver @@ -51,7 +52,7 @@ internal class UserEventReceiverImpl internal constructor( private val logout: LogoutUseCase, private val oneOnOneResolver: OneOnOneResolver, private val selfUserId: UserId, - private val currentClientIdProvider: CurrentClientIdProvider, + private val currentClientIdProvider: CurrentClientIdProvider ) : UserEventReceiver { override suspend fun onEvent(event: Event.User): Either { @@ -85,7 +86,15 @@ internal class UserEventReceiverImpl internal constructor( private suspend fun handleNewConnection(event: Event.User.NewConnection): Either = connectionRepository.insertConnectionFromEvent(event) .flatMap { - resolveActiveOneOnOneConversationUponConnectionAccepted(event.connection) + if (event.connection.status != ConnectionState.ACCEPTED) { + return@flatMap Either.Right(Unit) + } + + oneOnOneResolver.scheduleResolveOneOnOneConversationWithUserId( + event.connection.qualifiedToId, + delay = if (event.live) 3.seconds else ZERO + ) + Either.Right(Unit) } .onSuccess { kaliumLogger @@ -103,13 +112,6 @@ internal class UserEventReceiverImpl internal constructor( ) } - private suspend fun resolveActiveOneOnOneConversationUponConnectionAccepted(connection: Connection): Either = - if (connection.status == ConnectionState.ACCEPTED) { - oneOnOneResolver.resolveOneOnOneConversationWithUserId(connection.qualifiedToId).map { } - } else { - Either.Right(Unit) - } - private suspend fun handleClientRemove(event: Event.User.ClientRemove): Either = currentClientIdProvider().map { currentClientId -> if (currentClientId == event.clientId) { diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepositoryTest.kt index 48df23712d0..6ae3c452806 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/ConversationRepositoryTest.kt @@ -124,6 +124,7 @@ class ConversationRepositoryTest { "id", TestConversation.ID, false, + false, TestUser.SELF.id, "time", CONVERSATION_RESPONSE @@ -154,6 +155,7 @@ class ConversationRepositoryTest { "id", TestConversation.ID, false, + false, TestUser.SELF.id, "time", CONVERSATION_RESPONSE @@ -185,6 +187,7 @@ class ConversationRepositoryTest { "id", TestConversation.ID, false, + false, TestUser.SELF.id, "time", CONVERSATION_RESPONSE @@ -216,6 +219,7 @@ class ConversationRepositoryTest { "id", TestConversation.ID, false, + false, TestUser.SELF.id, "time", CONVERSATION_RESPONSE.copy( diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt index 0933a47b6cf..f764cb0fdf8 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/conversation/MLSConversationRepositoryTest.kt @@ -1290,6 +1290,7 @@ class MLSConversationRepositoryTest { "eventId", TestConversation.ID, false, + false, TestUser.USER_ID, WELCOME.encodeBase64(), timestampIso = "2022-03-30T15:36:00.000Z" diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolverTest.kt index 677481ce34c..7b0ddf225ab 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/feature/conversation/mls/OneOnOneResolverTest.kt @@ -22,6 +22,8 @@ import com.wire.kalium.logic.data.user.SupportedProtocol import com.wire.kalium.logic.framework.TestConversation import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either +import com.wire.kalium.logic.util.arrangement.IncrementalSyncRepositoryArrangement +import com.wire.kalium.logic.util.arrangement.IncrementalSyncRepositoryArrangementImpl import com.wire.kalium.logic.util.arrangement.UserRepositoryArrangement import com.wire.kalium.logic.util.arrangement.UserRepositoryArrangementImpl import com.wire.kalium.logic.util.arrangement.mls.OneOnOneMigratorArrangement @@ -119,14 +121,16 @@ class OneOnOneResolverTest { private class Arrangement(private val block: Arrangement.() -> Unit) : UserRepositoryArrangement by UserRepositoryArrangementImpl(), OneOnOneProtocolSelectorArrangement by OneOnOneProtocolSelectorArrangementImpl(), - OneOnOneMigratorArrangement by OneOnOneMigratorArrangementImpl() + OneOnOneMigratorArrangement by OneOnOneMigratorArrangementImpl(), + IncrementalSyncRepositoryArrangement by IncrementalSyncRepositoryArrangementImpl() { fun arrange() = run { block() this@Arrangement to OneOnOneResolverImpl( userRepository = userRepository, oneOnOneProtocolSelector = oneOnOneProtocolSelector, - oneOnOneMigrator = oneOnOneMigrator + oneOnOneMigrator = oneOnOneMigrator, + incrementalSyncRepository = incrementalSyncRepository ) } } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt index 79647da7f68..b4c78e85afa 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/framework/TestEvent.kt @@ -37,6 +37,7 @@ object TestEvent { eventId, TestConversation.ID, false, + false, TestUser.USER_ID, members, "2022-03-30T15:36:00.000Z" @@ -46,6 +47,7 @@ object TestEvent { eventId, TestConversation.ID, false, + false, TestUser.USER_ID, listOf(), "2022-03-30T15:36:00.000Z" @@ -56,6 +58,7 @@ object TestEvent { TestConversation.ID, "2022-03-30T15:36:00.000Z", false, + false, member ) @@ -64,6 +67,7 @@ object TestEvent { TestConversation.ID, "2022-03-30T15:36:00.000Z", false, + false, MutedConversationStatus.AllAllowed, "2022-03-30T15:36:00.000Zp" ) @@ -72,20 +76,22 @@ object TestEvent { eventId, TestConversation.ID, false, + false ) - fun clientRemove(eventId: String = "eventId", clientId: ClientId) = Event.User.ClientRemove(false, eventId, clientId) - fun userDelete(eventId: String = "eventId", userId: UserId) = Event.User.UserDelete(false, eventId, userId) + fun clientRemove(eventId: String = "eventId", clientId: ClientId) = Event.User.ClientRemove(false, false, eventId, clientId) + fun userDelete(eventId: String = "eventId", userId: UserId) = Event.User.UserDelete(false, false, eventId, userId) fun updateUser(eventId: String = "eventId", userId: UserId) = Event.User.Update( eventId, - false, userId.toString(), null, false, "newName", null, null, null, null, null + false, false, userId.toString(), null, false, "newName", null, null, null, null, null ) fun newClient(eventId: String = "eventId", clientId: ClientId = ClientId("client")) = Event.User.NewClient( - false, eventId, TestClient.CLIENT + false, false, eventId, TestClient.CLIENT ) fun newConnection(eventId: String = "eventId", status: ConnectionState = ConnectionState.PENDING) = Event.User.NewConnection( + false, false, eventId, Connection( @@ -103,6 +109,7 @@ object TestEvent { eventId, TestConversation.ID, false, + false, TestUser.USER_ID, "2022-03-30T15:36:00.000Z" ) @@ -111,6 +118,7 @@ object TestEvent { eventId, TestConversation.ID, false, + false, "newName", TestUser.USER_ID, "2022-03-30T15:36:00.000Z" @@ -120,6 +128,7 @@ object TestEvent { eventId, TestConversation.ID, false, + false, receiptMode = Conversation.ReceiptMode.ENABLED, senderUserId = TestUser.USER_ID ) @@ -129,13 +138,15 @@ object TestEvent { teamId = "teamId", name = "teamName", transient = false, + live = false, icon = "icon", ) fun teamMemberJoin(eventId: String = "eventId") = Event.Team.MemberJoin( eventId, teamId = "teamId", - false, + transient = false, + live = false, memberId = "memberId" ) @@ -144,7 +155,8 @@ object TestEvent { teamId = "teamId", memberId = "memberId", timestampIso = "2022-03-30T15:36:00.000Z", - transient = false + transient = false, + live = false ) fun teamMemberUpdate(eventId: String = "eventId", permissionCode: Int) = Event.Team.MemberUpdate( @@ -152,13 +164,15 @@ object TestEvent { teamId = "teamId", memberId = "memberId", permissionCode = permissionCode, - transient = false + transient = false, + live = false ) fun timerChanged(eventId: String = "eventId") = Event.Conversation.ConversationMessageTimer( id = eventId, conversationId = TestConversation.ID, transient = false, + live = false, messageTimer = 3000, senderUserId = TestUser.USER_ID, timestampIso = "2022-03-30T15:36:00.000Z" @@ -167,6 +181,7 @@ object TestEvent { fun userPropertyReadReceiptMode(eventId: String = "eventId") = Event.UserProperty.ReadReceiptModeSet( id = eventId, transient = false, + live = false, value = true ) @@ -178,6 +193,7 @@ object TestEvent { "eventId", TestConversation.ID, false, + false, senderUserId, TestClient.CLIENT_ID, "time", @@ -191,6 +207,7 @@ object TestEvent { "eventId", TestConversation.ID, false, + false, null, TestUser.USER_ID, timestamp.toIsoDateTimeString(), @@ -201,6 +218,7 @@ object TestEvent { id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false, timestampIso = "timestamp", conversation = TestConversation.CONVERSATION_RESPONSE, senderUserId = TestUser.SELF.id @@ -210,6 +228,7 @@ object TestEvent { "eventId", TestConversation.ID, false, + false, TestUser.USER_ID, "dummy-message", timestampIso = "2022-03-30T15:36:00.000Z" @@ -220,13 +239,15 @@ object TestEvent { conversationId = TestConversation.ID, data = TestConversation.CONVERSATION_RESPONSE, qualifiedFrom = TestUser.USER_ID, - transient = false + transient = false, + live = false ) fun codeUpdated() = Event.Conversation.CodeUpdated( id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false, code = "code", key = "key", uri = "uri", @@ -237,6 +258,7 @@ object TestEvent { id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false ) fun newConversationProtocolEvent() = Event.Conversation.ConversationProtocol( diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt index 4d9ea9d53db..ea7ba20e67c 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/FeatureConfigEventReceiverTest.kt @@ -436,19 +436,19 @@ class FeatureConfigEventReceiverTest { fun newMLSUpdatedEvent( model: MLSModel - ) = Event.FeatureConfig.MLSUpdated("eventId", false, model) + ) = Event.FeatureConfig.MLSUpdated("eventId", false, false, model) fun newFileSharingUpdatedEvent( model: ConfigsStatusModel - ) = Event.FeatureConfig.FileSharingUpdated("eventId", false, model) + ) = Event.FeatureConfig.FileSharingUpdated("eventId", false, false, model) fun newConferenceCallingUpdatedEvent( model: ConferenceCallingModel - ) = Event.FeatureConfig.ConferenceCallingUpdated("eventId", false, model) + ) = Event.FeatureConfig.ConferenceCallingUpdated("eventId", false, false, model) fun newSelfDeletingMessagesUpdatedEvent( model: SelfDeletingMessagesModel - ) = Event.FeatureConfig.SelfDeletingMessagesConfig("eventId", false, model) + ) = Event.FeatureConfig.SelfDeletingMessagesConfig("eventId", false, false, model) fun arrange() = this to featureConfigEventReceiver } 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 0c2c53e712c..b375e0d890a 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 @@ -100,6 +100,7 @@ class FederationEventReceiverTest { val event = Event.Federation.Delete( "id", true, + false, defederatedDomain ) @@ -170,6 +171,7 @@ class FederationEventReceiverTest { val event = Event.Federation.ConnectionRemoved( "id", true, + false, listOf(defederatedDomain, defederatedDomainTwo) ) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiverTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiverTest.kt index 61982385f93..40a197f9965 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiverTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/UserEventReceiverTest.kt @@ -30,8 +30,8 @@ import com.wire.kalium.logic.feature.CurrentClientIdProvider import com.wire.kalium.logic.feature.auth.LogoutUseCase import com.wire.kalium.logic.framework.TestConversation import com.wire.kalium.logic.framework.TestEvent -import com.wire.kalium.logic.framework.TestUser import com.wire.kalium.logic.functional.Either +import com.wire.kalium.logic.test_util.TestKaliumDispatcher import com.wire.kalium.logic.util.arrangement.UserRepositoryArrangement import com.wire.kalium.logic.util.arrangement.UserRepositoryArrangementImpl import com.wire.kalium.logic.util.arrangement.mls.OneOnOneResolverArrangement @@ -44,9 +44,12 @@ import io.mockative.given import io.mockative.mock import io.mockative.once import io.mockative.verify -import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.advanceUntilIdle import kotlinx.coroutines.test.runTest import kotlin.test.Test +import kotlin.time.Duration.Companion.ZERO +import kotlin.time.Duration.Companion.seconds class UserEventReceiverTest { @@ -178,18 +181,36 @@ class UserEventReceiverTest { } @Test - fun givenNewConnectionEventWithStatusAccepted_thenActiveOneOnOneConversationIsResolved() = runTest { + fun givenNewConnectionEventWithStatusAccepted_thenResolveActiveOneOnOneConversationIsScheduled() = runTest { val event = TestEvent.newConnection(status = ConnectionState.ACCEPTED).copy() val (arrangement, eventReceiver) = arrange { withInsertConnectionFromEventSucceeding() - withResolveOneOnOneConversationWithUserIdReturning(Either.Right(TestConversation.ID)) + withScheduleResolveOneOnOneConversationWithUserId() } eventReceiver.onEvent(event) verify(arrangement.oneOnOneResolver) - .suspendFunction(arrangement.oneOnOneResolver::resolveOneOnOneConversationWithUserId) - .with(eq(event.connection.qualifiedToId)) + .suspendFunction(arrangement.oneOnOneResolver::scheduleResolveOneOnOneConversationWithUserId) + .with(eq(event.connection.qualifiedToId), eq(ZERO)) + .wasInvoked(exactly = once) + } + + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun givenLiveNewConnectionEventWithStatusAccepted_thenResolveActiveOneOnOneConversationIsScheduledWithDelay() = runTest(TestKaliumDispatcher.default) { + val event = TestEvent.newConnection(status = ConnectionState.ACCEPTED).copy(live = true) + val (arrangement, eventReceiver) = arrange { + withInsertConnectionFromEventSucceeding() + withScheduleResolveOneOnOneConversationWithUserId() + } + + eventReceiver.onEvent(event) + advanceUntilIdle() + + verify(arrangement.oneOnOneResolver) + .suspendFunction(arrangement.oneOnOneResolver::scheduleResolveOneOnOneConversationWithUserId) + .with(eq(event.connection.qualifiedToId), eq(3.seconds)) .wasInvoked(exactly = once) } diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeDeletedHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeDeletedHandlerTest.kt index 9ae28b1835e..400e3034a0a 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeDeletedHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeDeletedHandlerTest.kt @@ -41,7 +41,8 @@ class CodeDeletedHandlerTest { val event = Event.Conversation.CodeDeleted( conversationId = ConversationId("conversationId", "domain"), id = "event-id", - transient = false + transient = false, + live = false ) handler.handle(event) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeUpdateHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeUpdateHandlerTest.kt index c40c6e37a7f..9c213574329 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeUpdateHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/CodeUpdateHandlerTest.kt @@ -45,7 +45,8 @@ class CodeUpdateHandlerTest { code = "code", key = "key", id = "event-id", - transient = false + transient = false, + live = false ) handler.handle(event) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MLSWelcomeEventHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MLSWelcomeEventHandlerTest.kt index b6a66f5ebfa..27095c69945 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MLSWelcomeEventHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MLSWelcomeEventHandlerTest.kt @@ -242,6 +242,7 @@ class MLSWelcomeEventHandlerTest { "eventId", CONVERSATION_ID, false, + false, TestUser.USER_ID, WELCOME.encodeBase64(), timestampIso = "2022-03-30T15:36:00.000Z" diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MemberLeaveEventHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MemberLeaveEventHandlerTest.kt index d5be45c2828..58682933b92 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MemberLeaveEventHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/MemberLeaveEventHandlerTest.kt @@ -129,6 +129,7 @@ class MemberLeaveEventHandlerTest { id = "id", conversationId = conversationId, transient = false, + live = false, removedBy = userId, removedList = listOf(userId), timestampIso = "timestampIso" diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/NewConversationEventHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/NewConversationEventHandlerTest.kt index 5e4b0ab9cdc..6360cfd7bc7 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/NewConversationEventHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/NewConversationEventHandlerTest.kt @@ -62,6 +62,7 @@ class NewConversationEventHandlerTest { id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false, timestampIso = "timestamp", conversation = TestConversation.CONVERSATION_RESPONSE, senderUserId = TestUser.SELF.id @@ -103,7 +104,8 @@ class NewConversationEventHandlerTest { val event = Event.Conversation.NewConversation( id = "eventId", conversationId = TestConversation.ID, - false, + transient =false, + live = false, timestampIso = "timestamp", conversation = TestConversation.CONVERSATION_RESPONSE, senderUserId = TestUser.SELF.id @@ -142,6 +144,7 @@ class NewConversationEventHandlerTest { id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false, timestampIso = "timestamp", conversation = TestConversation.CONVERSATION_RESPONSE.copy( creator = "creatorId@creatorDomain", @@ -202,6 +205,7 @@ class NewConversationEventHandlerTest { id = "eventId", conversationId = TestConversation.ID, transient = false, + live = false, timestampIso = "timestamp", conversation = TestConversation.CONVERSATION_RESPONSE.copy( creator = "creatorId@creatorDomain", diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/mls/OneOnOneResolverArrangement.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/mls/OneOnOneResolverArrangement.kt index 87e368402c0..21fdbe02e99 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/mls/OneOnOneResolverArrangement.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/util/arrangement/mls/OneOnOneResolverArrangement.kt @@ -25,10 +25,13 @@ import io.mockative.Mock import io.mockative.any import io.mockative.given import io.mockative.mock +import kotlinx.coroutines.Job interface OneOnOneResolverArrangement { val oneOnOneResolver: OneOnOneResolver + + fun withScheduleResolveOneOnOneConversationWithUserId() fun withResolveOneOnOneConversationWithUserIdReturning(result: Either) fun withResolveOneOnOneConversationWithUserReturning(result: Either) fun withResolveAllOneOnOneConversationsReturning(result: Either) @@ -39,6 +42,13 @@ class OneOnOneResolverArrangementImpl : OneOnOneResolverArrangement { @Mock override val oneOnOneResolver = mock(OneOnOneResolver::class) + override fun withScheduleResolveOneOnOneConversationWithUserId() { + given(oneOnOneResolver) + .suspendFunction(oneOnOneResolver::scheduleResolveOneOnOneConversationWithUserId) + .whenInvokedWith(any(), any()) + .thenReturn(Job()) + } + override fun withResolveOneOnOneConversationWithUserIdReturning(result: Either) { given(oneOnOneResolver) .suspendFunction(oneOnOneResolver::resolveOneOnOneConversationWithUserId)