query_bind_values.rs (12271B)
1 use radroots_replica_schema::farm::{Farm, FarmQueryBindValues}; 2 use radroots_replica_schema::farm_gcs_location::FarmGcsLocationQueryBindValues; 3 use radroots_replica_schema::farm_member::FarmMemberQueryBindValues; 4 use radroots_replica_schema::farm_member_claim::FarmMemberClaimQueryBindValues; 5 use radroots_replica_schema::farm_tag::FarmTagQueryBindValues; 6 use radroots_replica_schema::gcs_location::GcsLocationQueryBindValues; 7 use radroots_replica_schema::log_error::LogErrorQueryBindValues; 8 use radroots_replica_schema::media_image::MediaImageQueryBindValues; 9 use radroots_replica_schema::nostr_event_head::NostrEventHeadQueryBindValues; 10 use radroots_replica_schema::nostr_profile::NostrProfileQueryBindValues; 11 use radroots_replica_schema::nostr_relay::NostrRelayQueryBindValues; 12 use radroots_replica_schema::plot::PlotQueryBindValues; 13 use radroots_replica_schema::plot_gcs_location::PlotGcsLocationQueryBindValues; 14 use radroots_replica_schema::plot_tag::PlotTagQueryBindValues; 15 use radroots_replica_schema::result::{ 16 ReplicaSchemaError, ReplicaSchemaResult, ReplicaSchemaResultList, ReplicaSchemaResultPass, 17 }; 18 use radroots_replica_schema::trade_product::{TradeProduct, TradeProductQueryBindValues}; 19 use serde_json::Value; 20 21 macro_rules! assert_query_bind_values { 22 ($test_name:ident, $id_expr:expr, $id_param:literal, $id_lookup:literal, [$(($expr:expr, $param:literal, $lookup:literal)),* $(,)?]) => { 23 #[test] 24 fn $test_name() { 25 let id_case = $id_expr; 26 let (id_param, id_value) = id_case.to_filter_param(); 27 assert_eq!(id_param, $id_param); 28 assert_eq!(id_value, Value::from($id_lookup.to_string())); 29 assert_eq!(id_case.primary_key(), Some($id_lookup.to_string())); 30 assert_eq!(id_case.lookup_key(), $id_lookup.to_string()); 31 32 $( 33 let alt_case = $expr; 34 let (alt_param, alt_value) = alt_case.to_filter_param(); 35 assert_eq!(alt_param, $param); 36 assert_eq!(alt_value, Value::from($lookup.to_string())); 37 assert_eq!(alt_case.primary_key(), None); 38 assert_eq!(alt_case.lookup_key(), $lookup.to_string()); 39 )* 40 } 41 }; 42 } 43 44 assert_query_bind_values!( 45 farm_query_bind_values_cover_all_variants, 46 FarmQueryBindValues::Id { 47 id: "farm-id".to_string() 48 }, 49 "id", 50 "farm-id", 51 [ 52 ( 53 FarmQueryBindValues::DTag { 54 d_tag: "farm-d".to_string() 55 }, 56 "d_tag", 57 "farm-d" 58 ), 59 ( 60 FarmQueryBindValues::Pubkey { 61 pubkey: "farm-pk".to_string() 62 }, 63 "pubkey", 64 "farm-pk" 65 ), 66 ] 67 ); 68 69 assert_query_bind_values!( 70 farm_gcs_location_query_bind_values_cover_all_variants, 71 FarmGcsLocationQueryBindValues::Id { 72 id: "farm-gcs-id".to_string() 73 }, 74 "id", 75 "farm-gcs-id", 76 [ 77 ( 78 FarmGcsLocationQueryBindValues::FarmId { 79 farm_id: "farm-id".to_string() 80 }, 81 "farm_id", 82 "farm-id" 83 ), 84 ( 85 FarmGcsLocationQueryBindValues::GcsLocationId { 86 gcs_location_id: "gcs-id".to_string() 87 }, 88 "gcs_location_id", 89 "gcs-id" 90 ), 91 ] 92 ); 93 94 assert_query_bind_values!( 95 farm_member_query_bind_values_cover_all_variants, 96 FarmMemberQueryBindValues::Id { 97 id: "farm-member-id".to_string() 98 }, 99 "id", 100 "farm-member-id", 101 [ 102 ( 103 FarmMemberQueryBindValues::FarmId { 104 farm_id: "farm-id".to_string() 105 }, 106 "farm_id", 107 "farm-id" 108 ), 109 ( 110 FarmMemberQueryBindValues::MemberPubkey { 111 member_pubkey: "member-pk".to_string() 112 }, 113 "member_pubkey", 114 "member-pk" 115 ), 116 ] 117 ); 118 119 assert_query_bind_values!( 120 farm_member_claim_query_bind_values_cover_all_variants, 121 FarmMemberClaimQueryBindValues::Id { 122 id: "farm-member-claim-id".to_string() 123 }, 124 "id", 125 "farm-member-claim-id", 126 [ 127 ( 128 FarmMemberClaimQueryBindValues::MemberPubkey { 129 member_pubkey: "member-pk".to_string() 130 }, 131 "member_pubkey", 132 "member-pk" 133 ), 134 ( 135 FarmMemberClaimQueryBindValues::FarmPubkey { 136 farm_pubkey: "farm-pk".to_string() 137 }, 138 "farm_pubkey", 139 "farm-pk" 140 ), 141 ] 142 ); 143 144 assert_query_bind_values!( 145 farm_tag_query_bind_values_cover_all_variants, 146 FarmTagQueryBindValues::Id { 147 id: "farm-tag-id".to_string() 148 }, 149 "id", 150 "farm-tag-id", 151 [ 152 ( 153 FarmTagQueryBindValues::FarmId { 154 farm_id: "farm-id".to_string() 155 }, 156 "farm_id", 157 "farm-id" 158 ), 159 ( 160 FarmTagQueryBindValues::Tag { 161 tag: "organic".to_string() 162 }, 163 "tag", 164 "organic" 165 ), 166 ] 167 ); 168 169 assert_query_bind_values!( 170 gcs_location_query_bind_values_cover_all_variants, 171 GcsLocationQueryBindValues::Id { 172 id: "gcs-location-id".to_string() 173 }, 174 "id", 175 "gcs-location-id", 176 [ 177 ( 178 GcsLocationQueryBindValues::DTag { 179 d_tag: "gcs-d".to_string() 180 }, 181 "d_tag", 182 "gcs-d" 183 ), 184 ( 185 GcsLocationQueryBindValues::Geohash { 186 geohash: "9q8yy".to_string() 187 }, 188 "geohash", 189 "9q8yy" 190 ), 191 ] 192 ); 193 194 assert_query_bind_values!( 195 log_error_query_bind_values_cover_all_variants, 196 LogErrorQueryBindValues::Id { 197 id: "log-error-id".to_string() 198 }, 199 "id", 200 "log-error-id", 201 [( 202 LogErrorQueryBindValues::NostrPubkey { 203 nostr_pubkey: "nostr-pk".to_string() 204 }, 205 "nostr_pubkey", 206 "nostr-pk" 207 ),] 208 ); 209 210 assert_query_bind_values!( 211 media_image_query_bind_values_cover_all_variants, 212 MediaImageQueryBindValues::Id { 213 id: "media-image-id".to_string() 214 }, 215 "id", 216 "media-image-id", 217 [( 218 MediaImageQueryBindValues::FilePath { 219 file_path: "/tmp/a.jpg".to_string() 220 }, 221 "file_path", 222 "/tmp/a.jpg" 223 ),] 224 ); 225 226 assert_query_bind_values!( 227 nostr_event_head_query_bind_values_cover_all_variants, 228 NostrEventHeadQueryBindValues::Id { 229 id: "nostr-event-state-id".to_string() 230 }, 231 "id", 232 "nostr-event-state-id", 233 [( 234 NostrEventHeadQueryBindValues::Key { 235 key: "event-key".to_string() 236 }, 237 "key", 238 "event-key" 239 ),] 240 ); 241 242 assert_query_bind_values!( 243 nostr_profile_query_bind_values_cover_all_variants, 244 NostrProfileQueryBindValues::Id { 245 id: "nostr-profile-id".to_string() 246 }, 247 "id", 248 "nostr-profile-id", 249 [( 250 NostrProfileQueryBindValues::PublicKey { 251 public_key: "nostr-public-key".to_string() 252 }, 253 "public_key", 254 "nostr-public-key" 255 ),] 256 ); 257 258 assert_query_bind_values!( 259 nostr_relay_query_bind_values_cover_all_variants, 260 NostrRelayQueryBindValues::Id { 261 id: "nostr-relay-id".to_string() 262 }, 263 "id", 264 "nostr-relay-id", 265 [( 266 NostrRelayQueryBindValues::Url { 267 url: "wss://relay.example.com".to_string() 268 }, 269 "url", 270 "wss://relay.example.com" 271 ),] 272 ); 273 274 assert_query_bind_values!( 275 plot_query_bind_values_cover_all_variants, 276 PlotQueryBindValues::Id { 277 id: "plot-id".to_string() 278 }, 279 "id", 280 "plot-id", 281 [ 282 ( 283 PlotQueryBindValues::DTag { 284 d_tag: "plot-d".to_string() 285 }, 286 "d_tag", 287 "plot-d" 288 ), 289 ( 290 PlotQueryBindValues::FarmId { 291 farm_id: "farm-id".to_string() 292 }, 293 "farm_id", 294 "farm-id" 295 ), 296 ] 297 ); 298 299 assert_query_bind_values!( 300 plot_gcs_location_query_bind_values_cover_all_variants, 301 PlotGcsLocationQueryBindValues::Id { 302 id: "plot-gcs-id".to_string() 303 }, 304 "id", 305 "plot-gcs-id", 306 [ 307 ( 308 PlotGcsLocationQueryBindValues::PlotId { 309 plot_id: "plot-id".to_string() 310 }, 311 "plot_id", 312 "plot-id" 313 ), 314 ( 315 PlotGcsLocationQueryBindValues::GcsLocationId { 316 gcs_location_id: "gcs-id".to_string() 317 }, 318 "gcs_location_id", 319 "gcs-id" 320 ), 321 ] 322 ); 323 324 assert_query_bind_values!( 325 plot_tag_query_bind_values_cover_all_variants, 326 PlotTagQueryBindValues::Id { 327 id: "plot-tag-id".to_string() 328 }, 329 "id", 330 "plot-tag-id", 331 [ 332 ( 333 PlotTagQueryBindValues::PlotId { 334 plot_id: "plot-id".to_string() 335 }, 336 "plot_id", 337 "plot-id" 338 ), 339 ( 340 PlotTagQueryBindValues::Tag { 341 tag: "steep".to_string() 342 }, 343 "tag", 344 "steep" 345 ), 346 ] 347 ); 348 349 assert_query_bind_values!( 350 trade_product_query_bind_values_cover_all_variants, 351 TradeProductQueryBindValues::Id { 352 id: "trade-product-id".to_string() 353 }, 354 "id", 355 "trade-product-id", 356 [] 357 ); 358 359 #[test] 360 fn schema_result_wrappers_cover_constructors_and_status_labels() { 361 assert_eq!( 362 ReplicaSchemaError::from("err-a".to_string()), 363 ReplicaSchemaError { 364 error: "err-a".to_string() 365 } 366 ); 367 assert_eq!( 368 ReplicaSchemaError::new("err-b".to_string()), 369 ReplicaSchemaError { 370 error: "err-b".to_string() 371 } 372 ); 373 assert_eq!( 374 ReplicaSchemaResult::new("result-a".to_string()), 375 ReplicaSchemaResult { 376 result: "result-a".to_string() 377 } 378 ); 379 380 let empty = ReplicaSchemaResultList::<String>::new(Vec::new()); 381 assert!(empty.is_empty()); 382 let filled = ReplicaSchemaResultList::new(vec!["row-a".to_string()]); 383 assert!(!filled.is_empty()); 384 assert_eq!(filled.results, vec!["row-a".to_string()]); 385 386 assert_eq!(ReplicaSchemaResultPass::new(true).status_label(), "pass"); 387 assert_eq!(ReplicaSchemaResultPass::new(false).status_label(), "fail"); 388 } 389 390 #[test] 391 fn checked_in_replica_schema_json_vectors_match_model_behavior() { 392 let vectors = 393 include_str!("../../../contracts/conformance/vectors/replica_schema/json_models.v1.json"); 394 let document: Value = serde_json::from_str(vectors).expect("replica schema vector json"); 395 let entries = document 396 .get("vectors") 397 .and_then(Value::as_array) 398 .expect("replica schema vectors"); 399 400 for entry in entries { 401 let kind = entry.get("kind").and_then(Value::as_str).expect("kind"); 402 let input_json = entry 403 .get("input") 404 .and_then(|input| input.get("json")) 405 .expect("input json") 406 .clone(); 407 let expected = entry.get("expected").expect("expected"); 408 match kind { 409 "replica_schema.farm_json.valid" => { 410 let farm: Farm = serde_json::from_value(input_json).expect("farm json"); 411 assert_eq!( 412 farm.id, 413 expected.get("id").and_then(Value::as_str).expect("farm id") 414 ); 415 } 416 "replica_schema.farm_json.invalid" => { 417 assert!(serde_json::from_value::<Farm>(input_json).is_err()); 418 } 419 "replica_schema.trade_product_json.valid" => { 420 let product: TradeProduct = 421 serde_json::from_value(input_json).expect("trade product json"); 422 assert_eq!( 423 product.id, 424 expected 425 .get("id") 426 .and_then(Value::as_str) 427 .expect("trade product id") 428 ); 429 } 430 "replica_schema.trade_product_json.invalid" => { 431 assert!(serde_json::from_value::<TradeProduct>(input_json).is_err()); 432 } 433 other => panic!("unknown replica schema vector kind {other}"), 434 } 435 } 436 }