use deribit_websocket::client::DeribitWebSocketClient;
use deribit_websocket::config::WebSocketConfig;
#[test]
fn test_client_creation() {
let config = WebSocketConfig::default();
let result = DeribitWebSocketClient::new(&config);
assert!(result.is_ok());
}
#[test]
fn test_client_creation_with_custom_config() {
let config = WebSocketConfig::default()
.with_heartbeat_interval(std::time::Duration::from_secs(60))
.with_max_reconnect_attempts(10);
let result = DeribitWebSocketClient::new(&config);
assert!(result.is_ok());
}
#[test]
fn test_client_new_default() {
let config = WebSocketConfig::default();
let result = DeribitWebSocketClient::new(&config);
assert!(result.is_ok());
}
#[test]
fn test_client_new_production() {
let result = DeribitWebSocketClient::new_production();
assert!(result.is_ok());
}
#[test]
fn test_client_new_with_url() {
let result =
DeribitWebSocketClient::new_with_url("wss://test.deribit.com/ws/api/v2".to_string());
assert!(result.is_ok());
}
#[test]
fn test_client_new_with_invalid_url() {
let result = DeribitWebSocketClient::new_with_url("invalid-url".to_string());
assert!(result.is_err());
}
#[tokio::test]
async fn test_client_initial_connection_state() {
let config = WebSocketConfig::default();
let client = DeribitWebSocketClient::new(&config).unwrap();
assert!(!client.is_connected().await);
}
#[tokio::test]
async fn test_client_subscription_management() {
let config = WebSocketConfig::default();
let client = DeribitWebSocketClient::new(&config).unwrap();
let subscriptions = client.get_subscriptions().await;
assert!(subscriptions.is_empty());
}
#[test]
fn test_client_message_handler_management() {
let config = WebSocketConfig::default();
let mut client = DeribitWebSocketClient::new(&config).unwrap();
assert!(!client.has_message_handler());
client.set_message_handler(|_message| Ok(()), |_message, _error| {});
assert!(client.has_message_handler());
client.clear_message_handler();
assert!(!client.has_message_handler());
}
#[test]
fn test_client_debug() {
let config = WebSocketConfig::default();
let client = DeribitWebSocketClient::new(&config).unwrap();
let debug_str = format!("{:?}", client);
assert!(debug_str.contains("DeribitWebSocketClient"));
}
#[test]
fn test_client_parse_channel_type() {
use deribit_websocket::model::SubscriptionChannel;
assert_eq!(
SubscriptionChannel::from_string("ticker.BTC-PERPETUAL"),
SubscriptionChannel::Ticker("BTC-PERPETUAL".to_string())
);
assert_eq!(
SubscriptionChannel::from_string("book.ETH-PERPETUAL.raw"),
SubscriptionChannel::OrderBook("ETH-PERPETUAL".to_string())
);
assert_eq!(
SubscriptionChannel::from_string("trades.BTC-PERPETUAL.raw"),
SubscriptionChannel::Trades("BTC-PERPETUAL".to_string())
);
assert!(SubscriptionChannel::from_string("totally.unknown.channel").is_unknown());
}
#[tokio::test]
async fn test_client_connect_honors_connection_timeout() {
use deribit_websocket::error::WebSocketError;
use std::time::Duration;
use tokio::net::TcpListener;
let listener = TcpListener::bind("127.0.0.1:0")
.await
.expect("bind ephemeral localhost port");
let addr = listener.local_addr().expect("read local addr");
let _server = tokio::spawn(async move {
if let Ok((socket, _)) = listener.accept().await {
tokio::time::sleep(Duration::from_secs(2)).await;
drop(socket);
}
});
let config = WebSocketConfig::with_url(&format!("ws://{}/", addr))
.expect("valid ws url")
.with_connection_timeout(Duration::from_millis(150));
let client = DeribitWebSocketClient::new(&config).expect("client constructs");
let start = std::time::Instant::now();
let result = client.connect().await;
let elapsed = start.elapsed();
assert!(
matches!(result, Err(WebSocketError::Timeout(_))),
"expected Timeout from stalled handshake, got {:?}",
result
);
assert!(
elapsed < Duration::from_millis(500),
"timeout should fire near 150ms, elapsed = {:?}",
elapsed
);
}
#[test]
fn test_client_extract_instrument() {
use deribit_websocket::model::SubscriptionChannel;
for original in [
SubscriptionChannel::Ticker("BTC-PERPETUAL".to_string()),
SubscriptionChannel::OrderBook("ETH-PERPETUAL".to_string()),
SubscriptionChannel::Trades("BTC-PERPETUAL".to_string()),
SubscriptionChannel::Quote("SOL-PERPETUAL".to_string()),
] {
let channel_name = original.channel_name();
let reparsed = SubscriptionChannel::from_string(&channel_name);
assert_eq!(
original, reparsed,
"channel {} must survive a round-trip through from_string",
channel_name
);
}
}