lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

wire.rs (3140B)


      1 use radroots_event::GenericEventDraft;
      2 use radroots_event::draft::DraftError;
      3 use radroots_event::envelope::kind::{KIND_GEOCHAT, KIND_PROFILE, KIND_RHI_EVIDENCE_ATTESTATION};
      4 use radroots_event::wire::Nip01EventWireParts;
      5 use radroots_event_codec::decode::wire::{canonicalize_tags, empty_content};
      6 
      7 #[test]
      8 fn wire_canonicalize_tags_trims_sorts_and_dedups() {
      9     let mut tags = vec![
     10         vec![" z ".to_string(), "b".to_string()],
     11         vec!["t".to_string(), "a".to_string()],
     12         vec!["".to_string(), "x".to_string()],
     13         vec![" t ".to_string(), "a ".to_string()],
     14         vec!["t".to_string(), "a".to_string()],
     15     ];
     16 
     17     canonicalize_tags(&mut tags);
     18 
     19     assert_eq!(
     20         tags,
     21         vec![
     22             vec!["t".to_string(), "a".to_string()],
     23             vec!["z".to_string(), "b".to_string()],
     24         ]
     25     );
     26 }
     27 
     28 #[test]
     29 fn wire_parts_are_canonical_event_owned_payload_parts() {
     30     let parts = Nip01EventWireParts {
     31         kind: KIND_GEOCHAT,
     32         content: "hello".to_string(),
     33         tags: vec![vec!["t".to_string(), "a".to_string()]],
     34     };
     35     let json = serde_json::to_string(&parts).expect("json");
     36     let decoded: Nip01EventWireParts = serde_json::from_str(&json).expect("decoded");
     37 
     38     assert_eq!(decoded, parts);
     39 }
     40 
     41 #[test]
     42 fn draft_validation_accepts_wire_parts_without_signed_envelope() {
     43     let parts = Nip01EventWireParts {
     44         kind: KIND_GEOCHAT,
     45         content: "hello".to_string(),
     46         tags: vec![vec!["t".to_string(), "a".to_string()]],
     47     };
     48 
     49     let draft = GenericEventDraft::new(
     50         "radroots.social.geochat.v1",
     51         parts.kind,
     52         99,
     53         parts.tags,
     54         parts.content,
     55         "a".repeat(64),
     56     )
     57     .expect("draft");
     58 
     59     assert_eq!(draft.kind_u32(), KIND_GEOCHAT);
     60     assert_eq!(draft.created_at_u64(), 99);
     61     assert_eq!(draft.expected_pubkey().to_hex(), "a".repeat(64));
     62     assert_eq!(draft.content(), "hello");
     63     assert_eq!(draft.tags().len(), 1);
     64     assert_eq!(draft.expected_event_id_hex().len(), 64);
     65 }
     66 
     67 #[test]
     68 fn generic_draft_rejects_typed_only_contracts() {
     69     let typed_only = Nip01EventWireParts {
     70         kind: KIND_PROFILE,
     71         content: r#"{"name":"Alice"}"#.to_string(),
     72         tags: Vec::new(),
     73     };
     74     let error = GenericEventDraft::new(
     75         "radroots.profile.metadata.v1",
     76         typed_only.kind,
     77         99,
     78         typed_only.tags,
     79         typed_only.content,
     80         "a".repeat(64),
     81     )
     82     .expect_err("typed-only contract");
     83     assert!(matches!(
     84         error,
     85         DraftError::ContractNotDraftAuthorable { .. }
     86     ));
     87 }
     88 
     89 #[test]
     90 fn generic_draft_rejects_the_typed_only_rhi_attestation_contract() {
     91     let error = GenericEventDraft::new(
     92         "radroots.rhi.evidence_attestation.v1",
     93         KIND_RHI_EVIDENCE_ATTESTATION,
     94         99,
     95         Vec::new(),
     96         "{}",
     97         "a".repeat(64),
     98     )
     99     .expect_err("RHI attestation requires the typed authoring path");
    100     assert!(matches!(
    101         error,
    102         DraftError::ContractNotDraftAuthorable { .. }
    103     ));
    104 }
    105 
    106 #[test]
    107 fn wire_empty_content_is_empty_string() {
    108     let content = empty_content();
    109     assert!(content.is_empty());
    110 }