#[cfg(feature = "graph")]
#[tokio::test]
async fn test_temporal_diffing_integration() {
use gossan_graph::SqliteBackend as GraphStore;
use gossan_core::{Target, DiscoverySource, DomainTarget};
use std::path::Path;
let db_path = "test_temporal_int.db";
if Path::new(db_path).exists() {
let _ = std::fs::remove_file(db_path);
}
let mut store = GraphStore::open(db_path).expect("Failed to open DB");
let t1 = Target::Domain(DomainTarget {
domain: "seen-once.com".into(),
source: DiscoverySource::Seed,
});
store.persist_scan(&[t1.clone()], &[]).expect("First scan failed");
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
let t2 = Target::Domain(DomainTarget {
domain: "new-domain.com".into(),
source: DiscoverySource::Seed,
});
let diff = store.compute_diff(&[t1.clone(), t2.clone()], &[], std::time::Duration::from_secs(60)).expect("Diff failed");
assert_eq!(diff.added_targets.len(), 1);
assert_eq!(gossan_graph::target_id(&diff.added_targets[0]), "domain:new-domain.com");
assert_eq!(diff.changed_targets.len(), 0);
{
let conn = rusqlite::Connection::open(db_path).unwrap();
conn.execute(
"UPDATE targets SET last_seen = datetime('now', '-2 hours') WHERE id = 'domain:seen-once.com'",
[]
).expect("Manual update failed");
}
let diff = store.compute_diff(&[], &[], std::time::Duration::from_secs(3600)).expect("Diff failed");
assert_eq!(diff.removed_targets.len(), 1, "Old last_seen should be considered removed");
let _ = std::fs::remove_file(db_path);
}