mod.rs (8620B)
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 use crate::error::EventEncodeError; 10 use crate::resource_area::encode::{resource_area_build_tags, resource_area_ref_tags}; 11 use crate::resource_area::list_sets::{ 12 resource_area_members_farms_list_set, resource_area_members_plots_list_set, 13 resource_area_stewards_list_set, 14 }; 15 use radroots_events::farm::RadrootsFarmRef; 16 use radroots_events::farm::{ 17 RadrootsGcsLocation, RadrootsGeoJsonPoint, RadrootsGeoJsonPolygon, 18 }; 19 use radroots_events::plot::RadrootsPlotRef; 20 use radroots_events::resource_area::{ 21 RadrootsResourceArea, RadrootsResourceAreaLocation, RadrootsResourceAreaRef, 22 }; 23 24 fn sample_location() -> RadrootsResourceAreaLocation { 25 RadrootsResourceAreaLocation { 26 primary: None, 27 city: None, 28 region: None, 29 country: None, 30 gcs: RadrootsGcsLocation { 31 lat: -4.527, 32 lng: 129.898, 33 geohash: "pmb5v".to_string(), 34 point: RadrootsGeoJsonPoint { 35 r#type: "Point".to_string(), 36 coordinates: [129.898, -4.527], 37 }, 38 polygon: RadrootsGeoJsonPolygon { 39 r#type: "Polygon".to_string(), 40 coordinates: vec![vec![ 41 [129.898, -4.527], 42 [129.899, -4.527], 43 [129.899, -4.528], 44 [129.898, -4.527], 45 ]], 46 }, 47 accuracy: None, 48 altitude: None, 49 tag_0: None, 50 label: None, 51 area: None, 52 elevation: None, 53 soil: None, 54 climate: None, 55 gc_id: None, 56 gc_name: None, 57 gc_admin1_id: None, 58 gc_admin1_name: None, 59 gc_country_id: None, 60 gc_country_name: None, 61 }, 62 } 63 } 64 65 #[test] 66 fn resource_area_tags_include_required_fields() { 67 let area = RadrootsResourceArea { 68 d_tag: "AAAAAAAAAAAAAAAAAAAAAw".to_string(), 69 name: "Banda Grove".to_string(), 70 about: None, 71 location: sample_location(), 72 tags: Some(vec!["nutmeg".to_string()]), 73 }; 74 75 let tags = resource_area_build_tags(&area).expect("tags"); 76 assert!( 77 tags.iter() 78 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("d")) 79 ); 80 assert!( 81 tags.iter() 82 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("g")) 83 ); 84 assert!( 85 tags.iter() 86 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("t")) 87 ); 88 } 89 90 #[test] 91 fn resource_area_tags_allow_missing_optional_fields() { 92 let area = RadrootsResourceArea { 93 d_tag: "AAAAAAAAAAAAAAAAAAAAAw".to_string(), 94 name: "Banda Grove".to_string(), 95 about: None, 96 location: sample_location(), 97 tags: None, 98 }; 99 100 let tags = resource_area_build_tags(&area).expect("tags without optional fields"); 101 assert!( 102 tags.iter() 103 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("d")) 104 ); 105 assert!( 106 tags.iter() 107 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("g")) 108 ); 109 assert!( 110 !tags 111 .iter() 112 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("t")) 113 ); 114 } 115 116 #[test] 117 fn resource_area_ref_tags_include_p_and_a() { 118 let area_ref = RadrootsResourceAreaRef { 119 pubkey: "area_pubkey".to_string(), 120 d_tag: "AAAAAAAAAAAAAAAAAAAAAw".to_string(), 121 }; 122 123 let tags = resource_area_ref_tags(&area_ref).expect("ref tags"); 124 assert!( 125 tags.iter() 126 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("p")) 127 ); 128 assert!( 129 tags.iter() 130 .any(|tag| tag.get(0).map(|v| v.as_str()) == Some("a")) 131 ); 132 133 let err = resource_area_ref_tags(&RadrootsResourceAreaRef { 134 pubkey: "area_pubkey".to_string(), 135 d_tag: "invalid".to_string(), 136 }) 137 .expect_err("expected invalid resource_area.d_tag"); 138 assert!(matches!( 139 err, 140 EventEncodeError::InvalidField("resource_area.d_tag") 141 )); 142 } 143 144 #[test] 145 fn resource_area_build_tags_rejects_invalid_d_tag() { 146 let area = RadrootsResourceArea { 147 d_tag: "invalid".to_string(), 148 name: "Banda Grove".to_string(), 149 about: None, 150 location: sample_location(), 151 tags: None, 152 }; 153 154 let err = resource_area_build_tags(&area).expect_err("expected invalid d_tag"); 155 assert!(matches!(err, EventEncodeError::InvalidField("d_tag"))); 156 } 157 158 #[test] 159 fn resource_area_encode_rejects_empty_required_fields() { 160 let mut area = RadrootsResourceArea { 161 d_tag: "AAAAAAAAAAAAAAAAAAAAAw".to_string(), 162 name: "Banda Grove".to_string(), 163 about: None, 164 location: sample_location(), 165 tags: None, 166 }; 167 168 area.d_tag = " ".to_string(); 169 let err = resource_area_build_tags(&area).expect_err("expected empty d_tag"); 170 assert!(matches!(err, EventEncodeError::EmptyRequiredField("d_tag"))); 171 172 area.d_tag = "AAAAAAAAAAAAAAAAAAAAAw".to_string(); 173 area.name = " ".to_string(); 174 let err = resource_area_build_tags(&area).expect_err("expected empty name"); 175 assert!(matches!(err, EventEncodeError::EmptyRequiredField("name"))); 176 177 area.name = "Banda Grove".to_string(); 178 area.location.gcs.geohash = " ".to_string(); 179 let err = resource_area_build_tags(&area).expect_err("expected empty geohash"); 180 assert!(matches!( 181 err, 182 EventEncodeError::EmptyRequiredField("location.gcs.geohash") 183 )); 184 185 let err = resource_area_ref_tags(&RadrootsResourceAreaRef { 186 pubkey: " ".to_string(), 187 d_tag: "AAAAAAAAAAAAAAAAAAAAAw".to_string(), 188 }) 189 .expect_err("expected empty resource_area.pubkey"); 190 assert!(matches!( 191 err, 192 EventEncodeError::EmptyRequiredField("resource_area.pubkey") 193 )); 194 195 let err = resource_area_ref_tags(&RadrootsResourceAreaRef { 196 pubkey: "area_pubkey".to_string(), 197 d_tag: " ".to_string(), 198 }) 199 .expect_err("expected empty resource_area.d_tag"); 200 assert!(matches!( 201 err, 202 EventEncodeError::EmptyRequiredField("resource_area.d_tag") 203 )); 204 } 205 206 #[test] 207 fn resource_area_list_sets_include_expected_tags() { 208 let farms = resource_area_members_farms_list_set( 209 "AAAAAAAAAAAAAAAAAAAAAw", 210 [RadrootsFarmRef { 211 pubkey: "farm_pubkey".to_string(), 212 d_tag: "AAAAAAAAAAAAAAAAAAAAAA".to_string(), 213 }], 214 ) 215 .expect("farm members"); 216 assert_eq!(farms.d_tag, "resource:AAAAAAAAAAAAAAAAAAAAAw:members.farms"); 217 assert!(farms.entries.iter().any(|entry| entry.tag == "a")); 218 assert!(farms.entries.iter().any(|entry| entry.tag == "p")); 219 220 let plots = resource_area_members_plots_list_set( 221 "AAAAAAAAAAAAAAAAAAAAAw", 222 [RadrootsPlotRef { 223 pubkey: "farm_pubkey".to_string(), 224 d_tag: "AAAAAAAAAAAAAAAAAAAAAQ".to_string(), 225 }], 226 ) 227 .expect("plot members"); 228 assert_eq!(plots.d_tag, "resource:AAAAAAAAAAAAAAAAAAAAAw:members.plots"); 229 assert!(plots.entries.iter().any(|entry| entry.tag == "a")); 230 assert!(plots.entries.iter().any(|entry| entry.tag == "p")); 231 232 let stewards = 233 resource_area_stewards_list_set("AAAAAAAAAAAAAAAAAAAAAw", ["steward_pubkey"]) 234 .expect("stewards"); 235 assert_eq!( 236 stewards.d_tag, 237 "resource:AAAAAAAAAAAAAAAAAAAAAw:members.stewards" 238 ); 239 assert!(stewards.entries.iter().any(|entry| entry.tag == "p")); 240 241 let err = resource_area_stewards_list_set("AAAAAAAAAAAAAAAAAAAAAw", [" "]) 242 .expect_err("expected invalid steward entry"); 243 assert!(matches!( 244 err, 245 EventEncodeError::EmptyRequiredField("entry.values") 246 )); 247 } 248 }