Signed-off-by: Sienna Meridian Satterwhite <sienna@r3t.io>
This commit is contained in:
2025-11-16 11:50:49 +00:00
parent 1bd664fd2a
commit 888e5d303c
33 changed files with 766 additions and 460 deletions

View File

@@ -1,5 +1,8 @@
use lib::{ChatDb, Result};
use chrono::Datelike;
use lib::{
ChatDb,
Result,
};
/// Test that we can get messages from the Dutch phone number conversation
#[test]
@@ -12,11 +15,14 @@ fn test_get_our_messages_default_range() -> Result<()> {
println!("Found {} messages from January 2024 to now", messages.len());
// Verify we got some messages
assert!(messages.len() > 0, "Should find messages in the conversation");
assert!(
messages.len() > 0,
"Should find messages in the conversation"
);
// Verify messages are in chronological order (ASC)
for i in 1..messages.len().min(10) {
if let (Some(prev_date), Some(curr_date)) = (messages[i-1].date, messages[i].date) {
if let (Some(prev_date), Some(curr_date)) = (messages[i - 1].date, messages[i].date) {
assert!(
prev_date <= curr_date,
"Messages should be in ascending date order"
@@ -28,8 +34,12 @@ fn test_get_our_messages_default_range() -> Result<()> {
for msg in messages.iter().take(10) {
if let Some(date) = msg.date {
assert!(date.year() >= 2024, "Messages should be from 2024 or later");
println!("Message date: {}, from_me: {}, text: {:?}",
date, msg.is_from_me, msg.text.as_ref().map(|s| &s[..s.len().min(50)]));
println!(
"Message date: {}, from_me: {}, text: {:?}",
date,
msg.is_from_me,
msg.text.as_ref().map(|s| &s[..s.len().min(50)])
);
}
}
@@ -39,7 +49,10 @@ fn test_get_our_messages_default_range() -> Result<()> {
/// Test that we can get messages with a custom date range
#[test]
fn test_get_our_messages_custom_range() -> Result<()> {
use chrono::{TimeZone, Utc};
use chrono::{
TimeZone,
Utc,
};
let db = ChatDb::open("chat.db")?;
@@ -57,7 +70,9 @@ fn test_get_our_messages_custom_range() -> Result<()> {
assert!(
date >= start && date <= end,
"Message date {} should be between {} and {}",
date, start, end
date,
start,
end
);
}
}
@@ -86,11 +101,25 @@ fn test_conversation_summary() -> Result<()> {
for (i, msg) in messages.iter().take(5).enumerate() {
if let Some(date) = msg.date {
let sender = if msg.is_from_me { "Me" } else { "Them" };
let text = msg.text.as_ref()
.map(|t| if t.len() > 60 { format!("{}...", &t[..60]) } else { t.clone() })
let text = msg
.text
.as_ref()
.map(|t| {
if t.len() > 60 {
format!("{}...", &t[..60])
} else {
t.clone()
}
})
.unwrap_or_else(|| "[No text]".to_string());
println!("{}. {} ({}): {}", i + 1, date.format("%Y-%m-%d %H:%M"), sender, text);
println!(
"{}. {} ({}): {}",
i + 1,
date.format("%Y-%m-%d %H:%M"),
sender,
text
);
}
}

View File

@@ -1,7 +1,19 @@
use lib::sync::{synced, SyncMessage, Syncable};
use iroh::{Endpoint, protocol::{Router, ProtocolHandler, AcceptError}};
use anyhow::Result;
use std::sync::Arc;
use anyhow::Result;
use iroh::{
Endpoint,
protocol::{
AcceptError,
ProtocolHandler,
Router,
},
};
use lib::sync::{
SyncMessage,
Syncable,
synced,
};
use tokio::sync::Mutex;
/// Test configuration that can be synced
@@ -28,20 +40,25 @@ impl ProtocolHandler for SyncProtocol {
println!("Accepting connection from: {}", connection.remote_id());
// Accept the bidirectional stream
let (mut send, mut recv) = connection.accept_bi().await
let (mut send, mut recv) = connection
.accept_bi()
.await
.map_err(AcceptError::from_err)?;
println!("Stream accepted, reading message...");
// Read the sync message
let bytes = recv.read_to_end(1024 * 1024).await
let bytes = recv
.read_to_end(1024 * 1024)
.await
.map_err(AcceptError::from_err)?;
println!("Received {} bytes", bytes.len());
// Deserialize and apply
let msg = SyncMessage::<TestConfigOp>::from_bytes(&bytes)
.map_err(|e| AcceptError::from_err(std::io::Error::new(std::io::ErrorKind::InvalidData, e)))?;
let msg = SyncMessage::<TestConfigOp>::from_bytes(&bytes).map_err(|e| {
AcceptError::from_err(std::io::Error::new(std::io::ErrorKind::InvalidData, e))
})?;
println!("Applying operation from node: {}", msg.node_id);
@@ -51,8 +68,7 @@ impl ProtocolHandler for SyncProtocol {
println!("Operation applied successfully");
// Close the stream
send.finish()
.map_err(AcceptError::from_err)?;
send.finish().map_err(AcceptError::from_err)?;
Ok(())
}
@@ -76,24 +92,24 @@ async fn test_sync_between_two_nodes() -> Result<()> {
println!("Node 2: {}", node2_id);
// Create synced configs on both nodes
let mut config1 = TestConfig::new(
42,
"initial".to_string(),
node1_id.clone(),
);
let mut config1 = TestConfig::new(42, "initial".to_string(), node1_id.clone());
let config2 = TestConfig::new(
42,
"initial".to_string(),
node2_id.clone(),
);
let config2 = TestConfig::new(42, "initial".to_string(), node2_id.clone());
let config2_shared = Arc::new(Mutex::new(config2));
println!("\nInitial state:");
println!(" Node 1: value={}, name={}", config1.value(), config1.name());
println!(
" Node 1: value={}, name={}",
config1.value(),
config1.name()
);
{
let config2 = config2_shared.lock().await;
println!(" Node 2: value={}, name={}", config2.value(), config2.name());
println!(
" Node 2: value={}, name={}",
config2.value(),
config2.name()
);
}
// Set up router on node2 to accept incoming connections
@@ -101,9 +117,7 @@ async fn test_sync_between_two_nodes() -> Result<()> {
let protocol = SyncProtocol {
config: config2_shared.clone(),
};
let router = Router::builder(node2)
.accept(SYNC_ALPN, protocol)
.spawn();
let router = Router::builder(node2).accept(SYNC_ALPN, protocol).spawn();
router.endpoint().online().await;
println!("✓ Node2 router ready");
@@ -136,10 +150,18 @@ async fn test_sync_between_two_nodes() -> Result<()> {
// Verify both configs have the same value
println!("\nFinal state:");
println!(" Node 1: value={}, name={}", config1.value(), config1.name());
println!(
" Node 1: value={}, name={}",
config1.value(),
config1.name()
);
{
let config2 = config2_shared.lock().await;
println!(" Node 2: value={}, name={}", config2.value(), config2.name());
println!(
" Node 2: value={}, name={}",
config2.value(),
config2.name()
);
assert_eq!(*config1.value(), 100);
assert_eq!(*config2.value(), 100);