use agent_ask::{
build_answer, build_question, build_rating, cid_of, generate_keypair, BuildAnswerOpts,
BuildQuestionOpts, BuildRatingOpts, Store,
};
#[test]
fn insert_and_get() {
let s = Store::open(":memory:").unwrap();
let kp = generate_keypair();
let q = build_question(&kp, BuildQuestionOpts {
title: "t".into(), body: "b".into(), tags: vec![], ..Default::default()
}).unwrap();
let cid = s.insert_artifact(&q).unwrap();
assert_eq!(cid, cid_of(&q).unwrap());
assert_eq!(s.get_artifact(&cid).unwrap().as_ref(), Some(&q));
}
#[test]
fn insert_idempotent() {
let s = Store::open(":memory:").unwrap();
let kp = generate_keypair();
let q = build_question(&kp, BuildQuestionOpts {
title: "t".into(), body: "b".into(), tags: vec![],
created_at: Some("2026-04-24T00:00:00Z".into()),
id: Some("01920000-0000-7000-8000-000000000001".into()),
..Default::default()
}).unwrap();
let c1 = s.insert_artifact(&q).unwrap();
let c2 = s.insert_artifact(&q).unwrap();
assert_eq!(c1, c2);
assert_eq!(s.list_questions(None, None, 100).unwrap().len(), 1);
}
#[test]
fn list_filters_by_tag() {
let s = Store::open(":memory:").unwrap();
let kp = generate_keypair();
let q1 = build_question(&kp, BuildQuestionOpts {
title: "a".into(), body: "b".into(), tags: vec!["x".into()], ..Default::default()
}).unwrap();
let q2 = build_question(&kp, BuildQuestionOpts {
title: "b".into(), body: "b".into(), tags: vec!["y".into()], ..Default::default()
}).unwrap();
s.insert_artifact(&q1).unwrap();
s.insert_artifact(&q2).unwrap();
let xs = s.list_questions(Some("x"), None, 100).unwrap();
assert_eq!(xs.len(), 1);
assert_eq!(xs[0]["id"], q1["id"]);
}
#[test]
fn list_filters_by_since_strict() {
let s = Store::open(":memory:").unwrap();
let kp = generate_keypair();
let q1 = build_question(&kp, BuildQuestionOpts {
title: "a".into(), body: "b".into(), tags: vec![],
created_at: Some("2026-04-01T00:00:00Z".into()),
..Default::default()
}).unwrap();
let q2 = build_question(&kp, BuildQuestionOpts {
title: "b".into(), body: "b".into(), tags: vec![],
created_at: Some("2026-05-01T00:00:00Z".into()),
..Default::default()
}).unwrap();
s.insert_artifact(&q1).unwrap();
s.insert_artifact(&q2).unwrap();
let recent = s.list_questions(None, Some("2026-04-15T00:00:00Z"), 100).unwrap();
assert_eq!(recent.len(), 1);
assert_eq!(recent[0]["id"], q2["id"]);
}
#[test]
fn stream_feed_newest_first() {
let s = Store::open(":memory:").unwrap();
let kp = generate_keypair();
let q = build_question(&kp, BuildQuestionOpts {
title: "t".into(), body: "b".into(), tags: vec![],
created_at: Some("2026-04-24T00:00:00Z".into()),
..Default::default()
}).unwrap();
let q_cid = s.insert_artifact(&q).unwrap();
let a = build_answer(&kp, BuildAnswerOpts {
question_cid: q_cid.clone(), body: "ans".into(),
created_at: Some("2026-04-24T00:01:00Z".into()),
..Default::default()
}).unwrap();
let a_cid = s.insert_artifact(&a).unwrap();
let r = build_rating(&kp, BuildRatingOpts {
target_cid: a_cid, score: 1,
created_at: Some("2026-04-24T00:02:00Z".into()),
..Default::default()
}).unwrap();
s.insert_artifact(&r).unwrap();
let feed = s.stream_feed(None, 1000).unwrap();
assert_eq!(feed.len(), 3);
assert_eq!(feed[0]["kind"], "rating");
}
#[test]
fn has_artifact_unknown() {
let s = Store::open(":memory:").unwrap();
assert!(!s.has_artifact("bafkunknown").unwrap());
}