test: expand test coverage for backend and frontend modules
Security Scan and Upload / Security & DefectDojo Upload (pull_request) Successful in 58s
CI / Lint & Test (pull_request) Failing after 5m51s
CI / Build Linux (pull_request) Has been skipped
CI / Build Windows (cross-compile) (pull_request) Has been skipped

- Add 25+ tests for temp_manager.rs (0% -> 96.59% coverage)
- Expand sessions.rs tests (23% -> 68.50% coverage)
- Expand quick_actions.rs tests (23% -> 71.13% coverage)
- Expand snippets.rs tests (23% -> 72.32% coverage)
- Expand stats.rs tests with cost calculation and streak tests
- Add frontend test infrastructure with Tauri mocks
- Add tests for conversations, quickActions, and snippets stores
- Total backend tests: 298 passing
This commit is contained in:
2026-01-25 23:18:03 -08:00
committed by Naomi Carrigan
parent bee4eb393e
commit 8cb4c17dc1
10 changed files with 3077 additions and 0 deletions
+206
View File
@@ -145,6 +145,30 @@ pub async fn clear_all_sessions(app: AppHandle) -> Result<(), String> {
#[cfg(test)]
mod tests {
use super::*;
use chrono::TimeZone;
fn create_test_session(id: &str, name: &str) -> SavedSession {
SavedSession {
id: id.to_string(),
name: name.to_string(),
created_at: Utc::now(),
last_activity_at: Utc::now(),
working_directory: "/home/test".to_string(),
message_count: 5,
preview: "Hello world".to_string(),
messages: vec![],
}
}
fn create_test_message(id: &str, content: &str, msg_type: &str) -> SavedMessage {
SavedMessage {
id: id.to_string(),
message_type: msg_type.to_string(),
content: content.to_string(),
timestamp: Utc::now(),
tool_name: None,
}
}
#[test]
fn test_session_list_item_from_saved_session() {
@@ -164,4 +188,186 @@ mod tests {
assert_eq!(item.name, "Test Session");
assert_eq!(item.message_count, 5);
}
#[test]
fn test_session_list_item_preserves_all_fields() {
let created = Utc.with_ymd_and_hms(2024, 1, 15, 10, 30, 0).unwrap();
let last_activity = Utc.with_ymd_and_hms(2024, 1, 15, 14, 45, 0).unwrap();
let session = SavedSession {
id: "sess-123".to_string(),
name: "My Chat".to_string(),
created_at: created,
last_activity_at: last_activity,
working_directory: "/home/naomi/project".to_string(),
message_count: 42,
preview: "What is the meaning of life?".to_string(),
messages: vec![],
};
let item = SessionListItem::from(&session);
assert_eq!(item.id, "sess-123");
assert_eq!(item.name, "My Chat");
assert_eq!(item.created_at, created);
assert_eq!(item.last_activity_at, last_activity);
assert_eq!(item.working_directory, "/home/naomi/project");
assert_eq!(item.message_count, 42);
assert_eq!(item.preview, "What is the meaning of life?");
}
#[test]
fn test_saved_session_serialization() {
let session = create_test_session("test-1", "Test Session");
let json = serde_json::to_string(&session).expect("Failed to serialize");
let parsed: SavedSession = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(parsed.id, session.id);
assert_eq!(parsed.name, session.name);
assert_eq!(parsed.working_directory, session.working_directory);
}
#[test]
fn test_saved_message_serialization() {
let message = create_test_message("msg-1", "Hello!", "user");
let json = serde_json::to_string(&message).expect("Failed to serialize");
let parsed: SavedMessage = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(parsed.id, message.id);
assert_eq!(parsed.content, message.content);
assert_eq!(parsed.message_type, "user");
}
#[test]
fn test_saved_message_with_tool_name() {
let message = SavedMessage {
id: "msg-tool-1".to_string(),
message_type: "tool".to_string(),
content: "File read successfully".to_string(),
timestamp: Utc::now(),
tool_name: Some("Read".to_string()),
};
let json = serde_json::to_string(&message).expect("Failed to serialize");
let parsed: SavedMessage = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(parsed.tool_name, Some("Read".to_string()));
}
#[test]
fn test_session_with_messages_serialization() {
let mut session = create_test_session("sess-full", "Full Session");
session.messages = vec![
create_test_message("msg-1", "Hello!", "user"),
create_test_message("msg-2", "Hi there!", "assistant"),
create_test_message("msg-3", "Read file", "tool"),
];
session.message_count = 3;
let json = serde_json::to_string(&session).expect("Failed to serialize");
let parsed: SavedSession = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(parsed.messages.len(), 3);
assert_eq!(parsed.messages[0].content, "Hello!");
assert_eq!(parsed.messages[1].message_type, "assistant");
assert_eq!(parsed.messages[2].message_type, "tool");
}
#[test]
fn test_session_list_item_serialization() {
let item = SessionListItem {
id: "list-item-1".to_string(),
name: "Quick Chat".to_string(),
created_at: Utc::now(),
last_activity_at: Utc::now(),
working_directory: "/tmp".to_string(),
message_count: 10,
preview: "Short preview...".to_string(),
};
let json = serde_json::to_string(&item).expect("Failed to serialize");
let parsed: SessionListItem = serde_json::from_str(&json).expect("Failed to deserialize");
assert_eq!(parsed.id, item.id);
assert_eq!(parsed.name, item.name);
assert_eq!(parsed.preview, item.preview);
}
#[test]
fn test_message_type_field_rename() {
// The message_type field is renamed to "type" in JSON
let message = create_test_message("msg-1", "Test", "assistant");
let json = serde_json::to_string(&message).expect("Failed to serialize");
assert!(json.contains("\"type\":"));
assert!(!json.contains("\"message_type\":"));
}
#[test]
fn test_session_default_empty_messages() {
let session = SavedSession {
id: "empty".to_string(),
name: "Empty".to_string(),
created_at: Utc::now(),
last_activity_at: Utc::now(),
working_directory: "/".to_string(),
message_count: 0,
preview: "".to_string(),
messages: vec![],
};
assert!(session.messages.is_empty());
assert_eq!(session.message_count, 0);
}
#[test]
fn test_session_sorting_by_activity() {
let old_time = Utc.with_ymd_and_hms(2024, 1, 1, 0, 0, 0).unwrap();
let new_time = Utc.with_ymd_and_hms(2024, 6, 15, 12, 0, 0).unwrap();
let mut sessions = vec![
SessionListItem {
id: "old".to_string(),
name: "Old Session".to_string(),
created_at: old_time,
last_activity_at: old_time,
working_directory: "/old".to_string(),
message_count: 1,
preview: "Old".to_string(),
},
SessionListItem {
id: "new".to_string(),
name: "New Session".to_string(),
created_at: new_time,
last_activity_at: new_time,
working_directory: "/new".to_string(),
message_count: 1,
preview: "New".to_string(),
},
];
// Sort by last activity, most recent first (mimics list_sessions behavior)
sessions.sort_by(|a, b| b.last_activity_at.cmp(&a.last_activity_at));
assert_eq!(sessions[0].id, "new");
assert_eq!(sessions[1].id, "old");
}
#[test]
fn test_session_clone() {
let original = create_test_session("clone-test", "Clone Test");
let cloned = original.clone();
assert_eq!(original.id, cloned.id);
assert_eq!(original.name, cloned.name);
}
#[test]
fn test_message_clone() {
let original = create_test_message("msg-clone", "Content", "user");
let cloned = original.clone();
assert_eq!(original.id, cloned.id);
assert_eq!(original.content, cloned.content);
}
}