test: add unit tests for RPC framing, SDK state machine, and server domain services

Add comprehensive tests across three layers:
- RPC framing: empty payloads, max boundary, truncated frames, multi-frame buffers,
  all status codes, all method ID ranges, payload-too-large for response/push
- SDK: event broadcast send/receive, multiple subscribers, clone preservation,
  conversation upsert, missing conversation, message ID roundtrip, member keys
- Server domain: auth session validation/expiry, channel creation/symmetry/validation,
  delivery peek/ack/sequence ordering/fetch-limited, key package upload/fetch/validation,
  hybrid key batch fetch, size boundary tests
- CI: MSRV (1.75) check job, macOS cross-platform build check
This commit is contained in:
2026-03-08 18:07:43 +01:00
parent e4c5868b31
commit 872695e5f1
8 changed files with 1114 additions and 0 deletions

View File

@@ -1038,4 +1038,83 @@ mod tests {
// Returns 0 for unknown conversations.
assert_eq!(store.get_last_seen_seq(&missing).unwrap(), 0);
}
#[test]
fn upsert_conversation_updates_fields() {
let (_dir, store) = open_test_store();
let mut conv = make_group_conv("updatable", 1000);
store.save_conversation(&conv).unwrap();
// Update display name and activity
conv.display_name = "#updated".to_string();
conv.last_activity_ms = 9000;
conv.unread_count = 5;
conv.is_hybrid = true;
store.save_conversation(&conv).unwrap();
let loaded = store.load_conversation(&conv.id).unwrap().unwrap();
assert_eq!(loaded.display_name, "#updated");
assert_eq!(loaded.last_activity_ms, 9000);
assert_eq!(loaded.unread_count, 5);
assert!(loaded.is_hybrid);
}
#[test]
fn load_missing_conversation_returns_none() {
let (_dir, store) = open_test_store();
let missing = ConversationId([0xFFu8; 16]);
assert!(store.load_conversation(&missing).unwrap().is_none());
}
#[test]
fn conversation_id_hex_encoding() {
let id = ConversationId([0xAB; 16]);
assert_eq!(id.hex(), "abababababababababababababababab");
assert_eq!(id.hex().len(), 32);
}
#[test]
fn save_message_with_message_id_and_ref() {
let (_dir, store) = open_test_store();
let conv = make_group_conv("msg-ids", 1000);
store.save_conversation(&conv).unwrap();
let msg_id = [42u8; 16];
let ref_id = [99u8; 16];
store.save_message(&StoredMessage {
conversation_id: conv.id.clone(),
message_id: Some(msg_id),
sender_key: vec![1, 2, 3],
sender_name: Some("alice".to_string()),
body: "reply".to_string(),
msg_type: "chat".to_string(),
ref_msg_id: Some(ref_id),
timestamp_ms: 5000,
is_outgoing: true,
}).unwrap();
let msgs = store.load_recent_messages(&conv.id, 10).unwrap();
assert_eq!(msgs.len(), 1);
assert_eq!(msgs[0].message_id, Some(msg_id));
assert_eq!(msgs[0].ref_msg_id, Some(ref_id));
assert!(msgs[0].is_outgoing);
}
#[test]
fn member_keys_serialization_roundtrip() {
let (_dir, store) = open_test_store();
let mut conv = make_group_conv("member-keys", 1000);
conv.member_keys = vec![
vec![1u8; 32],
vec![2u8; 32],
vec![3u8; 32],
];
store.save_conversation(&conv).unwrap();
let loaded = store.load_conversation(&conv.id).unwrap().unwrap();
assert_eq!(loaded.member_keys.len(), 3);
assert_eq!(loaded.member_keys[0], vec![1u8; 32]);
assert_eq!(loaded.member_keys[1], vec![2u8; 32]);
assert_eq!(loaded.member_keys[2], vec![3u8; 32]);
}
}