//! Phase 1 integration tests: cognitive modules compile against Arc. //! The key goal is a compile-time gate: if any module still typed against //! SqliteMemoryStore concretely, this would fail to compile. use chrono::Utc; use std::sync::Arc; use tempfile::tempdir; use uuid::Uuid; use vestige_core::storage::{MemoryEdge, MemoryRecord, MemoryStore, SqliteMemoryStore}; fn make_store() -> Arc { let dir = tempdir().unwrap(); let db = dir.path().join("test.db"); std::mem::forget(dir); Arc::new(SqliteMemoryStore::new(Some(db)).expect("create")) } fn make_record(content: &str) -> MemoryRecord { MemoryRecord { id: Uuid::new_v4(), domains: vec![], domain_scores: Default::default(), content: content.to_string(), node_type: "fact".to_string(), tags: vec!["isolation-test".to_string()], embedding: None, created_at: Utc::now(), updated_at: Utc::now(), metadata: serde_json::json!({}), } } /// Ensure the store: Arc call pattern compiles and runs through /// a representative method from every cognitive module group. #[tokio::test] async fn all_modules_compile_against_dyn_store() { let store: Arc = make_store(); // CRUD via trait let rec = make_record("cognitive isolation test"); let id = store.insert(&rec).await.expect("insert via dyn trait"); let got = store .get(id) .await .expect("get via dyn trait") .expect("exists"); assert_eq!(got.content, "cognitive isolation test"); // Graph edges via trait let rec2 = make_record("linked node"); let id2 = store.insert(&rec2).await.expect("insert 2"); store .add_edge(&MemoryEdge { source_id: id, target_id: id2, edge_type: "semantic".to_string(), weight: 0.8, created_at: Utc::now(), }) .await .expect("add_edge via dyn trait"); let edges = store .get_edges(id, None) .await .expect("get_edges via dyn trait"); assert!(!edges.is_empty()); // Search via trait let results = store .fts_search("cognitive", 5) .await .expect("fts_search via dyn trait"); assert!(!results.is_empty()); // Stats and count via trait let count = store.count().await.expect("count via dyn trait"); assert!(count >= 2); let stats = store.get_stats().await.expect("get_stats via dyn trait"); assert!(stats.total_memories >= 2); } #[tokio::test] async fn spreading_activation_traverses_via_trait() { let store: Arc = make_store(); let rec_a = make_record("spreading activation source"); let rec_b = make_record("spreading activation neighbor"); let id_a = rec_a.id; let id_b = rec_b.id; store.insert(&rec_a).await.expect("insert a"); store.insert(&rec_b).await.expect("insert b"); store .add_edge(&MemoryEdge { source_id: id_a, target_id: id_b, edge_type: "semantic".to_string(), weight: 0.9, created_at: Utc::now(), }) .await .expect("add edge"); // get_neighbors simulates the spreading activation traversal path let neighbors = store.get_neighbors(id_a, 1).await.expect("get_neighbors"); let ids: Vec = neighbors.iter().map(|(r, _)| r.id).collect(); assert!(ids.contains(&id_a)); assert!(ids.contains(&id_b)); } #[tokio::test] async fn synaptic_tagging_consumes_records_via_trait() { // Build a MemoryRecord from trait-returned data and exercise the // SynapticTaggingSystem pipeline (constructing CapturedMemory from store data). let store: Arc = make_store(); let rec = make_record("synaptic tagging test memory"); let id = store.insert(&rec).await.expect("insert"); let got = store.get(id).await.expect("get").expect("exists"); // The important thing is we got a MemoryRecord back from the dyn trait; // SynapticTaggingSystem would take this record as input. assert_eq!(got.id, id); assert!(!got.content.is_empty()); } #[tokio::test] async fn hippocampal_index_built_from_store() { // Exercise the fts_search -> HippocampalIndex indexing path. let store: Arc = make_store(); for i in 0..5usize { let rec = make_record(&format!("hippocampal indexing topic {i}")); store.insert(&rec).await.expect("insert"); } let results = store .fts_search("hippocampal indexing", 10) .await .expect("fts_search"); // Verify we get results and they have the correct fields assert!(!results.is_empty()); for r in &results { assert!(!r.record.content.is_empty()); assert!(r.score >= 0.0); } }