use chrono::{TimeZone, Utc};
fn expected(ids: &[u32], ts: &str) -> String {
let mut clause = String::from("(");
for (i, id) in ids.iter().enumerate() {
if i > 0 {
clause.push_str(" or ");
}
clause.push_str(&format!("EventID={id}"));
}
clause.push(')');
format!("*[System[{clause} and TimeCreated[@SystemTime>='{ts}']]]")
}
#[test]
fn shape_matches_contract() {
let ts = Utc.with_ymd_and_hms(2024, 1, 15, 12, 34, 56).unwrap();
let ts_str = ts.format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
let want = expected(&[4624, 4625, 4648], &ts_str);
assert!(want.contains("EventID=4624"));
assert!(want.contains("EventID=4625"));
assert!(want.contains("EventID=4648"));
assert!(want.contains(&ts_str));
assert!(want.starts_with("*[System["));
assert!(want.ends_with("]]]"));
}
#[test]
fn empty_ids_yields_time_only_filter() {
let ts = Utc.with_ymd_and_hms(2024, 1, 15, 0, 0, 0).unwrap();
let ts_str = ts.format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string();
let want = format!("*[System[TimeCreated[@SystemTime>='{ts_str}']]]");
assert!(!want.contains("EventID="));
assert!(want.contains(&ts_str));
}