diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/asset/AssetMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/asset/AssetMapper.kt index 1ff82991855..7ce23d1ccc8 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/asset/AssetMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/asset/AssetMapper.kt @@ -38,6 +38,7 @@ import com.wire.kalium.persistence.dao.asset.AssetMessageEntity import com.wire.kalium.persistence.dao.message.MessageEntity import com.wire.kalium.persistence.dao.message.MessageEntityContent import com.wire.kalium.protobuf.messages.Asset +import com.wire.kalium.protobuf.messages.LegalHoldStatus import com.wire.kalium.util.DateTimeUtil import com.wire.kalium.util.KaliumDispatcher import com.wire.kalium.util.KaliumDispatcherImpl @@ -52,7 +53,11 @@ interface AssetMapper { fun fromUserAssetToDaoModel(assetId: String, assetDomain: String?, dataPath: Path, dataSize: Long): AssetEntity fun fromAssetEntityToAssetContent(assetContentEntity: MessageEntityContent.Asset): AssetContent fun fromProtoAssetMessageToAssetContent(protoAssetMessage: Asset): AssetContent - fun fromAssetContentToProtoAssetMessage(messageContent: MessageContent.Asset, expectsReadConfirmation: Boolean): Asset + fun fromAssetContentToProtoAssetMessage( + messageContent: MessageContent.Asset, + expectsReadConfirmation: Boolean, + legalHoldStatus: LegalHoldStatus + ): Asset } class AssetMapperImpl( @@ -196,8 +201,11 @@ class AssetMapperImpl( } } - override fun fromAssetContentToProtoAssetMessage(messageContent: MessageContent.Asset, expectsReadConfirmation: Boolean): Asset = - with(messageContent.value) { + override fun fromAssetContentToProtoAssetMessage( + messageContent: MessageContent.Asset, + expectsReadConfirmation: Boolean, + legalHoldStatus: LegalHoldStatus + ): Asset = with(messageContent.value) { Asset( original = Asset.Original( mimeType = mimeType, @@ -231,7 +239,8 @@ class AssetMapperImpl( encryption = encryptionAlgorithmMapper.toProtoBufModel(remoteData.encryptionAlgorithm) ) ), - expectsReadConfirmation = expectsReadConfirmation + expectsReadConfirmation = expectsReadConfirmation, + legalHoldStatus = legalHoldStatus ) } } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/Conversation.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/Conversation.kt index 5af639df12f..bf4bf6f3cf2 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/Conversation.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/conversation/Conversation.kt @@ -194,7 +194,7 @@ data class Conversation( enum class TypingIndicatorMode { STARTED, STOPPED } enum class VerificationStatus { VERIFIED, NOT_VERIFIED, DEGRADED } - enum class LegalHoldStatus { ENABLED, DISABLED, DEGRADED } + enum class LegalHoldStatus { ENABLED, DISABLED, DEGRADED, UNKNOWN } @Suppress("MagicNumber") enum class CipherSuite(val tag: Int) { diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContent.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContent.kt index f213aa38431..56d10fd8c77 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContent.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContent.kt @@ -18,6 +18,7 @@ package com.wire.kalium.logic.data.message +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.message.ProtoContent.ExternalMessageInstructions import com.wire.kalium.persistence.dao.conversation.ConversationEntity.ProtocolInfo.Proteus import com.wire.kalium.protobuf.messages.GenericMessage @@ -38,6 +39,7 @@ sealed interface ProtoContent { override val messageUid: String, val messageContent: MessageContent.FromProto, val expectsReadConfirmation: Boolean, + val legalHoldStatus: Conversation.LegalHoldStatus, val expiresAfterMillis: Long? = null ) : ProtoContent diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapper.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapper.kt index 42aae27ebbb..6045a3c5eca 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapper.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapper.kt @@ -20,6 +20,7 @@ package com.wire.kalium.logic.data.message import com.wire.kalium.logger.obfuscateId import com.wire.kalium.logic.data.asset.AssetMapper +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.id.IdMapper import com.wire.kalium.logic.data.message.mention.MessageMentionMapper @@ -43,6 +44,7 @@ import com.wire.kalium.protobuf.messages.External import com.wire.kalium.protobuf.messages.GenericMessage import com.wire.kalium.protobuf.messages.Knock import com.wire.kalium.protobuf.messages.LastRead +import com.wire.kalium.protobuf.messages.LegalHoldStatus import com.wire.kalium.protobuf.messages.MessageDelete import com.wire.kalium.protobuf.messages.MessageEdit import com.wire.kalium.protobuf.messages.MessageHide @@ -84,12 +86,14 @@ class ProtoContentMapperImpl( mapEphemeralContent( protoContent.messageContent, protoContent.expiresAfterMillis, - protoContent.expectsReadConfirmation + protoContent.expectsReadConfirmation, + protoContent.legalHoldStatus ) } else { mapNormalContent( protoContent.messageContent, - protoContent.expectsReadConfirmation + protoContent.expectsReadConfirmation, + protoContent.legalHoldStatus ) } } @@ -97,13 +101,14 @@ class ProtoContentMapperImpl( @Suppress("ComplexMethod") private fun mapNormalContent( readableContent: MessageContent.FromProto, - expectsReadConfirmation: Boolean + expectsReadConfirmation: Boolean, + legalHoldStatus: Conversation.LegalHoldStatus ): GenericMessage.Content { return when (readableContent) { - is MessageContent.Text -> packText(readableContent, expectsReadConfirmation) + is MessageContent.Text -> packText(readableContent, expectsReadConfirmation, legalHoldStatus) is MessageContent.Calling -> packCalling(readableContent) - is MessageContent.Asset -> packAsset(readableContent, expectsReadConfirmation) - is MessageContent.Knock -> GenericMessage.Content.Knock(Knock(hotKnock = readableContent.hotKnock)) + is MessageContent.Asset -> packAsset(readableContent, expectsReadConfirmation, legalHoldStatus) + is MessageContent.Knock -> packKnock(readableContent, legalHoldStatus) is MessageContent.DeleteMessage -> GenericMessage.Content.Deleted(MessageDelete(messageId = readableContent.messageId)) is MessageContent.DeleteForMe -> packHidden(readableContent) is MessageContent.Availability -> GenericMessage.Content.Availability( @@ -114,7 +119,7 @@ class ProtoContentMapperImpl( is MessageContent.LastRead -> packLastRead(readableContent) is MessageContent.Cleared -> packCleared(readableContent) - is MessageContent.Reaction -> packReaction(readableContent) + is MessageContent.Reaction -> packReaction(readableContent, legalHoldStatus) is MessageContent.Receipt -> packReceipt(readableContent) is MessageContent.ClientAction -> packClientAction() is MessageContent.TextEdited -> packEdited(readableContent) @@ -123,7 +128,7 @@ class ProtoContentMapperImpl( "Unexpected message content type: ${readableContent.getType()}" ) - is MessageContent.Composite -> packComposite(readableContent, expectsReadConfirmation) + is MessageContent.Composite -> packComposite(readableContent, expectsReadConfirmation, legalHoldStatus) is MessageContent.ButtonAction -> packButtonAction(readableContent) is MessageContent.ButtonActionConfirmation -> TODO() @@ -142,12 +147,13 @@ class ProtoContentMapperImpl( private fun packComposite( readableContent: MessageContent.Composite, - expectsReadConfirmation: Boolean + expectsReadConfirmation: Boolean, + legalHoldStatus: Conversation.LegalHoldStatus ): GenericMessage.Content.Composite { val items: MutableList = mutableListOf() readableContent.textContent?.let { - val text = packText(it, expectsReadConfirmation) + val text = packText(it, expectsReadConfirmation, legalHoldStatus) Composite.Item.Content.Text(text.value).also { items.add(Composite.Item(it)) } @@ -159,7 +165,8 @@ class ProtoContentMapperImpl( val composite = GenericMessage.Content.Composite( Composite( items = items, - expectsReadConfirmation = expectsReadConfirmation + expectsReadConfirmation = expectsReadConfirmation, + legalHoldStatus = toProtoLegalHoldStatus(legalHoldStatus) ) ) return composite @@ -168,25 +175,26 @@ class ProtoContentMapperImpl( private fun mapEphemeralContent( readableContent: MessageContent.FromProto, expireAfterMillis: Long, - expectsReadConfirmation: Boolean + expectsReadConfirmation: Boolean, + legalHoldStatus: Conversation.LegalHoldStatus ): GenericMessage.Content { val ephemeralContent = when (readableContent) { is MessageContent.Text -> { - val text = packText(readableContent, expectsReadConfirmation) + val text = packText(readableContent, expectsReadConfirmation, legalHoldStatus) Ephemeral.Content.Text( text.value ) } is MessageContent.Asset -> { - val asset = packAsset(readableContent, expectsReadConfirmation) + val asset = packAsset(readableContent, expectsReadConfirmation, legalHoldStatus) Ephemeral.Content.Asset( asset.value ) } is MessageContent.Knock -> { - val knock = GenericMessage.Content.Knock(Knock(hotKnock = readableContent.hotKnock)) + val knock = packKnock(readableContent, legalHoldStatus) Ephemeral.Content.Knock( knock.value ) @@ -236,6 +244,7 @@ class ProtoContentMapperImpl( is GenericMessage.Content.Asset -> content.value.expectsReadConfirmation ?: false else -> false } + val legalHoldStatus = getLegalHoldStatusFromProtoContent(genericMessage) val expiresAfterMillis: Long? = when (val content = genericMessage.content) { is GenericMessage.Content.Ephemeral -> content.value.expireAfterMillis else -> null @@ -244,11 +253,32 @@ class ProtoContentMapperImpl( messageUid = genericMessage.messageId, messageContent = getReadableContent(genericMessage, encodedContent), expectsReadConfirmation = expectsReadConfirmation, + legalHoldStatus = fromProtoLegalHoldStatus(legalHoldStatus), expiresAfterMillis = expiresAfterMillis ) } } + private fun getLegalHoldStatusFromProtoContent(genericMessage: GenericMessage) = + when (val content = genericMessage.content) { + is GenericMessage.Content.Text -> content.value.legalHoldStatus + is GenericMessage.Content.Asset -> content.value.legalHoldStatus + is GenericMessage.Content.Knock -> content.value.legalHoldStatus + is GenericMessage.Content.Location -> content.value.legalHoldStatus + is GenericMessage.Content.Reaction -> content.value.legalHoldStatus + is GenericMessage.Content.Composite -> content.value.legalHoldStatus + else -> null + } + + private fun fromProtoLegalHoldStatus(legalHoldStatus: LegalHoldStatus?): Conversation.LegalHoldStatus = + legalHoldStatus?.let { + when (legalHoldStatus) { + is LegalHoldStatus.ENABLED -> Conversation.LegalHoldStatus.ENABLED + is LegalHoldStatus.DISABLED -> Conversation.LegalHoldStatus.DISABLED + else -> Conversation.LegalHoldStatus.UNKNOWN + } + } ?: run { Conversation.LegalHoldStatus.UNKNOWN } + @Suppress("ComplexMethod", "LongMethod") private fun getReadableContent( genericMessage: GenericMessage, @@ -335,12 +365,20 @@ class ProtoContentMapperImpl( ) } ?: MessageContent.Ignored - private fun packReaction(readableContent: MessageContent.Reaction) = - GenericMessage.Content.Reaction(Reaction(emoji = readableContent.emojiSet.map { it.trim() }.filter { it.isNotBlank() } - .joinToString(separator = ",") { it }, - messageId = readableContent.messageId - ) + private fun packReaction( + readableContent: MessageContent.Reaction, + legalHoldStatus: Conversation.LegalHoldStatus + ): GenericMessage.Content.Reaction { + val protoLegalHoldStatus = toProtoLegalHoldStatus(legalHoldStatus) + return GenericMessage.Content.Reaction( + Reaction( + emoji = readableContent.emojiSet.map { it.trim() }.filter { it.isNotBlank() } + .joinToString(separator = ",") { it }, + messageId = readableContent.messageId, + legalHoldStatus = protoLegalHoldStatus + ) ) + } private fun packClientAction() = GenericMessage.Content.ClientAction(ClientAction.RESET_SESSION) @@ -461,17 +499,30 @@ class ProtoContentMapperImpl( time = Instant.fromEpochMilliseconds(protoContent.value.clearedTimestamp) ) - private fun packText(readableContent: MessageContent.Text, expectsReadConfirmation: Boolean): GenericMessage.Content.Text { + private fun toProtoLegalHoldStatus(legalHoldStatus: Conversation.LegalHoldStatus): LegalHoldStatus = + when (legalHoldStatus) { + Conversation.LegalHoldStatus.ENABLED -> LegalHoldStatus.ENABLED + Conversation.LegalHoldStatus.DISABLED -> LegalHoldStatus.DISABLED + else -> LegalHoldStatus.UNKNOWN + } + + private fun packText( + readableContent: MessageContent.Text, + expectsReadConfirmation: Boolean, + legalHoldStatus: Conversation.LegalHoldStatus + ): GenericMessage.Content.Text { val mentions = readableContent.mentions.map { messageMentionMapper.fromModelToProto(it) } val quote = readableContent.quotedMessageReference?.let { Quote(it.quotedMessageId, it.quotedMessageSha256?.let { hash -> ByteArr(hash) }) } + val protoLegalHoldStatus = toProtoLegalHoldStatus(legalHoldStatus) return GenericMessage.Content.Text( Text( content = readableContent.value, mentions = mentions, quote = quote, - expectsReadConfirmation = expectsReadConfirmation + expectsReadConfirmation = expectsReadConfirmation, + legalHoldStatus = protoLegalHoldStatus ) ) } @@ -509,11 +560,30 @@ class ProtoContentMapperImpl( } } - private fun packAsset(readableContent: MessageContent.Asset, expectsReadConfirmation: Boolean): GenericMessage.Content.Asset { + private fun packKnock( + readableContent: MessageContent.Knock, + legalHoldStatus: Conversation.LegalHoldStatus + ): GenericMessage.Content.Knock { + val protoLegalHoldStatus = toProtoLegalHoldStatus(legalHoldStatus) + return GenericMessage.Content.Knock( + Knock( + hotKnock = readableContent.hotKnock, + legalHoldStatus = protoLegalHoldStatus + ) + ) + } + + private fun packAsset( + readableContent: MessageContent.Asset, + expectsReadConfirmation: Boolean, + legalHoldStatus: Conversation.LegalHoldStatus + ): GenericMessage.Content.Asset { + val protoLegalHoldStatus = toProtoLegalHoldStatus(legalHoldStatus) return GenericMessage.Content.Asset( asset = assetMapper.fromAssetContentToProtoAssetMessage( readableContent, - expectsReadConfirmation + expectsReadConfirmation, + protoLegalHoldStatus ) ) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/web/WebMappers.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/web/WebMappers.kt index a512a25dd8f..d13666fef45 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/web/WebMappers.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/data/web/WebMappers.kt @@ -52,7 +52,9 @@ fun WebEventContent.toMigratedMessage(selfUserDomain: String): MigratedMessage? MessageContent.Text( data.text, ), - data.expectsReadConfirmation ?: false + data.expectsReadConfirmation ?: false, + legalHoldStatus = if (data.legalHoldStatus == 2) Conversation.LegalHoldStatus.ENABLED + else Conversation.LegalHoldStatus.DISABLED ), encryptedProto = null, null, @@ -110,7 +112,9 @@ fun WebEventContent.toMigratedMessage(selfUserDomain: String): MigratedMessage? downloadStatus = Message.DownloadStatus.NOT_DOWNLOADED ), ), - data.expectsReadConfirmation + data.expectsReadConfirmation, + legalHoldStatus = if (data.legalHoldStatus == 2) Conversation.LegalHoldStatus.ENABLED + else Conversation.LegalHoldStatus.DISABLED ), encryptedProto = null, null, @@ -172,7 +176,7 @@ fun WebConversationContent.toConversation(selfUserId: UserId): Conversation? { archivedDateTime = conversationArchivedTimestamp, mlsVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, proteusVerificationStatus = Conversation.VerificationStatus.NOT_VERIFIED, - legalHoldStatus = if (legalHoldStatus == 1) Conversation.LegalHoldStatus.ENABLED + legalHoldStatus = if (legalHoldStatus == 2) Conversation.LegalHoldStatus.ENABLED else Conversation.LegalHoldStatus.DISABLED ) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MLSMessageCreator.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MLSMessageCreator.kt index f289533e237..25064d3aa07 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MLSMessageCreator.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MLSMessageCreator.kt @@ -21,6 +21,7 @@ package com.wire.kalium.logic.feature.message import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.data.client.MLSClientProvider +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.GroupID import com.wire.kalium.logic.data.id.IdMapper import com.wire.kalium.logic.data.message.Message @@ -59,11 +60,18 @@ class MLSMessageCreatorImpl( else -> false } + // TODO(legalhold) - Get correct legal hold status + val legalHoldStatus = when (message) { + is Message.Regular -> Conversation.LegalHoldStatus.DISABLED + else -> Conversation.LegalHoldStatus.DISABLED + } + val content = protoContentMapper.encodeToProtobuf( protoContent = ProtoContent.Readable( messageUid = message.id, messageContent = message.content, - expectsReadConfirmation = expectsReadConfirmation + expectsReadConfirmation = expectsReadConfirmation, + legalHoldStatus = legalHoldStatus ) ) wrapMLSRequest { MLSMessageApi.Message(mlsClient.encryptMessage(idMapper.toCryptoModel(groupId), content.data)) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageEnvelopeCreator.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageEnvelopeCreator.kt index dba290a00c0..d4caf93b72a 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageEnvelopeCreator.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/feature/message/MessageEnvelopeCreator.kt @@ -43,6 +43,7 @@ import com.wire.kalium.logic.data.message.RecipientEntry import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.di.MapperProvider import com.wire.kalium.logic.data.client.ProteusClientProvider +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.functional.flatMap import com.wire.kalium.logic.kaliumLogger @@ -80,11 +81,18 @@ class MessageEnvelopeCreatorImpl( else -> false } + // TODO(legalhold) - Get correct legal hold status + val legalHoldStatus = when (message) { + is Message.Regular -> Conversation.LegalHoldStatus.DISABLED + else -> Conversation.LegalHoldStatus.DISABLED + } + val actualMessageContent = ProtoContent.Readable( messageUid = message.id, messageContent = message.content, expectsReadConfirmation = expectsReadConfirmation, - expiresAfterMillis = message.expirationData?.expireAfter?.inWholeMilliseconds + expiresAfterMillis = message.expirationData?.expireAfter?.inWholeMilliseconds, + legalHoldStatus = legalHoldStatus ) return createEnvelope(actualMessageContent, recipients, senderClientId) @@ -96,7 +104,11 @@ class MessageEnvelopeCreatorImpl( ): Either { val senderClientId = message.senderClientId val expectsReadConfirmation = false - val actualMessageContent = ProtoContent.Readable(message.id, message.content, expectsReadConfirmation) + + // TODO - Get legal hold status + val legalHoldStatus = Conversation.LegalHoldStatus.UNKNOWN + + val actualMessageContent = ProtoContent.Readable(message.id, message.content, expectsReadConfirmation, legalHoldStatus) return createEnvelope(actualMessageContent, recipients, senderClientId) } diff --git a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandler.kt b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandler.kt index a67df1e6ac7..66c5aefeeae 100644 --- a/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandler.kt +++ b/logic/src/commonMain/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandler.kt @@ -83,6 +83,7 @@ internal class NewMessageEventHandlerImpl( }.onSuccess { if (it is MessageUnpackResult.ApplicationMessage) { handleSuccessfulResult(it) + // TODO(legalhold): update legal hold status in DB onMessageInserted(it) } kaliumLogger diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/asset/AssetMapperTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/asset/AssetMapperTest.kt index 62deef5e627..35f68328f55 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/asset/AssetMapperTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/asset/AssetMapperTest.kt @@ -23,6 +23,7 @@ import com.wire.kalium.logic.data.message.Message import com.wire.kalium.logic.data.message.MessageContent import com.wire.kalium.logic.data.message.MessageEncryptionAlgorithm import com.wire.kalium.protobuf.messages.Asset +import com.wire.kalium.protobuf.messages.LegalHoldStatus import com.wire.kalium.util.KaliumDispatcher import io.mockative.Mock import io.mockative.classOf @@ -65,7 +66,8 @@ class AssetMapperTest { // when val result = mapper.fromAssetContentToProtoAssetMessage( messageContent = messageContent, - expectsReadConfirmation = true + expectsReadConfirmation = true, + legalHoldStatus = LegalHoldStatus.DISABLED ) // then diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapperTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapperTest.kt index 7a8c248594e..538d5fbc946 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapperTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/ProtoContentMapperTest.kt @@ -19,6 +19,7 @@ package com.wire.kalium.logic.data.message import com.wire.kalium.cryptography.utils.generateRandomAES256Key +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.IdMapper import com.wire.kalium.logic.data.id.IdMapperImpl import com.wire.kalium.logic.data.message.receipt.ReceiptType @@ -51,7 +52,12 @@ class ProtoContentMapperTest { @Test fun givenTextContent_whenMappingToProtoDataAndBack_thenTheContentsShouldMatchTheOriginal() { val messageContent = MessageContent.Text("Hello") - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false) + val protoContent = ProtoContent.Readable( + TEST_MESSAGE_UUID, + messageContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -67,7 +73,12 @@ class ProtoContentMapperTest { quotedMessageId = "quotedMessageId", quotedMessageSha256 = null, true ) ) - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false) + val protoContent = ProtoContent.Readable( + TEST_MESSAGE_UUID, + messageContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -116,7 +127,12 @@ class ProtoContentMapperTest { downloadStatus = Message.DownloadStatus.NOT_DOWNLOADED ) ) - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false) + val protoContent = ProtoContent.Readable( + TEST_MESSAGE_UUID, + messageContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -127,7 +143,12 @@ class ProtoContentMapperTest { @Test fun givenCallingContent_whenMappingToProtoDataAndBack_thenTheContentsShouldMatchTheOriginal() { val callingContent = MessageContent.Calling("Calling") - val protoContent = ProtoContent.Readable(TEST_CALLING_UUID, callingContent, false) + val protoContent = ProtoContent.Readable( + TEST_CALLING_UUID, + callingContent, + false, + Conversation.LegalHoldStatus.UNKNOWN + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -138,7 +159,12 @@ class ProtoContentMapperTest { @Test fun givenDeleteMessageContent_whenMappingToProtoDataAndBack_thenTheContentsShouldMatchTheOriginal() { val messageContent = MessageContent.DeleteMessage(TEST_MESSAGE_UUID) - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false) + val protoContent = ProtoContent.Readable( + TEST_MESSAGE_UUID, + messageContent, + false, + Conversation.LegalHoldStatus.UNKNOWN + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -151,7 +177,12 @@ class ProtoContentMapperTest { val messageContent = MessageContent.DeleteForMe( TEST_MESSAGE_UUID, TEST_CONVERSATION_ID ) - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false) + val protoContent = ProtoContent.Readable( + TEST_MESSAGE_UUID, + messageContent, + false, + Conversation.LegalHoldStatus.UNKNOWN + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -197,7 +228,70 @@ class ProtoContentMapperTest { listOf("messageI", "messageII", "messageIII") ) - val originalContent = ProtoContent.Readable(messageUid, content, false) + val originalContent = ProtoContent.Readable( + messageUid, + content, + false, + Conversation.LegalHoldStatus.UNKNOWN + ) + val encoded = protoContentMapper.encodeToProtobuf(originalContent) + val decoded = protoContentMapper.decodeFromProtobuf(encoded) + + assertEquals(originalContent, decoded) + } + @Test + fun givenReactionContent_whenMappingToProtoAndBack_thenShouldMaintainSameValues() { + val messageUid = "uid" + val emojis = setOf("👍", "👎") + val content = MessageContent.Reaction( + messageUid, + emojis + ) + + val originalContent = ProtoContent.Readable( + messageUid, + content, + false, + Conversation.LegalHoldStatus.ENABLED + ) + val encoded = protoContentMapper.encodeToProtobuf(originalContent) + val decoded = protoContentMapper.decodeFromProtobuf(encoded) + + assertEquals(originalContent, decoded) + } + + @Test + fun givenKnockContent_whenMappingToProtoAndBack_thenShouldMaintainSameValues() { + val messageUid = "uid" + val content = MessageContent.Knock(true) + + val originalContent = ProtoContent.Readable( + messageUid, + content, + false, + Conversation.LegalHoldStatus.DISABLED + ) + val encoded = protoContentMapper.encodeToProtobuf(originalContent) + val decoded = protoContentMapper.decodeFromProtobuf(encoded) + + assertEquals(originalContent, decoded) + } + @Test + fun givenCompositeContent_whenMappingToProtoAndBack_thenShouldMaintainSameValues() { + val messageUid = "uid" + val textContent = MessageContent.Text("Hello") + val buttons = listOf( + MessageContent.Composite.Button("button1", "button1", false), + MessageContent.Composite.Button("button2", "button2", false) + ) + val content = MessageContent.Composite(textContent, buttons) + + val originalContent = ProtoContent.Readable( + messageUid, + content, + false, + Conversation.LegalHoldStatus.ENABLED + ) val encoded = protoContentMapper.encodeToProtobuf(originalContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -212,7 +306,12 @@ class ProtoContentMapperTest { listOf("messageI", "messageII", "messageIII") ) - val originalContent = ProtoContent.Readable(messageUid, content, false) + val originalContent = ProtoContent.Readable( + messageUid, + content, + false, + Conversation.LegalHoldStatus.UNKNOWN + ) val encoded = protoContentMapper.encodeToProtobuf(originalContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) @@ -260,7 +359,8 @@ class ProtoContentMapperTest { messageUid = TEST_MESSAGE_UUID, messageContent = messageContent, expectsReadConfirmation = false, - expiresAfterMillis = expiresAfterMillis + expiresAfterMillis = expiresAfterMillis, + legalHoldStatus = Conversation.LegalHoldStatus.UNKNOWN ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) @@ -293,7 +393,13 @@ class ProtoContentMapperTest { ) ) val expiresAfterMillis = 1000L - val protoContent = ProtoContent.Readable(TEST_MESSAGE_UUID, messageContent, false, expiresAfterMillis = expiresAfterMillis) + val protoContent = ProtoContent.Readable( + messageUid = TEST_MESSAGE_UUID, + messageContent = messageContent, + expectsReadConfirmation = false, + legalHoldStatus = Conversation.LegalHoldStatus.UNKNOWN, + expiresAfterMillis = expiresAfterMillis + ) val encoded = protoContentMapper.encodeToProtobuf(protoContent) val decoded = protoContentMapper.decodeFromProtobuf(encoded) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/protobuf/ProtoContentReactionMapperTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/protobuf/ProtoContentReactionMapperTest.kt index 0661c63ac52..1a018af9bf8 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/protobuf/ProtoContentReactionMapperTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/data/message/protobuf/ProtoContentReactionMapperTest.kt @@ -18,6 +18,7 @@ package com.wire.kalium.logic.data.message.protobuf +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.message.MessageContent import com.wire.kalium.logic.data.message.PlainMessageBlob import com.wire.kalium.logic.data.message.ProtoContent @@ -161,7 +162,8 @@ class ProtoContentReactionMapperTest { val protoContent = ProtoContent.Readable( "Whatever", MessageContent.Reaction("referencedMessageId", emojiSet = emojiSet), - false + false, + Conversation.LegalHoldStatus.DISABLED ) val result = protoContentMapper.encodeToProtobuf(protoContent) @@ -176,7 +178,8 @@ class ProtoContentReactionMapperTest { val protoContent = ProtoContent.Readable( "Whatever", MessageContent.Reaction("referencedMessageId", emojiSet = emojiSet), - false + false, + Conversation.LegalHoldStatus.DISABLED ) val result = protoContentMapper.encodeToProtobuf(protoContent) @@ -191,7 +194,8 @@ class ProtoContentReactionMapperTest { val protoContent = ProtoContent.Readable( "messageId", MessageContent.Reaction(referencedMessageId, emojiSet = setOf()), - false + false, + Conversation.LegalHoldStatus.DISABLED ) val result = protoContentMapper.encodeToProtobuf(protoContent) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt index 2a45f7d6f07..3bdfc116591 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ApplicationMessageHandlerTest.kt @@ -22,6 +22,7 @@ import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.StorageFailure import com.wire.kalium.logic.configuration.FileSharingStatus import com.wire.kalium.logic.configuration.UserConfigRepository +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.message.AssetContent import com.wire.kalium.logic.data.message.Message import com.wire.kalium.logic.data.message.MessageContent @@ -71,7 +72,12 @@ class ApplicationMessageHandlerTest { Message.UploadStatus.NOT_UPLOADED, Message.DownloadStatus.NOT_DOWNLOADED ) ) - val protoContent = ProtoContent.Readable(messageId, validImageContent, false) + val protoContent = ProtoContent.Readable( + messageId, + validImageContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) val coreFailure = StorageFailure.DataNotFound val (arrangement, messageHandler) = Arrangement() .withPersistingMessageReturning(Either.Right(Unit)) @@ -107,7 +113,12 @@ class ApplicationMessageHandlerTest { referencedMessageId = messageId, buttonId = "buttonId" ) - val protoContent = ProtoContent.Readable(messageId, validImageContent, false) + val protoContent = ProtoContent.Readable( + messageId, + validImageContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) val (arrangement, messageHandler) = Arrangement() .withPersistingMessageReturning(Either.Right(Unit)) .withButtonActionConfirmation(Either.Right(Unit)) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandlerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandlerTest.kt index 12ff3697e30..c4be76400c2 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandlerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/NewMessageEventHandlerTest.kt @@ -23,6 +23,7 @@ import com.wire.kalium.logic.CoreFailure import com.wire.kalium.logic.MLSFailure import com.wire.kalium.logic.ProteusFailure import com.wire.kalium.logic.data.conversation.ClientId +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.data.id.ConversationId import com.wire.kalium.logic.data.message.MessageContent import com.wire.kalium.logic.data.message.ProtoContent @@ -159,6 +160,7 @@ class NewMessageEventHandlerTest { value = "messageContent" ), expectsReadConfirmation = false, + legalHoldStatus = Conversation.LegalHoldStatus.DISABLED, expiresAfterMillis = 123L ) ) @@ -204,6 +206,7 @@ class NewMessageEventHandlerTest { value = "messageContent" ), expectsReadConfirmation = false, + legalHoldStatus = Conversation.LegalHoldStatus.DISABLED, expiresAfterMillis = 123L ) ) @@ -249,6 +252,7 @@ class NewMessageEventHandlerTest { value = "messageContent" ), expectsReadConfirmation = false, + legalHoldStatus = Conversation.LegalHoldStatus.DISABLED, expiresAfterMillis = null ) ) diff --git a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ProteusMessageUnpackerTest.kt b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ProteusMessageUnpackerTest.kt index f151581ab11..6e2b0bbc6f7 100644 --- a/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ProteusMessageUnpackerTest.kt +++ b/logic/src/commonTest/kotlin/com/wire/kalium/logic/sync/receiver/conversation/message/ProteusMessageUnpackerTest.kt @@ -31,6 +31,7 @@ import com.wire.kalium.logic.data.message.ProtoContent import com.wire.kalium.logic.data.message.ProtoContentMapper import com.wire.kalium.logic.data.user.UserId import com.wire.kalium.logic.data.client.ProteusClientProvider +import com.wire.kalium.logic.data.conversation.Conversation import com.wire.kalium.logic.framework.TestEvent import com.wire.kalium.logic.functional.Either import com.wire.kalium.logic.util.Base64 @@ -60,8 +61,12 @@ class ProteusMessageUnpackerTest { fun givenNewMessageEvent_whenUnpacking_shouldAskProteusClientForDecryption() = runTest { val (arrangement, proteusUnpacker) = Arrangement() .withProteusClientDecryptingByteArray(decryptedData = byteArrayOf()) - .withProtoContentMapperReturning(any(), ProtoContent.Readable("uuid", MessageContent.Unknown(), false)) - .arrange() + .withProtoContentMapperReturning(any(), ProtoContent.Readable( + "uuid", + MessageContent.Unknown(), + false, + Conversation.LegalHoldStatus.DISABLED + )).arrange() val encodedEncryptedContent = Base64.encodeToBase64("Hello".encodeToByteArray()) val messageEvent = TestEvent.newMessageEvent(encodedEncryptedContent.decodeToString()) @@ -104,7 +109,12 @@ class ProteusMessageUnpackerTest { .withProtoContentMapperReturning(matching { it.data.contentEquals(emptyArray) }, externalInstructions) .withProtoContentMapperReturning( matching { it.data.contentEquals(protobufExternalContent.encodeToByteArray()) }, - ProtoContent.Readable(messageUid, decryptedExternalContent, false) + ProtoContent.Readable( + messageUid, + decryptedExternalContent, + false, + Conversation.LegalHoldStatus.DISABLED + ) ).arrange() val messageEvent = TestEvent.newMessageEvent(