use super::*;
fn pair() -> OrderBookConfig {
let mut config: MarketsConfigPartial =
serde_json::from_str(include_str!("../tests/fixtures/sidecar-markets.json"))
.unwrap();
let mut pair = config.pairs.remove(0);
pair.contract_id = Some(ContractId::new([1; 32]));
pair.sidecar.as_mut().unwrap().contract_id = Some(ContractId::new([2; 32]));
pair
}
#[test]
fn sidecar_selection_survives_config_roundtrip() {
let mut json: serde_json::Value =
serde_json::from_str(super::tests::LIVE_LEGACY_TIER).unwrap();
json["sidecar"] = serde_json::json!(true);
let tier: MarginTierConfig = serde_json::from_value(json).unwrap();
assert!(tier.sidecar);
let copy: MarginTierConfig =
serde_json::from_value(serde_json::to_value(tier).unwrap()).unwrap();
assert!(copy.sidecar);
}
#[test]
fn markets_resolve_to_the_selected_venue_by_symbol_or_market_id() {
let pair = pair();
let names = [
"BTC/USDT".to_owned(),
" btc/usdt ".to_owned(),
hex::encode(*pair.market_id),
format!("0x{}", hex::encode(*pair.market_id)),
];
for name in names {
for (sidecar, expected) in [
(false, pair.contract_id.unwrap()),
(true, pair.sidecar.as_ref().unwrap().contract_id.unwrap()),
] {
assert_eq!(
resolve_tier_market(&name, std::slice::from_ref(&pair), sidecar).unwrap(),
expected,
);
}
}
}
#[test]
fn missing_sidecars_never_fall_back_to_canonical() {
let mut pair = pair();
pair.sidecar.as_mut().unwrap().contract_id = None;
for sidecar in [pair.sidecar.clone(), None] {
pair.sidecar = sidecar;
let err = resolve_tier_market("BTC/USDT", std::slice::from_ref(&pair), true)
.unwrap_err();
assert!(err.to_string().contains("BTC/USDT"), "{err}");
assert!(err.to_string().contains("no deployed sidecar"), "{err}");
assert_eq!(
resolve_tier_market("BTC/USDT", std::slice::from_ref(&pair), false).unwrap(),
pair.contract_id.unwrap(),
);
}
}
#[test]
fn unknown_markets_and_missing_canonical_books_are_rejected() {
let mut pair = pair();
for sidecar in [false, true] {
let err =
resolve_tier_market("UNKNOWN/USDT", std::slice::from_ref(&pair), sidecar)
.unwrap_err();
assert!(err.to_string().contains("unknown market"), "{err}");
}
pair.contract_id = None;
let err = resolve_tier_market("BTC/USDT", &[pair], false).unwrap_err();
assert!(err.to_string().contains("no deployed order book"), "{err}");
}
#[test]
fn switching_venues_replaces_the_allowlist_in_both_directions() {
let pair = pair();
let canonical = pair.contract_id.unwrap();
let house = pair.sidecar.as_ref().unwrap().contract_id.unwrap();
let pairs = [pair];
assert!(tier_book_route_changed(true, &pairs, &[canonical]));
assert!(tier_book_route_changed(false, &pairs, &[house]));
assert!(tier_book_route_changed(true, &pairs, &[canonical, house]));
assert!(tier_book_route_changed(false, &pairs, &[canonical, house]));
assert!(!tier_book_route_changed(false, &pairs, &[canonical]));
assert!(!tier_book_route_changed(true, &pairs, &[house]));
assert!(!tier_book_route_changed(true, &pairs, &[]));
}