test(storage): 编写 Storage 单元测试
This commit is contained in:
parent
3ffa8c41f7
commit
c17e286db1
@ -33,4 +33,4 @@ termimad = "0.34"
|
||||
textwrap = "0.16"
|
||||
chrono = "0.4"
|
||||
hostname = "0.3"
|
||||
sqlx = { version = "0.8", features = ["sqlite", "macros", "chrono"] }
|
||||
sqlx = { version = "0.8", features = ["sqlite", "macros", "chrono", "runtime-tokio"] }
|
||||
|
||||
@ -361,3 +361,164 @@ impl Storage {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use tempfile::TempDir;
|
||||
|
||||
async fn create_test_storage() -> (Storage, TempDir) {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let db_path = dir.path().join("test.db");
|
||||
let storage = Storage::new(&db_path).await.unwrap();
|
||||
(storage, dir)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_upsert_and_get_session() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
let meta = crate::storage::session::SessionMeta {
|
||||
id: "cli_chat:sid123:dialog1".to_string(),
|
||||
channel: "cli_chat".to_string(),
|
||||
chat_id: "sid123".to_string(),
|
||||
dialog_id: "dialog1".to_string(),
|
||||
title: "测试会话".to_string(),
|
||||
created_at: 1000,
|
||||
last_active_at: 1000,
|
||||
message_count: 0,
|
||||
routing_info: Some(r#"{"type":"cli"}"#.to_string()),
|
||||
deleted_at: None,
|
||||
};
|
||||
|
||||
storage.upsert_session(&meta).await.unwrap();
|
||||
|
||||
let loaded = storage.get_session(&meta.id).await.unwrap();
|
||||
assert_eq!(loaded.title, "测试会话");
|
||||
assert_eq!(loaded.channel, "cli_chat");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_get_nonexistent_session() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
let result = storage.get_session("nonexistent").await;
|
||||
assert!(result.is_err());
|
||||
matches!(result.unwrap_err(), StorageError::NotFound(_));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_list_sessions() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
for i in 0..5 {
|
||||
let meta = crate::storage::session::SessionMeta {
|
||||
id: format!("cli_chat:sid123:dialog{}", i),
|
||||
channel: "cli_chat".to_string(),
|
||||
chat_id: "sid123".to_string(),
|
||||
dialog_id: format!("dialog{}", i),
|
||||
title: format!("会话{}", i),
|
||||
created_at: i as i64 * 1000,
|
||||
last_active_at: i as i64 * 1000,
|
||||
message_count: i,
|
||||
routing_info: None,
|
||||
deleted_at: None,
|
||||
};
|
||||
storage.upsert_session(&meta).await.unwrap();
|
||||
}
|
||||
|
||||
let sessions = storage.list_sessions("cli_chat", "sid123", 10).await.unwrap();
|
||||
assert_eq!(sessions.len(), 5);
|
||||
// 按 last_active_at DESC 排序
|
||||
assert_eq!(sessions[0].dialog_id, "dialog4");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_soft_delete() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
let meta = crate::storage::session::SessionMeta {
|
||||
id: "cli_chat:sid123:dialog1".to_string(),
|
||||
channel: "cli_chat".to_string(),
|
||||
chat_id: "sid123".to_string(),
|
||||
dialog_id: "dialog1".to_string(),
|
||||
title: "测试".to_string(),
|
||||
created_at: 1000,
|
||||
last_active_at: 1000,
|
||||
message_count: 0,
|
||||
routing_info: None,
|
||||
deleted_at: None,
|
||||
};
|
||||
|
||||
storage.upsert_session(&meta).await.unwrap();
|
||||
storage.soft_delete_session(&meta.id).await.unwrap();
|
||||
|
||||
let result = storage.get_session(&meta.id).await;
|
||||
assert!(result.is_err());
|
||||
matches!(result.unwrap_err(), StorageError::NotFound(_));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_append_and_load_messages() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
let session_meta = crate::storage::session::SessionMeta {
|
||||
id: "cli_chat:sid123:dialog1".to_string(),
|
||||
channel: "cli_chat".to_string(),
|
||||
chat_id: "sid123".to_string(),
|
||||
dialog_id: "dialog1".to_string(),
|
||||
title: "测试".to_string(),
|
||||
created_at: 1000,
|
||||
last_active_at: 1000,
|
||||
message_count: 0,
|
||||
routing_info: None,
|
||||
deleted_at: None,
|
||||
};
|
||||
storage.upsert_session(&session_meta).await.unwrap();
|
||||
|
||||
let msg = crate::storage::message::MessageMeta {
|
||||
id: "msg1".to_string(),
|
||||
session_id: session_meta.id.clone(),
|
||||
seq: 1,
|
||||
role: "user".to_string(),
|
||||
content: "你好".to_string(),
|
||||
media_refs: None,
|
||||
tool_call_id: None,
|
||||
tool_name: None,
|
||||
tool_calls: None,
|
||||
created_at: 1000,
|
||||
};
|
||||
|
||||
let seq = storage.append_message(&session_meta.id, &msg).await.unwrap();
|
||||
assert_eq!(seq, 1);
|
||||
|
||||
let loaded = storage.load_messages(&session_meta.id, 0).await.unwrap();
|
||||
assert_eq!(loaded.len(), 1);
|
||||
assert_eq!(loaded[0].content, "你好");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_touch_session() {
|
||||
let (storage, _dir) = create_test_storage().await;
|
||||
|
||||
let meta = crate::storage::session::SessionMeta {
|
||||
id: "cli_chat:sid123:dialog1".to_string(),
|
||||
channel: "cli_chat".to_string(),
|
||||
chat_id: "sid123".to_string(),
|
||||
dialog_id: "dialog1".to_string(),
|
||||
title: "测试".to_string(),
|
||||
created_at: 1000,
|
||||
last_active_at: 1000,
|
||||
message_count: 0,
|
||||
routing_info: None,
|
||||
deleted_at: None,
|
||||
};
|
||||
storage.upsert_session(&meta).await.unwrap();
|
||||
|
||||
storage.touch_session(&meta.id, 5, 2000).await.unwrap();
|
||||
|
||||
let loaded = storage.get_session(&meta.id).await.unwrap();
|
||||
assert_eq!(loaded.message_count, 5);
|
||||
assert_eq!(loaded.last_active_at, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user