feat(chat): persistance bornee du brouillon custom chat par projet/layout (#182)
This commit is contained in:
110
crates/infrastructure/tests/chat_drafts.rs
Normal file
110
crates/infrastructure/tests/chat_drafts.rs
Normal file
@ -0,0 +1,110 @@
|
||||
use domain::ports::{ChatDraftStore, IdGenerator};
|
||||
use domain::{ChatDraft, ChatDraftKey, LayoutId, NodeId, ProjectId, ProjectPath};
|
||||
use infrastructure::{FsChatDraftStore, UuidGenerator};
|
||||
use uuid::Uuid;
|
||||
|
||||
fn temp_dir(tag: &str) -> std::path::PathBuf {
|
||||
std::env::temp_dir().join(format!(
|
||||
"idea-chat-draft-{tag}-{}",
|
||||
UuidGenerator::new().new_uuid()
|
||||
))
|
||||
}
|
||||
|
||||
fn pid(n: u128) -> ProjectId {
|
||||
ProjectId::from_uuid(Uuid::from_u128(n))
|
||||
}
|
||||
|
||||
fn lid(n: u128) -> LayoutId {
|
||||
LayoutId::from_uuid(Uuid::from_u128(n))
|
||||
}
|
||||
|
||||
fn nid(n: u128) -> NodeId {
|
||||
NodeId::from_uuid(Uuid::from_u128(n))
|
||||
}
|
||||
|
||||
fn key(layout: u128, node: u128) -> ChatDraftKey {
|
||||
ChatDraftKey::new(pid(1), lid(layout), nid(node))
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn fs_chat_draft_store_saves_reads_and_replaces_one_scope() {
|
||||
let project_root = temp_dir("roundtrip");
|
||||
tokio::fs::create_dir_all(&project_root).await.unwrap();
|
||||
let root = ProjectPath::new(project_root.to_string_lossy().into_owned()).unwrap();
|
||||
let store = FsChatDraftStore::new();
|
||||
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 3), "first", 10).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 3), "second", 11).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let draft = store.read(&root, key(2, 3)).await.unwrap().unwrap();
|
||||
assert_eq!(draft.text, "second");
|
||||
assert_eq!(draft.updated_at_ms, 11);
|
||||
assert!(
|
||||
tokio::fs::metadata(project_root.join(".ideai/chat-drafts.json"))
|
||||
.await
|
||||
.is_ok()
|
||||
);
|
||||
|
||||
let _ = tokio::fs::remove_dir_all(project_root).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn fs_chat_draft_store_scopes_by_layout_and_node() {
|
||||
let project_root = temp_dir("scoped");
|
||||
tokio::fs::create_dir_all(&project_root).await.unwrap();
|
||||
let root = ProjectPath::new(project_root.to_string_lossy().into_owned()).unwrap();
|
||||
let store = FsChatDraftStore::new();
|
||||
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 2), "node two", 10).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 3), "node three", 11).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
store.read(&root, key(2, 2)).await.unwrap().unwrap().text,
|
||||
"node two"
|
||||
);
|
||||
assert_eq!(
|
||||
store.read(&root, key(2, 3)).await.unwrap().unwrap().text,
|
||||
"node three"
|
||||
);
|
||||
|
||||
let _ = tokio::fs::remove_dir_all(project_root).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn fs_chat_draft_store_clear_removes_only_target_scope() {
|
||||
let project_root = temp_dir("clear");
|
||||
tokio::fs::create_dir_all(&project_root).await.unwrap();
|
||||
let root = ProjectPath::new(project_root.to_string_lossy().into_owned()).unwrap();
|
||||
let store = FsChatDraftStore::new();
|
||||
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 2), "clear", 10).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
store
|
||||
.save(&root, ChatDraft::new(key(2, 3), "keep", 11).unwrap())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
store.clear(&root, key(2, 2)).await.unwrap();
|
||||
|
||||
assert!(store.read(&root, key(2, 2)).await.unwrap().is_none());
|
||||
assert_eq!(
|
||||
store.read(&root, key(2, 3)).await.unwrap().unwrap().text,
|
||||
"keep"
|
||||
);
|
||||
|
||||
let _ = tokio::fs::remove_dir_all(project_root).await;
|
||||
}
|
||||
Reference in New Issue
Block a user