Ver código fonte

fix(cashu): skip serializing empty NUT15 settings in mint info (#1158)

Add is_empty method to nut15::Settings and configure skip_serializing_if
attribute to prevent empty NUT15 objects from appearing in serialized
mint info responses.
tsk 1 mês atrás
pai
commit
c30a078a12
2 arquivos alterados com 56 adições e 0 exclusões
  1. 35 0
      crates/cashu/src/nuts/nut06.rs
  2. 21 0
      crates/cashu/src/nuts/nut15.rs

+ 35 - 0
crates/cashu/src/nuts/nut06.rs

@@ -313,6 +313,7 @@ pub struct Nuts {
     /// NUT15 Settings
     #[serde(default)]
     #[serde(rename = "15")]
+    #[serde(skip_serializing_if = "nut15::Settings::is_empty")]
     pub nut15: nut15::Settings,
     /// NUT17 Settings
     #[serde(default)]
@@ -676,4 +677,38 @@ mod tests {
 
         assert_eq!(info, mint_info);
     }
+
+    #[test]
+    fn test_nut15_not_serialized_when_empty() {
+        // Test with default (empty) NUT15
+        let mint_info = MintInfo {
+            name: Some("Test Mint".to_string()),
+            nuts: Nuts::default(),
+            ..Default::default()
+        };
+
+        let json = serde_json::to_string(&mint_info).unwrap();
+        let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
+
+        // NUT15 should not be present in the nuts object when methods is empty
+        assert!(parsed["nuts"]["15"].is_null());
+
+        // Test with non-empty NUT15
+        let mint_info_with_nut15 = MintInfo {
+            name: Some("Test Mint".to_string()),
+            nuts: Nuts::default().nut15(vec![MppMethodSettings {
+                method: crate::PaymentMethod::Bolt11,
+                unit: crate::CurrencyUnit::Sat,
+            }]),
+            ..Default::default()
+        };
+
+        let json = serde_json::to_string(&mint_info_with_nut15).unwrap();
+        let parsed: serde_json::Value = serde_json::from_str(&json).unwrap();
+
+        // NUT15 should be present when methods is not empty
+        assert!(!parsed["nuts"]["15"].is_null());
+        assert!(parsed["nuts"]["15"]["methods"].is_array());
+        assert_eq!(parsed["nuts"]["15"]["methods"].as_array().unwrap().len(), 1);
+    }
 }

+ 21 - 0
crates/cashu/src/nuts/nut15.rs

@@ -34,6 +34,13 @@ pub struct Settings {
     pub methods: Vec<MppMethodSettings>,
 }
 
+impl Settings {
+    /// Check if methods is empty
+    pub fn is_empty(&self) -> bool {
+        self.methods.is_empty()
+    }
+}
+
 // Custom deserialization to handle both array and object formats
 impl<'de> Deserialize<'de> for Settings {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -89,4 +96,18 @@ mod tests {
         let json = serde_json::to_string(&settings).unwrap();
         assert_eq!(json, r#"{"methods":[{"method":"bolt11","unit":"sat"}]}"#);
     }
+
+    #[test]
+    fn test_nut15_settings_empty() {
+        let settings = Settings { methods: vec![] };
+        assert!(settings.is_empty());
+
+        let settings_with_data = Settings {
+            methods: vec![MppMethodSettings {
+                method: PaymentMethod::Bolt11,
+                unit: CurrencyUnit::Sat,
+            }],
+        };
+        assert!(!settings_with_data.is_empty());
+    }
 }