mod common;
use common::{get, sandbox, start};
const ALL_DAILY: &str = "tool=pi&bucket=daily&window=all";
#[tokio::test]
async fn costs_follow_the_selected_currency_and_it_is_remembered() {
let addr = start().await;
let settings = sandbox().config.join("settings.json");
let usd = get(addr, &format!("/?{ALL_DAILY}")).await.body;
assert!(
usd.contains("$0.75") || usd.contains("$0.5"),
"dollar costs: {usd}"
);
assert!(!usd.contains("cost ≈"));
assert!(usd.contains("name=\"currency\""), "the selector is there");
for code in ["USD", "EUR", "GBP", "JPY", "CHF"] {
assert!(
usd.contains(&format!("value=\"{code}\"")),
"{code} is offered"
);
}
let eur = get(addr, &format!("/?{ALL_DAILY}¤cy=EUR&metric=cost"))
.await
.body;
assert!(eur.contains(">€1.38<"), "1.50 USD at 0.92: {eur}");
assert!(eur.contains("cost ≈"), "built-in rates are estimates");
assert!(
!eur.contains(">$0."),
"no dollar amounts left in the cards and tables"
);
let cost_chart = get(addr, &format!("/?{ALL_DAILY}¤cy=EUR&metric=cost"))
.await
.body;
assert!(cost_chart.contains('€') && cost_chart.contains("Cost over time"));
assert!(!cost_chart.contains(">$"), "axis labels are in euros");
let saved = std::fs::read_to_string(&settings).unwrap();
assert!(saved.contains("\"currency\": \"EUR\""), "{saved}");
let again = get(addr, &format!("/?{ALL_DAILY}")).await.body;
assert!(
again.contains('€'),
"the saved currency applies on the next visit"
);
assert!(
again.contains("<option value=\"EUR\" selected=\"\">"),
"the selector shows the current one"
);
let jpy = get(addr, &format!("/?{ALL_DAILY}¤cy=jpy")).await.body;
assert!(jpy.contains('¥') && !jpy.contains("¥0."), "{jpy}");
let junk = get(addr, &format!("/?{ALL_DAILY}¤cy=%3Cscript%3E")).await;
assert_eq!(junk.status, 200);
assert!(!junk.body.contains("<script>") && junk.body.contains('¥'));
std::fs::write(&settings, r#"{"currency":"EUR","rates":{"EUR":2.0}}"#).unwrap();
let own = get(addr, &format!("/?{ALL_DAILY}")).await.body;
assert!(own.contains(">€3.00<"), "1.50 USD at 2.0: {own}");
assert!(!own.contains("cost ≈"), "your own rate is not an estimate");
let back = get(addr, &format!("/?{ALL_DAILY}¤cy=USD")).await.body;
assert!(back.contains(">$1.50<") && !back.contains('€'));
let api = get(addr, &format!("/api/report?{ALL_DAILY}¤cy=EUR"))
.await
.body;
assert!(api.contains("cost_usd"));
}