error_mapping.rs (3988B)
1 #![cfg(feature = "nostr-client")] 2 3 use std::{sync::mpsc, time::Duration}; 4 5 use radroots_field_core::runtime::trade_listing::TradeListingDraft; 6 use radroots_field_core::{RadrootsAppError, RadrootsRuntime}; 7 8 #[test] 9 fn invalid_host_custody_secret_maps_to_identity_error() { 10 let runtime = RadrootsRuntime::new().expect("runtime"); 11 12 let err = runtime 13 .nostr_identity_validate_host_custody_secret("not-a-secret".to_string()) 14 .expect_err("invalid secret should fail"); 15 16 assert!(matches!(err, RadrootsAppError::Identity(_))); 17 } 18 19 #[test] 20 fn uninitialized_nostr_publish_maps_to_relay_error() { 21 let runtime = RadrootsRuntime::new().expect("runtime"); 22 23 let err = runtime 24 .nostr_post_text_note("hello".to_string()) 25 .expect_err("uninitialized nostr should fail"); 26 27 assert!(matches!( 28 err, 29 RadrootsAppError::Relay(message) if message == "nostr not initialized" 30 )); 31 } 32 33 #[test] 34 fn profile_read_without_identity_maps_to_identity_error() { 35 let runtime = RadrootsRuntime::new().expect("runtime"); 36 37 let err = runtime 38 .nostr_profile_for_self() 39 .expect_err("missing identity should fail"); 40 41 assert!(matches!(err, RadrootsAppError::Identity(_))); 42 } 43 44 #[test] 45 fn profile_read_without_initialized_nostr_maps_to_relay_error() { 46 let runtime = RadrootsRuntime::new().expect("runtime"); 47 let identity = radroots_identity::RadrootsIdentity::generate(); 48 runtime 49 .nostr_identity_restore_host_custody_secret( 50 identity.secret_key_hex(), 51 Some("field".to_string()), 52 true, 53 ) 54 .expect("restore identity"); 55 56 let err = runtime 57 .nostr_profile_for_self() 58 .expect_err("uninitialized nostr should fail"); 59 60 assert!(matches!( 61 err, 62 RadrootsAppError::Relay(message) if message == "nostr not initialized" 63 )); 64 } 65 66 #[test] 67 fn post_stream_read_without_started_stream_returns_no_data() { 68 let runtime = RadrootsRuntime::new().expect("runtime"); 69 70 let event = runtime 71 .nostr_next_post_event() 72 .expect("missing stream should be a no-data state"); 73 74 assert!(event.is_none()); 75 } 76 77 #[test] 78 fn trade_listing_publish_with_initialized_nostr_does_not_relock_runtime() { 79 let runtime = RadrootsRuntime::new().expect("runtime"); 80 let identity = radroots_identity::RadrootsIdentity::generate(); 81 let public_key_hex = identity.public_key_hex(); 82 runtime 83 .nostr_identity_restore_host_custody_secret( 84 identity.secret_key_hex(), 85 Some("field".to_string()), 86 true, 87 ) 88 .expect("restore identity"); 89 runtime 90 .nostr_set_default_relays(Vec::new()) 91 .expect("initialize nostr manager"); 92 let draft = TradeListingDraft { 93 listing_id: Some("AAAAAAAAAAAAAAAAAAAAAg".to_string()), 94 farm_pubkey: public_key_hex, 95 farm_d_tag: "AAAAAAAAAAAAAAAAAAAAAQ".to_string(), 96 title: "Carrots".to_string(), 97 description: "Fresh carrots".to_string(), 98 category: "produce".to_string(), 99 bin_display_amount: "1".to_string(), 100 bin_display_unit: "lb".to_string(), 101 unit_price: "3.50".to_string(), 102 currency: "USD".to_string(), 103 bin_label: None, 104 bin_id: Some("bin-1".to_string()), 105 inventory: "10".to_string(), 106 delivery_method: "pickup".to_string(), 107 location_primary: "farm stand".to_string(), 108 location_city: None, 109 location_region: None, 110 location_country: None, 111 }; 112 let (tx, rx) = mpsc::channel(); 113 std::thread::spawn(move || { 114 let result = runtime.trade_listing_publish(draft); 115 let _ = tx.send(result); 116 }); 117 118 let result = rx 119 .recv_timeout(Duration::from_secs(3)) 120 .expect("publish must return instead of re-locking the runtime"); 121 122 match result { 123 Ok(_) | Err(RadrootsAppError::Relay(_)) => {} 124 other => panic!("unexpected publish result: {other:?}"), 125 } 126 }