pub trait BybitEndpointRouter {
fn rest_endpoint(&self) -> &'static str;
fn ws_public_endpoint(&self, category: &str) -> String;
fn ws_private_endpoint(&self) -> &str;
}
use super::Bybit;
impl BybitEndpointRouter for Bybit {
fn rest_endpoint(&self) -> &'static str {
if self.is_sandbox() {
"https://api-testnet.bybit.com"
} else {
"https://api.bybit.com"
}
}
fn ws_public_endpoint(&self, category: &str) -> String {
let urls = self.urls();
urls.ws_public_for_category(category)
}
fn ws_private_endpoint(&self) -> &str {
if self.is_sandbox() {
"wss://stream-testnet.bybit.com/v5/private"
} else {
"wss://stream.bybit.com/v5/private"
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::bybit::BybitOptions;
use ccxt_core::ExchangeConfig;
use ccxt_core::types::default_type::{DefaultSubType, DefaultType};
fn create_test_bybit() -> Bybit {
Bybit::new(ExchangeConfig::default()).unwrap()
}
fn create_sandbox_bybit() -> Bybit {
let config = ExchangeConfig {
sandbox: true,
..Default::default()
};
Bybit::new(config).unwrap()
}
#[test]
fn test_rest_endpoint_production() {
let bybit = create_test_bybit();
let url = bybit.rest_endpoint();
assert!(url.contains("api.bybit.com"));
assert!(!url.contains("testnet"));
}
#[test]
fn test_rest_endpoint_sandbox() {
let bybit = create_sandbox_bybit();
let url = bybit.rest_endpoint();
assert!(url.contains("api-testnet.bybit.com"));
}
#[test]
fn test_ws_public_endpoint_spot() {
let bybit = create_test_bybit();
let url = bybit.ws_public_endpoint("spot");
assert!(url.contains("stream.bybit.com"));
assert!(url.ends_with("/v5/public/spot"));
}
#[test]
fn test_ws_public_endpoint_linear() {
let bybit = create_test_bybit();
let url = bybit.ws_public_endpoint("linear");
assert!(url.contains("stream.bybit.com"));
assert!(url.ends_with("/v5/public/linear"));
}
#[test]
fn test_ws_public_endpoint_inverse() {
let bybit = create_test_bybit();
let url = bybit.ws_public_endpoint("inverse");
assert!(url.contains("stream.bybit.com"));
assert!(url.ends_with("/v5/public/inverse"));
}
#[test]
fn test_ws_public_endpoint_option() {
let bybit = create_test_bybit();
let url = bybit.ws_public_endpoint("option");
assert!(url.contains("stream.bybit.com"));
assert!(url.ends_with("/v5/public/option"));
}
#[test]
fn test_ws_public_endpoint_sandbox_spot() {
let bybit = create_sandbox_bybit();
let url = bybit.ws_public_endpoint("spot");
assert!(url.contains("stream-testnet.bybit.com"));
assert!(url.ends_with("/v5/public/spot"));
}
#[test]
fn test_ws_public_endpoint_sandbox_linear() {
let bybit = create_sandbox_bybit();
let url = bybit.ws_public_endpoint("linear");
assert!(url.contains("stream-testnet.bybit.com"));
assert!(url.ends_with("/v5/public/linear"));
}
#[test]
fn test_ws_private_endpoint_production() {
let bybit = create_test_bybit();
let url = bybit.ws_private_endpoint();
assert!(url.contains("stream.bybit.com"));
assert!(url.contains("/v5/private"));
assert!(!url.contains("testnet"));
}
#[test]
fn test_ws_private_endpoint_sandbox() {
let bybit = create_sandbox_bybit();
let url = bybit.ws_private_endpoint();
assert!(url.contains("stream-testnet.bybit.com"));
assert!(url.contains("/v5/private"));
}
#[test]
fn test_ws_public_endpoint_path_format() {
let bybit = create_test_bybit();
let categories = ["spot", "linear", "inverse", "option"];
for category in categories {
let url = bybit.ws_public_endpoint(category);
let expected_suffix = format!("/v5/public/{}", category);
assert!(
url.ends_with(&expected_suffix),
"URL {} should end with {}",
url,
expected_suffix
);
}
}
#[test]
fn test_rest_endpoint_with_testnet_option() {
let config = ExchangeConfig::default();
let options = BybitOptions {
testnet: true,
..Default::default()
};
let bybit = Bybit::new_with_options(config, options).unwrap();
let url = bybit.rest_endpoint();
assert!(url.contains("api-testnet.bybit.com"));
}
#[test]
fn test_ws_private_endpoint_with_testnet_option() {
let config = ExchangeConfig::default();
let options = BybitOptions {
testnet: true,
..Default::default()
};
let bybit = Bybit::new_with_options(config, options).unwrap();
let url = bybit.ws_private_endpoint();
assert!(url.contains("stream-testnet.bybit.com"));
}
#[test]
fn test_ws_public_endpoint_with_linear_default_type() {
let config = ExchangeConfig::default();
let options = BybitOptions {
default_type: DefaultType::Swap,
default_sub_type: Some(DefaultSubType::Linear),
..Default::default()
};
let bybit = Bybit::new_with_options(config, options).unwrap();
let category = bybit.category();
assert_eq!(category, "linear");
let url = bybit.ws_public_endpoint(category);
assert!(url.ends_with("/v5/public/linear"));
}
#[test]
fn test_ws_public_endpoint_with_inverse_default_type() {
let config = ExchangeConfig::default();
let options = BybitOptions {
default_type: DefaultType::Swap,
default_sub_type: Some(DefaultSubType::Inverse),
..Default::default()
};
let bybit = Bybit::new_with_options(config, options).unwrap();
let category = bybit.category();
assert_eq!(category, "inverse");
let url = bybit.ws_public_endpoint(category);
assert!(url.ends_with("/v5/public/inverse"));
}
}