#![allow(clippy::unwrap_used, clippy::expect_used)]
use timeglyph::carve::{carve, to_imhex_bookmarks, to_jsonl};
fn planted() -> Vec<timeglyph::carve::CarveHit> {
let ft = 133_908_455_300_649_390_u64.to_le_bytes();
let mut buf = vec![0xAA_u8; 3];
buf.extend_from_slice(&ft);
buf.extend_from_slice(&[0xBB; 3]);
let win = (
946_684_800_i128 * 1_000_000_000,
1_893_456_000_i128 * 1_000_000_000,
);
carve(&buf, 0.85, Some(win))
}
#[test]
fn jsonl_is_one_parseable_object_per_line_with_offset_and_format() {
let jsonl = to_jsonl(&planted());
assert!(!jsonl.is_empty());
for line in jsonl.lines() {
let v: serde_json::Value = serde_json::from_str(line).expect("each line is valid JSON");
assert!(v.get("offset").is_some(), "carries offset");
assert!(v.get("format").is_some(), "carries format");
assert!(v.get("score").is_some(), "carries score");
}
assert!(
jsonl
.lines()
.any(|l| l.contains("\"filetime\"") && l.contains("\"offset\":3")),
"the planted filetime at offset 3 appears in the JSONL"
);
}
#[test]
fn imhex_bookmarks_mark_the_offset_and_width() {
let bm = to_imhex_bookmarks(&planted());
let v: serde_json::Value = serde_json::from_str(&bm).expect("valid ImHex bookmark JSON");
let arr = v["bookmarks"].as_array().expect("bookmarks array");
assert!(
arr.iter()
.any(|b| b["region"]["address"] == 3 && b["region"]["size"] == 8),
"an 8-byte bookmark at address 3 (the planted FILETIME)"
);
}
#[test]
fn timesketch_jsonl_carries_the_required_import_fields() {
let jsonl = timeglyph::carve::to_timesketch_jsonl(&planted());
assert!(!jsonl.is_empty());
for line in jsonl.lines() {
let v: serde_json::Value = serde_json::from_str(line).expect("valid Timesketch JSONL");
assert!(v.get("message").is_some(), "message");
assert!(v.get("datetime").is_some(), "datetime (ISO8601)");
assert!(v.get("timestamp_desc").is_some(), "timestamp_desc");
}
assert!(
jsonl
.lines()
.any(|l| l.contains("2025-05-04") && l.contains("filetime")),
"the planted filetime becomes a Timesketch event"
);
}