From 7aec1c4590e5effd7f1076e86d868bd53bc25c50 Mon Sep 17 00:00:00 2001 From: Mojtaba Chenani Date: Fri, 20 Dec 2024 10:35:31 +0100 Subject: [PATCH] add tests to list_conversations function --- bindings_ffi/src/mls.rs | 91 ++++++++++++++++++++++++++++++++++++-- xmtp_mls/src/client.rs | 34 +++++++++----- xmtp_mls/src/groups/mod.rs | 2 - 3 files changed, 110 insertions(+), 17 deletions(-) diff --git a/bindings_ffi/src/mls.rs b/bindings_ffi/src/mls.rs index a4082e5d8..5283116bd 100644 --- a/bindings_ffi/src/mls.rs +++ b/bindings_ffi/src/mls.rs @@ -967,13 +967,19 @@ impl FfiConversations { pub async fn list_conversations( &self, - opts: FfiListConversationsOptions, ) -> Result>, GenericError> { let inner = self.inner_client.as_ref(); let convo_list: Vec> = inner .list_conversations()? .into_iter() - .map(|group| Arc::new(group.into())) + .filter_map(|(mls_group, stored_message)| { + let last_message = stored_message.map(|msg| msg.into()); + + Some(Arc::new(FfiConversationListItem { + conversation: mls_group.into(), + last_message, + })) + }) .collect(); Ok(convo_list) @@ -1158,7 +1164,7 @@ pub struct FfiConversation { #[derive(uniffi::Object)] pub struct FfiConversationListItem { conversation: FfiConversation, - last_message: FfiMessage + last_message: Option } impl From> for FfiConversation { @@ -2686,6 +2692,85 @@ mod tests { assert!(stream_messages.is_closed()); } + #[tokio::test(flavor = "multi_thread", worker_threads = 5)] + async fn test_list_conversations_last_message() { + // Step 1: Setup test client Alix and bo + let alix = new_test_client().await; + let bo = new_test_client().await; + + // Step 2: Create a group and add messages + let alix_conversations = alix.conversations(); + + // Create a group + let group = alix_conversations + .create_group( + vec![bo.account_address.clone()], + FfiCreateGroupOptions::default(), + ) + .await + .unwrap(); + + // Add messages to the group + group.send("First message".as_bytes().to_vec()).await.unwrap(); + group.send("Second message".as_bytes().to_vec()).await.unwrap(); + + // Step 3: Synchronize conversations + alix_conversations.sync_all_conversations(None).await.unwrap(); + + // Step 4: List conversations and verify + let conversations = alix_conversations + .list_conversations() + .await + .unwrap(); + + // Ensure the group is included + assert_eq!(conversations.len(), 1, "Alix should have exactly 1 group"); + + let last_message = conversations[0].last_message.as_ref().unwrap(); + assert_eq!( + last_message.content, + "Second message".as_bytes().to_vec(), + "Last message content should be the most recent" + ); + + } + + #[tokio::test(flavor = "multi_thread", worker_threads = 5)] + async fn test_list_conversations_no_messages() { + // Step 1: Setup test clients Alix and Bo + let alix = new_test_client().await; + let bo = new_test_client().await; + + let alix_conversations = alix.conversations(); + + // Step 2: Create a group with Bo but do not send messages + let group = alix_conversations + .create_group( + vec![bo.account_address.clone()], + FfiCreateGroupOptions::default(), + ) + .await + .unwrap(); + + // Step 3: Synchronize conversations + alix_conversations.sync_all_conversations(None).await.unwrap(); + + // Step 4: List conversations and verify + let conversations = alix_conversations + .list_conversations() + .await + .unwrap(); + + // Ensure the group is included + assert_eq!(conversations.len(), 1, "Alix should have exactly 1 group"); + + // Verify that the last_message is None + assert!( + conversations[0].last_message.is_none(), + "Last message should be None since no messages were sent" + ); + } + #[tokio::test(flavor = "multi_thread", worker_threads = 5)] async fn test_can_sync_all_groups() { let alix = new_test_client().await; diff --git a/xmtp_mls/src/client.rs b/xmtp_mls/src/client.rs index 09fa09142..d68f84f73 100644 --- a/xmtp_mls/src/client.rs +++ b/xmtp_mls/src/client.rs @@ -686,25 +686,35 @@ where pub fn list_conversations( &self, - ) -> Result, StoredGroupMessage)>, ClientError> { + ) -> Result, Option)>, ClientError> { Ok(self .store() .conn()? .fetch_conversation_list()? .into_iter() .map(|conversation_item| { - ( - StoredGroupMessage { - id: conversation_item.message_id?, + let message = if let Some(message_id) = conversation_item.message_id { + Some(StoredGroupMessage { + id: message_id, group_id: conversation_item.id.clone(), - decrypted_message_bytes: conversation_item.decrypted_message_bytes?, - sent_at_ns: conversation_item.sent_at_ns?, - sender_installation_id: conversation_item.sender_installation_id?, - sender_inbox_id: conversation_item.sender_inbox_id?, - kind: conversation_item.kind?, - delivery_status: conversation_item.delivery_status?, - }, - MlsGroup::new(self.clone(), conversation_item.id, conversation_item.created_at_ns), + decrypted_message_bytes: conversation_item.decrypted_message_bytes.unwrap(), + sent_at_ns: conversation_item.sent_at_ns.unwrap(), + sender_installation_id: conversation_item.sender_installation_id.unwrap(), + sender_inbox_id: conversation_item.sender_inbox_id.unwrap(), + kind: conversation_item.kind.unwrap(), + delivery_status: conversation_item.delivery_status.unwrap(), + }) + } else { + None + }; + + ( + MlsGroup::new( + self.clone(), + conversation_item.id, + conversation_item.created_at_ns, + ), + message, ) }) .collect()) diff --git a/xmtp_mls/src/groups/mod.rs b/xmtp_mls/src/groups/mod.rs index f9b3e1e7a..35662bc7d 100644 --- a/xmtp_mls/src/groups/mod.rs +++ b/xmtp_mls/src/groups/mod.rs @@ -272,7 +272,6 @@ impl RetryableError for GroupError { pub struct MlsGroup { pub group_id: Vec, pub created_at_ns: i64, - pub last_message: Option, pub client: Arc, mutex: Arc>, } @@ -290,7 +289,6 @@ impl Clone for MlsGroup { Self { group_id: self.group_id.clone(), created_at_ns: self.created_at_ns, - last_message: self.last_message.clone(), client: self.client.clone(), mutex: self.mutex.clone(), }