#[macro_export]
macro_rules! registry_backend_contract_tests {
($name:ident, $setup:expr $(,)?) => {
mod $name {
use std::ops::ControlFlow;
use super::*;
use $crate::storage::registry::RegistryBackend as _;
#[test]
fn contract_append_and_get_event() {
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-append-get");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let got = store.get_event(&prefix, 0).unwrap();
assert_eq!(got.said(), event.said());
}
#[test]
fn contract_get_event_not_found() {
use $crate::keri::types::Prefix;
let (store, _guard) = $setup;
let prefix = Prefix::new_unchecked(
"EUnknownPrefix000000000000000000000000000000".to_string(),
);
let result = store.get_event(&prefix, 0);
assert!(result.is_err(), "missing event should return Err");
}
#[test]
fn contract_append_refuses_duplicate_sequence() {
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-dup");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let again = $crate::testing::fixtures::test_inception_event("seed-dup");
let result = store.append_event(&prefix, &again);
assert!(result.is_err(), "duplicate seq 0 should be rejected");
}
#[test]
fn contract_get_tip_after_append() {
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-tip");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let tip = store.get_tip(&prefix).unwrap();
assert_eq!(tip.sequence, 0);
assert_eq!(&tip.said, event.said());
}
#[test]
fn contract_get_key_state_not_found() {
use $crate::keri::types::Prefix;
let (store, _guard) = $setup;
let prefix = Prefix::new_unchecked(
"EUnknownPrefix000000000000000000000000000000".to_string(),
);
let result = store.get_key_state(&prefix);
assert!(result.is_err(), "missing key state should return Err");
}
#[test]
fn contract_write_and_get_key_state() {
use $crate::keri::state::KeyState;
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-write-key-state");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let ks = KeyState::from_inception(
prefix.clone(),
vec![auths_keri::CesrKey::new_unchecked("DTestKey".to_string())],
vec![auths_keri::Said::new_unchecked("ETestNext".to_string())],
auths_keri::Threshold::Simple(1),
auths_keri::Threshold::Simple(1),
event.said().clone(),
vec![],
auths_keri::Threshold::Simple(0),
vec![],
);
store.write_key_state(&prefix, &ks).unwrap();
let got = store.get_key_state(&prefix).unwrap();
assert_eq!(got.prefix, prefix);
}
#[test]
fn contract_visit_events_early_exit() {
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-visit-events");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let mut visited = 0usize;
store
.visit_events(&prefix, 0, &mut |_| {
visited += 1;
ControlFlow::Break(())
})
.unwrap();
assert_eq!(
visited, 1,
"early-exit visitor should visit exactly 1 event"
);
}
#[test]
fn contract_visit_identities_early_exit() {
let (store, _guard) = $setup;
let e0 = $crate::testing::fixtures::test_inception_event("seed-ident-a");
let e1 = $crate::testing::fixtures::test_inception_event("seed-ident-b");
store.append_event(e0.prefix(), &e0).unwrap();
store.append_event(e1.prefix(), &e1).unwrap();
let mut seen = 0usize;
store
.visit_identities(&mut |_| {
seen += 1;
ControlFlow::Break(())
})
.unwrap();
assert_eq!(
seen, 1,
"early-exit visitor should stop after first identity"
);
}
#[test]
fn contract_store_and_load_attestation() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did = CanonicalDid::new_unchecked("did:key:zContractStoreLoad1");
let att = $crate::testing::fixtures::test_attestation(&did, "did:keri:EIssuer1");
store.store_attestation(&att).unwrap();
let loaded = store.load_attestation(&did).unwrap();
assert!(
loaded.is_some(),
"attestation should be present after store"
);
assert_eq!(loaded.unwrap().subject.as_str(), did.as_str());
}
#[test]
fn contract_load_attestation_not_found() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did = CanonicalDid::new_unchecked("did:key:zNotStored99");
let result = store.load_attestation(&did).unwrap();
assert!(result.is_none(), "missing attestation should return None");
}
#[test]
fn contract_store_attestation_overwrites_latest() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did = CanonicalDid::new_unchecked("did:key:zContractOverwrite1");
let att1 = $crate::testing::fixtures::test_attestation(&did, "did:keri:EIssuer1");
let mut att2 =
$crate::testing::fixtures::test_attestation(&did, "did:keri:EIssuer1");
att2.rid = auths_verifier::core::ResourceId::new("updated-rid");
store.store_attestation(&att1).unwrap();
store.store_attestation(&att2).unwrap();
let loaded = store.load_attestation(&did).unwrap().unwrap();
assert_eq!(
loaded.rid, "updated-rid",
"second store should overwrite latest"
);
}
#[test]
fn contract_attestation_history_preserves_order() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did = CanonicalDid::new_unchecked("did:key:zContractHistory1");
for i in 0..3u32 {
let mut att =
$crate::testing::fixtures::test_attestation(&did, "did:keri:EIssuer1");
att.rid = auths_verifier::core::ResourceId::new(format!("rid-{}", i));
store.store_attestation(&att).unwrap();
}
let mut history = Vec::new();
store
.visit_attestation_history(&did, &mut |att| {
history.push(att.rid.clone());
ControlFlow::Continue(())
})
.unwrap();
assert_eq!(history.len(), 3);
assert_eq!(history[0], "rid-0");
assert_eq!(history[2], "rid-2");
}
#[test]
fn contract_visit_attestation_history_early_exit() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did = CanonicalDid::new_unchecked("did:key:zContractHistExit1");
for i in 0..3u32 {
let mut att =
$crate::testing::fixtures::test_attestation(&did, "did:keri:EIssuer1");
att.rid = auths_verifier::core::ResourceId::new(format!("rid-{}", i));
store.store_attestation(&att).unwrap();
}
let mut count = 0usize;
store
.visit_attestation_history(&did, &mut |_| {
count += 1;
ControlFlow::Break(())
})
.unwrap();
assert_eq!(count, 1, "early-exit visitor should stop after first entry");
}
#[test]
fn contract_visit_devices_early_exit() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let did1 = CanonicalDid::new_unchecked("did:key:zContractDev1");
let did2 = CanonicalDid::new_unchecked("did:key:zContractDev2");
store
.store_attestation(&$crate::testing::fixtures::test_attestation(
&did1,
"did:keri:EIssuer1",
))
.unwrap();
store
.store_attestation(&$crate::testing::fixtures::test_attestation(
&did2,
"did:keri:EIssuer1",
))
.unwrap();
let mut seen = 0usize;
store
.visit_devices(&mut |_| {
seen += 1;
ControlFlow::Break(())
})
.unwrap();
assert_eq!(seen, 1, "early-exit visitor should stop after first device");
}
#[test]
fn contract_store_and_visit_org_member() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let org = "ETestOrgPrefix";
let did = CanonicalDid::new_unchecked("did:key:zMemberContract1");
let mut att =
$crate::testing::fixtures::test_attestation(&did, "did:keri:ETestOrgPrefix");
att.rid = auths_verifier::core::ResourceId::new("org-rid");
store.store_org_member(org, &att).unwrap();
let mut found = false;
store
.visit_org_member_attestations(org, &mut |entry| {
if entry.did.as_str() == did.as_str() {
found = true;
}
ControlFlow::Continue(())
})
.unwrap();
assert!(found, "org member should be visible after store");
}
#[test]
fn contract_metadata_reflects_counts() {
use auths_verifier::types::CanonicalDid;
let (store, _guard) = $setup;
let event = $crate::testing::fixtures::test_inception_event("seed-metadata");
let prefix = event.prefix().clone();
store.append_event(&prefix, &event).unwrap();
let did = CanonicalDid::new_unchecked("did:key:zContractMeta1");
store
.store_attestation(&$crate::testing::fixtures::test_attestation(
&did,
"did:keri:EIssuer1",
))
.unwrap();
let meta = store.metadata().unwrap();
assert!(
meta.identity_count >= 1,
"at least one identity should be counted"
);
assert!(
meta.device_count >= 1,
"at least one device should be counted"
);
}
}
};
}