canonical_surface.rs (3464B)
1 use radroots_event::{ 2 admission::{Error as VerificationError, RawEvent, SignatureVerifier}, 3 envelope::{EventEnvelope, EventEnvelopeParts}, 4 }; 5 use radroots_event_codec::{Codec, EncodeError, canonical, verify}; 6 7 struct AcceptSignature; 8 9 impl SignatureVerifier for AcceptSignature { 10 fn verify_signature(&self, _event: &EventEnvelope) -> Result<(), VerificationError> { 11 Ok(()) 12 } 13 } 14 15 fn profile_event() -> EventEnvelope { 16 EventEnvelope::new(EventEnvelopeParts { 17 id: "762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0" 18 .to_owned(), 19 author: "585591529da0bab31b3b1b1f986611cf5f435dca84f978c89ee8a40cca7103df" 20 .to_owned(), 21 created_at: 1_800_000_100, 22 kind: 0, 23 tags: vec![], 24 content: "{\"display_name\":\"Moss Street Farm\",\"bot\":false,\"website\":\"https://mossstreet.example\",\"picture\":42}".to_owned(), 25 sig: "4290da0bb6422986647bc8cd5f63bd52d49f41e7b665d3b47105b8109183e8d596f322c531d4061df53e1d2b70fda12d5d1c14f3720d7a56d9d0a03746af5109".to_owned(), 26 }) 27 .expect("valid fixture envelope") 28 } 29 30 #[test] 31 fn canonical_surface_preserves_every_verification_stage() { 32 let event = profile_event(); 33 34 assert_eq!(canonical::id(&event).expect("canonical id"), *event.id()); 35 assert!( 36 canonical::id_preimage(&event) 37 .expect("preimage") 38 .starts_with("[0,") 39 ); 40 41 let id_verified = Codec::verify_id(RawEvent::new(event)).expect("id verified"); 42 let signature_verified = 43 Codec::verify_signature(id_verified, &AcceptSignature).expect("signature verified"); 44 let contract_validated = 45 Codec::verify_contract(signature_verified).expect("contract validated"); 46 47 assert_eq!( 48 contract_validated.contract_id(), 49 "radroots.profile.metadata.v1" 50 ); 51 } 52 53 #[test] 54 fn module_entrypoints_match_codec_convenience_type() { 55 let id_verified = verify::id(RawEvent::new(profile_event())).expect("id verified"); 56 let signature_verified = 57 verify::signature(id_verified, &AcceptSignature).expect("signature verified"); 58 let contract_validated = verify::contract(signature_verified).expect("contract validated"); 59 60 assert_eq!(contract_validated.event(), &profile_event()); 61 } 62 63 #[cfg(feature = "json")] 64 #[test] 65 fn decode_does_not_hide_identifier_verification() { 66 let encoded = Codec::encode_event(&profile_event()).expect("encoded event"); 67 let mismatched = encoded.replacen( 68 "762bee187e9e645b81ec26ade05a69b5e8398caf527be8de0d9a45311ed0c7a0", 69 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 70 1, 71 ); 72 73 let raw = Codec::decode_event(&mismatched).expect("structurally valid event"); 74 let error = Codec::verify_id(raw).expect_err("identifier mismatch"); 75 76 assert_eq!(error.code(), "id_mismatch"); 77 } 78 79 #[cfg(feature = "json")] 80 #[test] 81 fn compact_json_round_trip_is_deterministic() { 82 let encoded = Codec::encode_event(&profile_event()).expect("encoded event"); 83 let decoded = Codec::decode_event(&encoded).expect("decoded event"); 84 let reencoded = Codec::encode_event(decoded.event()).expect("re-encoded event"); 85 86 assert_eq!(reencoded, encoded); 87 } 88 89 #[cfg(feature = "json")] 90 #[test] 91 fn public_errors_expose_stable_concise_codes() { 92 let decode = Codec::decode_event("{").expect_err("invalid JSON"); 93 94 assert_eq!(decode.code(), "invalid_json"); 95 assert_eq!(EncodeError::Json.code(), "json"); 96 }