lib

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

mod.rs (7017B)


      1 pub mod decode;
      2 pub mod encode;
      3 
      4 #[cfg(test)]
      5 mod tests {
      6     use radroots_events::{http_auth::RadrootsHttpAuth, kinds::KIND_POST};
      7 
      8     use crate::error::{EventEncodeError, EventParseError};
      9     use crate::http_auth::decode::{data_from_event, http_auth_from_event, parsed_from_event};
     10     use crate::http_auth::encode::{http_auth_build_tags, to_wire_parts, to_wire_parts_with_kind};
     11 
     12     const PAYLOAD: &str = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
     13 
     14     #[test]
     15     fn http_auth_encodes_and_decodes_get_without_payload() {
     16         let auth = RadrootsHttpAuth {
     17             url: "https://media.example.invalid/download".to_string(),
     18             method: "GET".to_string(),
     19             payload_sha256: None,
     20         };
     21         let parts = to_wire_parts(&auth).expect("http auth wire parts");
     22 
     23         assert_eq!(parts.kind, 27235);
     24         assert_eq!(parts.content, "");
     25         assert!(parts.tags.contains(&tag("u", auth.url.as_str())));
     26         assert!(parts.tags.contains(&tag("method", "GET")));
     27 
     28         let decoded =
     29             http_auth_from_event(parts.kind, &parts.tags, &parts.content).expect("decode");
     30         assert_eq!(decoded, auth);
     31     }
     32 
     33     #[test]
     34     fn http_auth_encodes_and_decodes_post_with_payload() {
     35         let auth = RadrootsHttpAuth {
     36             url: "https://media.example.invalid/upload".to_string(),
     37             method: "POST".to_string(),
     38             payload_sha256: Some(PAYLOAD.to_string()),
     39         };
     40         let parts = to_wire_parts(&auth).expect("http auth wire parts");
     41 
     42         assert!(parts.tags.contains(&tag("payload", PAYLOAD)));
     43         let decoded =
     44             http_auth_from_event(parts.kind, &parts.tags, &parts.content).expect("decode");
     45         assert_eq!(decoded.payload_sha256.as_deref(), Some(PAYLOAD));
     46     }
     47 
     48     #[test]
     49     fn http_auth_rejects_missing_url_missing_method_bad_payload_and_content() {
     50         let auth = RadrootsHttpAuth {
     51             url: "https://media.example.invalid/upload".to_string(),
     52             method: "POST".to_string(),
     53             payload_sha256: Some(PAYLOAD.to_string()),
     54         };
     55         let parts = to_wire_parts(&auth).expect("http auth wire parts");
     56         let without_url = parts
     57             .tags
     58             .iter()
     59             .filter(|tag| tag.first().map(|value| value.as_str()) != Some("u"))
     60             .cloned()
     61             .collect::<Vec<_>>();
     62         let missing_url = http_auth_from_event(parts.kind, &without_url, "").unwrap_err();
     63         assert!(matches!(missing_url, EventParseError::MissingTag("u")));
     64 
     65         let without_method = parts
     66             .tags
     67             .iter()
     68             .filter(|tag| tag.first().map(|value| value.as_str()) != Some("method"))
     69             .cloned()
     70             .collect::<Vec<_>>();
     71         let missing_method = http_auth_from_event(parts.kind, &without_method, "").unwrap_err();
     72         assert!(matches!(
     73             missing_method,
     74             EventParseError::MissingTag("method")
     75         ));
     76 
     77         let mut bad_payload = auth.clone();
     78         bad_payload.payload_sha256 = Some("ABC".to_string());
     79         let payload_err = http_auth_build_tags(&bad_payload).unwrap_err();
     80         assert!(matches!(
     81             payload_err,
     82             EventEncodeError::InvalidField("payload_sha256")
     83         ));
     84 
     85         let mut empty_url = auth.clone();
     86         empty_url.url.clear();
     87         let url_err = http_auth_build_tags(&empty_url).unwrap_err();
     88         assert!(matches!(
     89             url_err,
     90             EventEncodeError::EmptyRequiredField("url")
     91         ));
     92 
     93         let mut empty_method = auth.clone();
     94         empty_method.method.clear();
     95         let method_err = http_auth_build_tags(&empty_method).unwrap_err();
     96         assert!(matches!(
     97             method_err,
     98             EventEncodeError::EmptyRequiredField("method")
     99         ));
    100 
    101         let mut bad_payload_tag = parts.tags.clone();
    102         replace_tag_value(&mut bad_payload_tag, "payload", "ABC");
    103         let payload_tag_err = http_auth_from_event(parts.kind, &bad_payload_tag, "").unwrap_err();
    104         assert!(matches!(
    105             payload_tag_err,
    106             EventParseError::InvalidTag("payload")
    107         ));
    108 
    109         let mut invalid_url = parts.tags.clone();
    110         replace_tag_value(&mut invalid_url, "u", " ");
    111         let url_tag_err = http_auth_from_event(parts.kind, &invalid_url, "").unwrap_err();
    112         assert!(matches!(url_tag_err, EventParseError::InvalidTag("u")));
    113 
    114         let content_err = http_auth_from_event(parts.kind, &parts.tags, "not empty").unwrap_err();
    115         assert!(matches!(
    116             content_err,
    117             EventParseError::InvalidJson("content")
    118         ));
    119     }
    120 
    121     #[test]
    122     fn http_auth_rejects_wrong_kind() {
    123         let auth = RadrootsHttpAuth {
    124             url: "https://media.example.invalid/upload".to_string(),
    125             method: "POST".to_string(),
    126             payload_sha256: Some(PAYLOAD.to_string()),
    127         };
    128         let wrong_kind = to_wire_parts_with_kind(&auth, KIND_POST).unwrap_err();
    129         assert!(matches!(
    130             wrong_kind,
    131             EventEncodeError::InvalidKind(KIND_POST)
    132         ));
    133 
    134         let parts = to_wire_parts(&auth).expect("http auth wire parts");
    135         let decode_wrong_kind = http_auth_from_event(KIND_POST, &parts.tags, "").unwrap_err();
    136         assert!(matches!(
    137             decode_wrong_kind,
    138             EventParseError::InvalidKind {
    139                 expected: "27235",
    140                 got: KIND_POST
    141             }
    142         ));
    143     }
    144 
    145     #[test]
    146     fn http_auth_wrappers_preserve_event_metadata() {
    147         let auth = RadrootsHttpAuth {
    148             url: "https://media.example.invalid/upload".to_string(),
    149             method: "POST".to_string(),
    150             payload_sha256: Some(PAYLOAD.to_string()),
    151         };
    152         let parts = to_wire_parts(&auth).expect("http auth wire parts");
    153 
    154         let data = data_from_event(
    155             "event-id".to_string(),
    156             "author-pubkey".to_string(),
    157             99,
    158             parts.kind,
    159             parts.content.clone(),
    160             parts.tags.clone(),
    161         )
    162         .expect("parsed data");
    163         assert_eq!(data.id, "event-id");
    164         assert_eq!(data.author, "author-pubkey");
    165         assert_eq!(data.published_at, 99);
    166         assert_eq!(data.data, auth);
    167 
    168         let parsed = parsed_from_event(
    169             "event-id".to_string(),
    170             "author-pubkey".to_string(),
    171             99,
    172             parts.kind,
    173             parts.content,
    174             parts.tags,
    175             "sig".to_string(),
    176         )
    177         .expect("parsed event");
    178         assert_eq!(parsed.event.sig, "sig");
    179         assert_eq!(parsed.data.data, auth);
    180     }
    181 
    182     fn tag(key: &str, value: &str) -> Vec<String> {
    183         vec![key.to_string(), value.to_string()]
    184     }
    185 
    186     fn replace_tag_value(tags: &mut [Vec<String>], key: &str, value: &str) {
    187         let tag = tags
    188             .iter_mut()
    189             .find(|tag| tag.first().map(String::as_str) == Some(key))
    190             .expect("tag");
    191         tag[1] = value.to_string();
    192     }
    193 }