use client::platforms::test::{MockDelivery, MockOutbox}; use client::{ChatClient, ContentData, ConversationIdOwned, StorageConfig}; use std::sync::Arc; fn new_client(name: &str) -> (ChatClient, MockOutbox) { let outbox = MockOutbox::default(); let delivery = MockDelivery::with_outbox(&outbox); (ChatClient::new(name, delivery), outbox) } fn pop_and_receive( sender_outbox: &MockOutbox, receiver: &mut ChatClient, ) -> Option { let raw = sender_outbox.pop_front().expect("expected envelope"); receiver.receive(&raw).expect("receive failed") } #[test] fn alice_bob_message_exchange() { let (mut alice, alice_outbox) = new_client("alice"); let (mut bob, bob_outbox) = new_client("bob"); // Exchange intro bundles out-of-band let bob_bundle = bob.create_intro_bundle().unwrap(); // Alice initiates conversation with Bob let alice_convo_id = alice .create_conversation(&bob_bundle, b"hello bob") .unwrap(); // Bob receives Alice's initial message let content = pop_and_receive(&alice_outbox, &mut bob).expect("expected content"); assert_eq!(content.data, b"hello bob"); assert!(content.is_new_convo); let bob_convo_id: ConversationIdOwned = Arc::from(content.conversation_id.as_str()); // Bob replies bob.send_message(&bob_convo_id, b"hi alice").unwrap(); let content = pop_and_receive(&bob_outbox, &mut alice).expect("expected content"); assert_eq!(content.data, b"hi alice"); assert!(!content.is_new_convo); // Multiple back-and-forth rounds for i in 0u8..5 { let msg = format!("msg {i}"); alice.send_message(&alice_convo_id, msg.as_bytes()).unwrap(); let content = pop_and_receive(&alice_outbox, &mut bob).expect("expected content"); assert_eq!(content.data, msg.as_bytes()); let reply = format!("reply {i}"); bob.send_message(&bob_convo_id, reply.as_bytes()).unwrap(); let content = pop_and_receive(&bob_outbox, &mut alice).expect("expected content"); assert_eq!(content.data, reply.as_bytes()); } // Both sides have exactly one conversation assert_eq!(alice.list_conversations().unwrap().len(), 1); assert_eq!(bob.list_conversations().unwrap().len(), 1); } #[test] fn open_persistent_client() { let dir = tempfile::tempdir().unwrap(); let db_path = dir.path().join("test.db").to_string_lossy().to_string(); let config = StorageConfig::File(db_path); let client1 = ChatClient::open("alice", config.clone(), MockDelivery::default()).unwrap(); let name1 = client1.installation_name().to_string(); drop(client1); let client2 = ChatClient::open("alice", config, MockDelivery::default()).unwrap(); let name2 = client2.installation_name().to_string(); assert_eq!(name1, name2, "installation name should persist across restarts"); }