Add protected chapter
This commit is contained in:
@@ -15,7 +15,9 @@ fn fixed_secret() -> SecretKey {
|
||||
fn make_signed_event(kind: u16, tags: Vec<Tag>) -> coracle_lib::events::Event {
|
||||
let sk = fixed_secret();
|
||||
let pk = sk.public_key();
|
||||
let hashed = EventContent::new("test", tags)
|
||||
let hashed = EventContent::new()
|
||||
.content("test")
|
||||
.tags(tags)
|
||||
.kind(kind)
|
||||
.stamp(1_700_000_000)
|
||||
.own(pk)
|
||||
|
||||
@@ -13,7 +13,9 @@ fn fixed_secret() -> SecretKey {
|
||||
}
|
||||
|
||||
fn build_hashed(content: &str, tags: Vec<Tag>) -> HashedEvent {
|
||||
EventContent::new(content, tags)
|
||||
EventContent::new()
|
||||
.content(content)
|
||||
.tags(tags)
|
||||
.kind(1)
|
||||
.stamp(1_700_000_000)
|
||||
.own(fixed_secret().public_key())
|
||||
@@ -29,7 +31,7 @@ fn sign_fixture() -> Event {
|
||||
|
||||
#[test]
|
||||
fn pipeline_progresses_through_types() {
|
||||
let content = EventContent::new("hi", Tags::new());
|
||||
let content = EventContent::new().content("hi").tags(Tags::new());
|
||||
let template: EventTemplate = content.kind(1);
|
||||
let stamped: StampedEvent = template.stamp(1_700_000_000);
|
||||
let owned: OwnedEvent = stamped.own(fixed_secret().public_key());
|
||||
|
||||
@@ -15,7 +15,9 @@ fn fixed_secret() -> SecretKey {
|
||||
|
||||
fn make_event(kind: u16, timestamp: u64, tags: Vec<Tag>) -> Event {
|
||||
let sk = fixed_secret();
|
||||
let hashed = EventContent::new("hello", tags)
|
||||
let hashed = EventContent::new()
|
||||
.content("hello")
|
||||
.tags(tags)
|
||||
.kind(kind)
|
||||
.stamp(timestamp)
|
||||
.own(sk.public_key())
|
||||
|
||||
@@ -12,7 +12,9 @@ fn fixed_secret() -> SecretKey {
|
||||
}
|
||||
|
||||
fn test_event() -> OwnedEvent {
|
||||
EventContent::new("hello nostr", Tags::new())
|
||||
EventContent::new()
|
||||
.content("hello nostr")
|
||||
.tags(Tags::new())
|
||||
.kind(1)
|
||||
.stamp(1_700_000_000)
|
||||
.own(fixed_secret().public_key())
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
use coracle_lib::events::{EventContent, HashedEvent};
|
||||
use coracle_lib::keys::SecretKey;
|
||||
use coracle_lib::protected::is_protected;
|
||||
use coracle_lib::tags::{Tag, Tags};
|
||||
|
||||
fn fixed_secret() -> SecretKey {
|
||||
let bytes: [u8; 32] = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||
26, 27, 28, 29, 30, 31, 32,
|
||||
];
|
||||
SecretKey::from_hex(&hex::encode(bytes)).unwrap()
|
||||
}
|
||||
|
||||
fn build_hashed(tags: Tags) -> HashedEvent {
|
||||
EventContent::new()
|
||||
.content("hi")
|
||||
.tags(tags)
|
||||
.kind(1)
|
||||
.stamp(1_700_000_000)
|
||||
.own(fixed_secret().public_key())
|
||||
.hash()
|
||||
}
|
||||
|
||||
// --- Tag::protected constructor ---
|
||||
|
||||
#[test]
|
||||
fn tag_constructor_shape() {
|
||||
let t = Tag::protected();
|
||||
assert_eq!(t.name(), "-");
|
||||
assert_eq!(t.len(), 1);
|
||||
assert!(t.values().is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tag_constructor_serializes_as_single_element() {
|
||||
let t = Tag::protected();
|
||||
assert_eq!(serde_json::to_string(&t).unwrap(), r#"["-"]"#);
|
||||
}
|
||||
|
||||
// --- is_protected ---
|
||||
|
||||
#[test]
|
||||
fn is_protected_false_when_tag_absent() {
|
||||
let tags = Tags::new();
|
||||
assert!(!is_protected(&tags));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_protected_false_with_unrelated_tags() {
|
||||
let tags = Tags::from(vec![Tag::new("t", ["nostr"]), Tag::expiration(100)]);
|
||||
assert!(!is_protected(&tags));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_protected_true_when_tag_present() {
|
||||
let tags = Tags::from(vec![Tag::protected()]);
|
||||
assert!(is_protected(&tags));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_protected_true_among_other_tags() {
|
||||
let tags = Tags::from(vec![
|
||||
Tag::new("t", ["nostr"]),
|
||||
Tag::protected(),
|
||||
Tag::expiration(100),
|
||||
]);
|
||||
assert!(is_protected(&tags));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_protected_detects_a_raw_dash_tag() {
|
||||
// The marker is identified by name alone; a hand-built ["-"] is
|
||||
// equivalent to Tag::protected().
|
||||
let tags = Tags::from(vec![Tag::new("-", Vec::<String>::new())]);
|
||||
assert!(is_protected(&tags));
|
||||
}
|
||||
|
||||
// --- HashedEvent method facade ---
|
||||
|
||||
#[test]
|
||||
fn hashed_event_reports_protected() {
|
||||
let event = build_hashed(Tags::from(vec![Tag::protected()]));
|
||||
assert!(event.is_protected());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hashed_event_reports_unprotected() {
|
||||
let event = build_hashed(Tags::new());
|
||||
assert!(!event.is_protected());
|
||||
}
|
||||
|
||||
// --- Event method facade ---
|
||||
|
||||
#[test]
|
||||
fn signed_event_reports_protected() {
|
||||
let sk = fixed_secret();
|
||||
let hashed = build_hashed(Tags::from(vec![Tag::protected()]));
|
||||
let sig = sk.sign(&hashed.id);
|
||||
let signed = hashed.sign(sig);
|
||||
|
||||
assert!(signed.is_protected());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn protected_tag_survives_hashing_and_signing() {
|
||||
// The tag is part of the canonical hash input, so it must round-trip
|
||||
// through hash() and sign() intact and still verify.
|
||||
let sk = fixed_secret();
|
||||
let hashed = build_hashed(Tags::from(vec![Tag::protected()]));
|
||||
let sig = sk.sign(&hashed.id);
|
||||
let signed = hashed.sign(sig);
|
||||
|
||||
assert!(signed.verify_id());
|
||||
assert!(signed.is_protected());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn unprotected_event_stays_unprotected_through_signing() {
|
||||
let sk = fixed_secret();
|
||||
let hashed = build_hashed(Tags::new());
|
||||
let sig = sk.sign(&hashed.id);
|
||||
let signed = hashed.sign(sig);
|
||||
|
||||
assert!(!signed.is_protected());
|
||||
}
|
||||
Reference in New Issue
Block a user