use chrono::Utc;
use gradatum_core::author::{AuthorKind, AuthorRef};
use gradatum_core::error::DriftError;
use gradatum_core::frontmatter::{ExtraFields, Frontmatter};
use gradatum_core::identity::{ContentHash, NoteId, NoteVersion};
use gradatum_core::note::{Note, NoteBody};
use gradatum_core::scope::VaultId;
use gradatum_core::section::Section;
use gradatum_core::status::NoteStatus;
use smallvec::SmallVec;
fn build_note(body: &str) -> Note {
let frontmatter = Frontmatter {
schema_version: 1,
vault_id: VaultId("main".into()),
locus: None,
section: Section::Decisions,
status: NoteStatus::Live,
status_reason: None,
status_changed: None,
tags: SmallVec::new(),
author: Some(AuthorRef {
kind: AuthorKind::Human,
id: "operator".into(),
display_name: None,
}),
created: Utc::now(),
updated: None,
extra: ExtraFields::empty(),
provenance: None,
forgotten: None,
forgotten_at: None,
forgotten_by: None,
};
let content_hash = ContentHash::compute(&frontmatter, body);
Note {
id: NoteId::new(),
frontmatter,
body: NoteBody {
markdown: body.to_string(),
},
version: NoteVersion::initial(),
content_hash,
integrity_signature: None,
}
}
#[test]
fn verify_integrity_ok_when_consistent() {
let note = build_note("body");
assert!(note.verify_integrity().is_ok());
}
#[test]
fn verify_integrity_detects_body_drift() {
let mut note = build_note("original body");
note.body.markdown = "tampered body".into();
let result = note.verify_integrity();
assert!(matches!(
result,
Err(DriftError::ContentHashMismatch { .. })
));
}
#[test]
fn verify_integrity_detects_frontmatter_drift() {
let mut note = build_note("body");
note.frontmatter.status = NoteStatus::Garbage;
assert!(note.verify_integrity().is_err());
}
#[test]
fn verify_integrity_idempotent() {
let note = build_note("body");
assert!(note.verify_integrity().is_ok());
assert!(note.verify_integrity().is_ok());
}