lib

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

capability_status.rs (4968B)


      1 use radroots_transport::{
      2     SinkStatus, SourceStatus, TransportId,
      3     capability::{Availability, Maturity, SinkCapabilities, SourceCapabilities},
      4 };
      5 
      6 #[test]
      7 fn maturity_and_availability_round_trip_through_protocol_dtos() {
      8     for maturity in [Maturity::Experimental, Maturity::Preview, Maturity::Stable] {
      9         let protocol = radroots_protocol::capability::v1::Maturity::from(maturity);
     10         assert_eq!(Maturity::from(protocol), maturity);
     11     }
     12 
     13     for availability in [
     14         Availability::Available,
     15         Availability::Degraded,
     16         Availability::Unavailable,
     17     ] {
     18         let protocol = radroots_protocol::capability::v1::Availability::from(availability);
     19         assert_eq!(Availability::from(protocol), availability);
     20     }
     21 }
     22 
     23 #[test]
     24 fn runtime_state_dimensions_are_independent() {
     25     let transport_id = TransportId::parse("future-mesh").expect("custom transport");
     26     let states = [
     27         (false, Maturity::Experimental, Availability::Available),
     28         (true, Maturity::Preview, Availability::Degraded),
     29         (true, Maturity::Stable, Availability::Unavailable),
     30     ];
     31 
     32     for (configured, maturity, availability) in states {
     33         let status = SourceStatus::new(
     34             transport_id,
     35             configured,
     36             maturity,
     37             availability,
     38             SourceCapabilities::NONE,
     39             "explicit state",
     40         );
     41         assert_eq!(status.transport_id(), transport_id);
     42         assert_eq!(status.is_configured(), configured);
     43         assert_eq!(status.maturity(), maturity);
     44         assert_eq!(status.availability(), availability);
     45         assert_eq!(status.message(), "explicit state");
     46     }
     47 }
     48 
     49 #[test]
     50 fn source_and_sink_capabilities_are_separate_contracts() {
     51     let source = SourceStatus::new(
     52         TransportId::NOSTR,
     53         true,
     54         Maturity::Stable,
     55         Availability::Available,
     56         SourceCapabilities::FETCH.with_discovery(true),
     57         "source",
     58     );
     59     assert!(source.capabilities().can_fetch());
     60     assert!(source.capabilities().can_discover());
     61     assert_eq!(source.transport_id(), TransportId::NOSTR);
     62 
     63     let sink = SinkStatus::new(
     64         TransportId::NOSTR,
     65         true,
     66         Maturity::Stable,
     67         Availability::Available,
     68         SinkCapabilities::DELIVER
     69             .with_gateway_forwarding(true)
     70             .with_receipt_observation(true),
     71         "sink",
     72     );
     73     assert!(sink.capabilities().can_deliver());
     74     assert!(sink.capabilities().can_gateway_forward());
     75     assert!(sink.capabilities().can_observe_receipts());
     76     assert_eq!(sink.transport_id(), TransportId::NOSTR);
     77 }
     78 
     79 #[test]
     80 fn protocol_descriptors_preserve_unknown_transports_and_split_capabilities() {
     81     use radroots_protocol::capability::v1::{
     82         Availability as ProtocolAvailability, Maturity as ProtocolMaturity, TransportDescriptor,
     83         TransportKind,
     84     };
     85 
     86     let descriptor = TransportDescriptor {
     87         kind: TransportKind::parse("future-mesh").expect("custom protocol transport"),
     88         maturity: ProtocolMaturity::Experimental,
     89         availability: ProtocolAvailability::Degraded,
     90         can_deliver: true,
     91         can_fetch: false,
     92         can_discover: true,
     93         can_gateway_forward: true,
     94         can_observe_receipts: false,
     95         required_for_v1: false,
     96     };
     97 
     98     let source = SourceStatus::from_descriptor(&descriptor, false, "source not configured");
     99     assert_eq!(source.transport_id().as_str(), "future-mesh");
    100     assert!(!source.is_configured());
    101     assert_eq!(source.maturity(), Maturity::Experimental);
    102     assert_eq!(source.availability(), Availability::Degraded);
    103     assert!(!source.capabilities().can_fetch());
    104     assert!(source.capabilities().can_discover());
    105 
    106     let sink = SinkStatus::from_descriptor(&descriptor, true, "sink configured");
    107     assert_eq!(sink.transport_id().as_str(), "future-mesh");
    108     assert!(sink.is_configured());
    109     assert!(sink.capabilities().can_deliver());
    110     assert!(sink.capabilities().can_gateway_forward());
    111     assert!(!sink.capabilities().can_observe_receipts());
    112 }
    113 
    114 #[cfg(feature = "serde")]
    115 #[test]
    116 fn experimental_maturity_has_a_stable_wire_spelling() {
    117     assert_eq!(
    118         serde_json::to_string(&Maturity::Experimental).expect("serialize maturity"),
    119         "\"experimental\""
    120     );
    121     assert_eq!(
    122         serde_json::from_str::<Maturity>("\"experimental\"").expect("deserialize maturity"),
    123         Maturity::Experimental
    124     );
    125 
    126     let status = SourceStatus::new(
    127         TransportId::parse("future-mesh").expect("custom transport"),
    128         true,
    129         Maturity::Experimental,
    130         Availability::Degraded,
    131         SourceCapabilities::FETCH,
    132         "degraded source",
    133     );
    134     let encoded = serde_json::to_string(&status).expect("serialize source status");
    135     assert!(encoded.contains("\"transport_id\":\"future-mesh\""));
    136     assert_eq!(
    137         serde_json::from_str::<SourceStatus>(&encoded).expect("deserialize source status"),
    138         status
    139     );
    140 }