mod.rs (7079B)
1 #![forbid(unsafe_code)] 2 3 pub mod decode; 4 pub mod encode; 5 pub mod list_sets; 6 7 #[cfg(test)] 8 mod tests { 9 #[cfg(feature = "serde_json")] 10 use crate::coop::decode::coop_from_event; 11 use crate::coop::encode::{coop_build_tags, coop_ref_tags}; 12 use crate::coop::list_sets::{ 13 coop_items_list_set, coop_members_farms_list_set, coop_members_list_set, 14 member_of_coops_list_set, 15 }; 16 use crate::error::EventEncodeError; 17 use radroots_events::coop::{RadrootsCoop, RadrootsCoopLocation, RadrootsCoopRef}; 18 use radroots_events::farm::{ 19 RadrootsFarmRef, RadrootsGcsLocation, RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon, 20 }; 21 #[cfg(feature = "serde_json")] 22 use radroots_events::kinds::KIND_COOP; 23 24 #[test] 25 fn coop_tags_include_required_fields() { 26 let coop = RadrootsCoop { 27 d_tag: "BAAAAAAAAAAAAAAAAAAAAA".to_string(), 28 name: "Test Coop".to_string(), 29 about: None, 30 website: None, 31 picture: None, 32 banner: None, 33 location: Some(RadrootsCoopLocation { 34 primary: None, 35 city: None, 36 region: None, 37 country: None, 38 gcs: RadrootsGcsLocation { 39 lat: 37.0, 40 lng: -122.0, 41 geohash: "9q8yy".to_string(), 42 point: RadrootsGeoJsonPoint { 43 r#type: "Point".to_string(), 44 coordinates: [-122.0, 37.0], 45 }, 46 polygon: RadrootsGeoJsonPolygon { 47 r#type: "Polygon".to_string(), 48 coordinates: vec![vec![ 49 [-122.0, 37.0], 50 [-122.0, 37.0001], 51 [-122.0001, 37.0001], 52 [-122.0, 37.0], 53 ]], 54 }, 55 accuracy: None, 56 altitude: None, 57 tag_0: None, 58 label: None, 59 area: None, 60 elevation: None, 61 soil: None, 62 climate: None, 63 gc_id: None, 64 gc_name: None, 65 gc_admin1_id: None, 66 gc_admin1_name: None, 67 gc_country_id: None, 68 gc_country_name: None, 69 }, 70 }), 71 tags: Some(vec!["regional".to_string()]), 72 }; 73 74 let tags = coop_build_tags(&coop).expect("tags"); 75 assert!(tags.iter().any(|tag| tag.get(0) == Some(&"d".to_string()))); 76 assert!(tags.iter().any(|tag| tag.get(0) == Some(&"t".to_string()))); 77 assert!(tags.iter().any(|tag| tag.get(0) == Some(&"g".to_string()))); 78 } 79 80 #[test] 81 fn coop_ref_tags_include_p_and_a() { 82 let coop = RadrootsCoopRef { 83 pubkey: "coop_pubkey".to_string(), 84 d_tag: "BAAAAAAAAAAAAAAAAAAAAA".to_string(), 85 }; 86 87 let tags = coop_ref_tags(&coop).expect("coop ref tags"); 88 let has_a = tags 89 .iter() 90 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("a")); 91 let has_p = tags 92 .iter() 93 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("p")); 94 assert!(has_a); 95 assert!(has_p); 96 97 let err = coop_ref_tags(&RadrootsCoopRef { 98 pubkey: "coop_pubkey".to_string(), 99 d_tag: "invalid".to_string(), 100 }) 101 .expect_err("expected invalid coop.d_tag"); 102 assert!(matches!(err, EventEncodeError::InvalidField("coop.d_tag"))); 103 } 104 105 #[test] 106 fn coop_build_tags_rejects_invalid_d_tag() { 107 let coop = RadrootsCoop { 108 d_tag: "invalid".to_string(), 109 name: "Test Coop".to_string(), 110 about: None, 111 website: None, 112 picture: None, 113 banner: None, 114 location: None, 115 tags: None, 116 }; 117 118 let err = coop_build_tags(&coop).expect_err("expected invalid d_tag"); 119 assert!(matches!(err, EventEncodeError::InvalidField("d_tag"))); 120 } 121 122 #[test] 123 #[cfg(feature = "serde_json")] 124 fn coop_decode_rejects_empty_d_tag_and_content() { 125 let coop = RadrootsCoop { 126 d_tag: "BAAAAAAAAAAAAAAAAAAAAA".to_string(), 127 name: "Test Coop".to_string(), 128 about: None, 129 website: None, 130 picture: None, 131 banner: None, 132 location: None, 133 tags: None, 134 }; 135 let content = serde_json::to_string(&coop).expect("coop content"); 136 137 let empty_d = coop_from_event( 138 KIND_COOP, 139 &[vec!["d".to_string(), " ".to_string()]], 140 &content, 141 ) 142 .expect_err("empty d tag"); 143 assert!(matches!( 144 empty_d, 145 crate::error::EventParseError::InvalidTag("d") 146 )); 147 148 let empty_content = coop_from_event( 149 KIND_COOP, 150 &[vec!["d".to_string(), "BAAAAAAAAAAAAAAAAAAAAA".to_string()]], 151 " ", 152 ) 153 .expect_err("empty content"); 154 assert!(matches!( 155 empty_content, 156 crate::error::EventParseError::InvalidJson("content") 157 )); 158 } 159 160 #[test] 161 fn coop_list_sets_include_expected_tags() { 162 let members = coop_members_list_set("BAAAAAAAAAAAAAAAAAAAAA", ["member_pubkey"]) 163 .expect("members list"); 164 assert_eq!(members.d_tag, "coop:BAAAAAAAAAAAAAAAAAAAAA:members"); 165 assert_eq!(members.entries.len(), 1); 166 assert_eq!(members.entries[0].tag, "p"); 167 168 let err = coop_members_list_set("BAAAAAAAAAAAAAAAAAAAAA", [" "]) 169 .expect_err("expected invalid members entry"); 170 assert!(matches!( 171 err, 172 EventEncodeError::EmptyRequiredField("entry.values") 173 )); 174 175 let farm_members = coop_members_farms_list_set( 176 "BAAAAAAAAAAAAAAAAAAAAA", 177 [RadrootsFarmRef { 178 pubkey: "farm_pubkey".to_string(), 179 d_tag: "AAAAAAAAAAAAAAAAAAAAAA".to_string(), 180 }], 181 ) 182 .expect("farm members list"); 183 assert_eq!( 184 farm_members.d_tag, 185 "coop:BAAAAAAAAAAAAAAAAAAAAA:members.farms" 186 ); 187 assert!(farm_members.entries.iter().any(|entry| entry.tag == "a")); 188 assert!(farm_members.entries.iter().any(|entry| entry.tag == "p")); 189 190 let items = coop_items_list_set( 191 "BAAAAAAAAAAAAAAAAAAAAA", 192 ["30361:coop_pubkey:FAAAAAAAAAAAAAAAAAAAAA"], 193 ) 194 .expect("items list"); 195 assert_eq!(items.d_tag, "coop:BAAAAAAAAAAAAAAAAAAAAA:items"); 196 assert_eq!(items.entries.len(), 1); 197 assert_eq!(items.entries[0].tag, "a"); 198 199 let claims = member_of_coops_list_set(["coop_pubkey"]).expect("claims list"); 200 assert_eq!(claims.d_tag, "member_of.coops"); 201 assert_eq!(claims.entries.len(), 1); 202 assert_eq!(claims.entries[0].tag, "p"); 203 } 204 }