use super::*;
const BOTH: &str = "agents are written once: at the top level or under [auth.lys], not both";
fn lys_auth(agents: &str) -> Result<AuthConfig, Box<dyn std::error::Error>> {
Ok(toml::from_str(&format!(
"token = \"s3cr3t\"\n[lys]\nissuer = \"https://lys.test\"\nnetwork_id = \"n\"\n\
keys_path = \"/k\"\napp_credential_path = \"/c\"\n{agents}"
))?)
}
#[test]
fn access013_an_open_exchange_with_top_level_agents_validates()
-> Result<(), Box<dyn std::error::Error>> {
let mut config = sample_config()?;
config.auth = None;
config.cluster = None;
config.agents = Some(crate::agents::config::AgentsConfig::default());
config.limits.max_channels = Some(64);
let message = config_validation_message(validate(&mut config, None));
assert_eq!(message, "", "an open exchange with [agents] validates");
assert_eq!(config.agents_place(), "top");
assert!(config.agents_config().is_some());
Ok(())
}
#[test]
fn access013_agents_in_both_places_are_refused_by_the_exact_words()
-> Result<(), Box<dyn std::error::Error>> {
let mut config = sample_config()?;
config.auth = Some(lys_auth("[lys.agents]\n")?);
config.agents = Some(crate::agents::config::AgentsConfig::default());
let message = config_validation_message(validate(&mut config, None));
assert!(
message.lines().any(|line| line == BOTH),
"missing {BOTH:?} in {message:?}"
);
Ok(())
}
#[test]
fn access013_a_gated_exchange_names_where_its_agents_are_written()
-> Result<(), Box<dyn std::error::Error>> {
let mut config = sample_config()?;
config.auth = Some(lys_auth("")?);
config.agents = Some(crate::agents::config::AgentsConfig::default());
let message = config_validation_message(validate(&mut config, None));
assert!(!message.contains(BOTH), "{message}");
assert_eq!(config.agents_place(), "top");
config.agents = None;
config.auth = Some(lys_auth("[lys.agents]\n")?);
assert_eq!(config.agents_place(), "auth.lys");
assert!(config.agents_config().is_some());
config.auth = Some(lys_auth("")?);
assert_eq!(config.agents_place(), "none");
assert!(config.agents_config().is_none());
Ok(())
}
#[test]
fn access013_a_registry_without_a_channel_bound_is_refused_by_name()
-> Result<(), Box<dyn std::error::Error>> {
const UNBOUNDED: &str = "agents: each station's inbox is a channel registered at runtime; write [limits] max_channels";
for place in ["top", "auth.lys"] {
let mut config = sample_config()?;
config.limits.max_channels = None;
if place == "top" {
config.auth = None;
config.cluster = None;
config.agents = Some(crate::agents::config::AgentsConfig::default());
} else {
config.auth = Some(lys_auth("[lys.agents]\n")?);
}
let message = config_validation_message(validate(&mut config, None));
assert!(
message.lines().any(|line| line == UNBOUNDED),
"{place}: missing {UNBOUNDED:?} in {message:?}"
);
}
Ok(())
}