use serde::de::DeserializeOwned;
use serde_json::Value;
use std::collections::HashMap;
#[derive(serde::Deserialize)]
struct Fixture {
#[serde(rename = "operationId")]
operation_id: String,
value: Value,
#[serde(rename = "exampleName")]
example_name: String,
}
fn load_fixtures() -> HashMap<String, Vec<Fixture>> {
let raw = include_str!("fixtures/examples.json");
let items: Vec<Fixture> = serde_json::from_str(raw).expect("fixtures load");
let mut by_op: HashMap<String, Vec<Fixture>> = HashMap::new();
for item in items {
by_op
.entry(item.operation_id.clone())
.or_default()
.push(item);
}
by_op
}
fn assert_deserialises<T: DeserializeOwned>(op_id: &str, fixtures: &HashMap<String, Vec<Fixture>>) {
let cases = fixtures
.get(op_id)
.unwrap_or_else(|| panic!("no fixtures for operationId {op_id}"));
assert!(
!cases.is_empty(),
"fixtures/examples.json has no entries for {op_id}"
);
for case in cases {
let result: Result<T, _> = serde_json::from_value(case.value.clone());
if let Err(e) = &result {
panic!(
"deserialise failed for {op_id}/{}: {e}\n payload: {}",
case.example_name, case.value
);
}
}
}
#[test]
fn portfolio_summary_example_deserialises() {
let fixtures = load_fixtures();
assert_deserialises::<bezant_api::PortfolioSummary>("getPortfolioSummary", &fixtures);
}
#[test]
fn account_summary_example_deserialises() {
let fixtures = load_fixtures();
assert_deserialises::<bezant_api::AccountSummaryResponse>("getAccountSummary", &fixtures);
}
#[test]
fn paginated_positions_example_deserialises() {
let fixtures = load_fixtures();
assert_deserialises::<Vec<bezant_api::IndividualPosition>>("getPaginatedPositions", &fixtures);
}
#[test]
fn fixtures_cover_expected_operations() {
let fixtures = load_fixtures();
for op in [
"getPortfolioSummary",
"getAccountSummary",
"getPaginatedPositions",
] {
assert!(
fixtures.contains_key(op),
"fixtures/examples.json missing operation {op}"
);
}
}