diff --git a/src/ws/sub_structs.rs b/src/ws/sub_structs.rs index 4c3c94e5..53d13547 100644 --- a/src/ws/sub_structs.rs +++ b/src/ws/sub_structs.rs @@ -332,6 +332,10 @@ pub struct SpotAssetCtx { #[serde(flatten)] pub shared: SharedAssetCtx, pub circulating_supply: String, + #[serde(default)] + pub total_supply: Option, + #[serde(default)] + pub day_base_vlm: Option, } #[derive(Deserialize, Serialize, Clone, Debug)] diff --git a/src/ws/ws_manager.rs b/src/ws/ws_manager.rs index 4035baf3..e48b8c3c 100755 --- a/src/ws/ws_manager.rs +++ b/src/ws/ws_manager.rs @@ -495,3 +495,85 @@ impl Drop for WsManager { self.stop_flag.store(true, Ordering::Relaxed); } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn active_spot_asset_ctx_deserializes_and_maps_identifier() { + let json = r#"{ + "channel": "activeSpotAssetCtx", + "data": { + "coin": "@107", + "ctx": { + "prevDayPx": "23.993", + "dayNtlVlm": "228614808.04913011", + "markPx": "23.277", + "midPx": "23.281", + "circulatingSupply": "334395529.28086698", + "coin": "@107", + "totalSupply": "999840322.48575342", + "dayBaseVlm": "9756716.93999999" + } + } + }"#; + + let msg: Message = serde_json::from_str(json).expect("sample activeSpotAssetCtx JSON"); + match &msg { + Message::ActiveSpotAssetCtx(spot) => { + assert_eq!(spot.data.coin, "@107"); + assert_eq!( + spot.data.ctx.total_supply.as_deref(), + Some("999840322.48575342") + ); + assert_eq!( + spot.data.ctx.day_base_vlm.as_deref(), + Some("9756716.93999999") + ); + } + other => panic!("expected ActiveSpotAssetCtx, got {other:?}"), + } + + assert_eq!( + WsManager::get_identifier(&msg).unwrap(), + serde_json::to_string(&Subscription::ActiveAssetCtx { + coin: "@107".into() + }) + .unwrap() + ); + } + + #[test] + fn active_asset_ctx_perps_maps_identifier() { + let json = r#"{ + "channel": "activeAssetCtx", + "data": { + "coin": "BTC", + "ctx": { + "funding": "0.0001", + "openInterest": "1000.0", + "oraclePx": "50000.0", + "dayNtlVlm": "1.0", + "prevDayPx": "49000.0", + "markPx": "50000.0", + "midPx": "50000.0" + } + } + }"#; + + let msg: Message = serde_json::from_str(json).expect("minimal perps activeAssetCtx JSON"); + match &msg { + Message::ActiveAssetCtx(_) => {} + other => panic!("expected ActiveAssetCtx, got {other:?}"), + } + + assert_eq!( + WsManager::get_identifier(&msg).unwrap(), + serde_json::to_string(&Subscription::ActiveAssetCtx { + coin: "BTC".into() + }) + .unwrap() + ); + } +}