use std::error::Error;
use std::path::Path;
use super::{Config, Credential};
const FIELDS: [&str; 8] = [
"server",
"channel",
"token_file",
"frame_bytes",
"record_bytes",
"reply_timeout_ms",
"flow_steps",
"request_bytes",
];
fn written(token: &Path, without: Option<&str>, zero: Option<&str>) -> String {
let mut top = String::new();
let mut limits = String::new();
for field in FIELDS {
if without == Some(field) {
continue;
}
let value = match field {
"server" => "\"127.0.0.1:4100\"".to_owned(),
"channel" => "\"events\"".to_owned(),
"token_file" => format!("{:?}", token.display().to_string()),
_ if zero == Some(field) => "0".to_owned(),
_ => "16".to_owned(),
};
if matches!(field, "server" | "channel" | "token_file") {
top.extend([field, " = ", value.as_str(), "\n"]);
} else {
limits.extend([field, " = ", value.as_str(), "\n"]);
}
}
format!("{top}\n[limits]\n{limits}")
}
#[test]
fn config_refuses_each_missing_or_zero_field_by_name() -> Result<(), Box<dyn Error>> {
let dir = tempfile::tempdir()?;
let token = dir.path().join("token");
std::fs::write(&token, "pass-bytes\n")?;
let path = dir.path().join("ticket.toml");
for field in FIELDS {
std::fs::write(&path, written(&token, Some(field), None))?;
let refusal = Config::load(&path).err().map(|e| e.to_string());
let refusal = refusal.ok_or("a missing field was accepted")?;
assert!(refusal.contains(field), "missing {field}: {refusal}");
}
for field in &FIELDS[3..] {
std::fs::write(&path, written(&token, None, Some(field)))?;
let refusal = Config::load(&path).err().map(|e| e.to_string());
let refusal = refusal.ok_or("a zero field was accepted")?;
assert!(refusal.contains(field), "zero {field}: {refusal}");
}
std::fs::write(&path, written(&token, None, None))?;
let config = Config::load(&path)?;
assert_eq!(config.limits.flow_steps, 16);
let Credential::Token(token) = &config.credential else {
return Err("a token_file configuration did not hold a token".into());
};
assert_eq!(token.as_str(), "pass-bytes");
Ok(())
}
#[test]
fn pass_bytes_appear_in_no_debug_and_no_error() -> Result<(), Box<dyn Error>> {
let dir = tempfile::tempdir()?;
let token = dir.path().join("token");
std::fs::write(&token, "distinct-pass-7f3a\n")?;
let path = dir.path().join("ticket.toml");
std::fs::write(&path, written(&token, None, None))?;
let config = Config::load(&path)?;
let debug = format!("{config:?}");
assert!(!debug.contains("distinct-pass-7f3a"), "{debug}");
assert!(debug.contains("Token(18 bytes)"), "{debug}");
std::fs::write(&token, "")?;
let refusal = Config::load(&path).err().map(|e| e.to_string());
let refusal = refusal.ok_or("an empty token was accepted")?;
assert!(refusal.contains("token file is empty"), "{refusal}");
Ok(())
}