mod common;
use std::fmt::Debug;
struct Check {
name: &'static str,
result: Result<String, String>,
}
fn summarize<T: Debug>(
result: Result<T, esi_openapi::prelude::EsiError>,
) -> Result<String, String> {
match result {
Ok(value) => {
let text = format!("{value:?}");
let short: String = text.chars().take(80).collect();
Ok(if text.len() > 80 {
format!("{short}...")
} else {
short
})
}
Err(e) => Err(format!("{e} ({e:?})")),
}
}
#[tokio::test]
async fn authenticated_endpoints() {
let cfg = match common::load() {
Ok(cfg) => cfg,
Err(reason) => {
eprintln!("skipping authenticated tests: {reason}");
return;
}
};
let (esi, character_id) = match common::authenticated_esi(&cfg).await {
Ok(v) => v,
Err(reason) if reason.starts_with("missing") => {
eprintln!("skipping authenticated tests: {reason}");
return;
}
Err(reason) => panic!("{reason}"),
};
println!("Testing as character {character_id}");
let mut checks = Vec::new();
macro_rules! check {
($name:literal, $call:expr) => {
checks.push(Check {
name: $name,
result: summarize($call.await),
});
};
}
check!("skills", esi.group_skills().get_skills(character_id));
check!("wallet", esi.group_wallet().get_wallet(character_id));
check!(
"wallet transactions",
esi.group_character().get_wallet_transactions(character_id)
);
check!("location", esi.group_location().get_location(character_id));
check!("online", esi.group_location().get_online(character_id));
check!("ship", esi.group_location().get_ship(character_id));
check!("clones", esi.group_clones().get_clones(character_id));
check!(
"implants",
esi.group_clones().get_clone_implants(character_id)
);
check!(
"blueprints",
esi.group_character().get_blueprints(character_id)
);
check!(
"notifications",
esi.group_character().get_notifications(character_id)
);
check!(
"mail labels",
esi.group_mail().get_character_mail_labels(character_id)
);
check!(
"market orders",
esi.group_market().get_character_orders(character_id)
);
check!(
"industry jobs",
esi.group_industry()
.get_character_industry_jobs(character_id, Some(true))
);
check!(
"recent killmails",
esi.group_killmails().get_character_recent(character_id)
);
check!(
"search",
esi.group_search().search(
character_id,
"solar_system".to_owned(),
"Jita".to_owned(),
Some(true)
)
);
let assets = esi.group_assets().get_character_assets(character_id).await;
let singleton_ids: Vec<i64> = match &assets {
Ok(items) => items
.iter()
.filter(|a| a.is_singleton)
.take(5)
.map(|a| a.item_id)
.collect(),
Err(_) => Vec::new(),
};
checks.push(Check {
name: "assets",
result: summarize(assets.map(|a| a.len())),
});
if singleton_ids.is_empty() {
println!("SKIP asset locations/names: no singleton assets");
} else {
let unsigned: Vec<u64> = singleton_ids.iter().map(|&id| id as u64).collect();
check!(
"asset locations",
esi.group_assets()
.get_character_assets_locations(character_id, &singleton_ids)
);
check!(
"asset names",
esi.group_assets()
.get_character_assets_names(character_id, &unsigned)
);
}
match cfg.structure_id {
Some(structure_id) => {
check!(
"structure",
esi.group_universe().get_structure(structure_id)
);
}
None => println!("SKIP structure: ESI_TEST_STRUCTURE_ID not set"),
}
let mut failures = 0;
for check in &checks {
match &check.result {
Ok(summary) => println!("OK {}: {summary}", check.name),
Err(error) => {
failures += 1;
println!("FAIL {}: {error}", check.name);
}
}
}
println!("Rate limits: {:?}", esi.rate_limit_statuses().await);
assert_eq!(failures, 0, "{failures} of {} checks failed", checks.len());
}