use std::path::PathBuf;
use purple_ssh::providers::{PROVIDER_NAMES, provider_display_name};
use purple_ssh::ssh_config::model::{ConfigElement, SshConfigFile};
fn parse(content: &str) -> SshConfigFile {
SshConfigFile {
elements: SshConfigFile::parse_content(content),
path: PathBuf::from("/tmp/test_config"),
crlf: false,
bom: false,
}
}
fn header_present(config: &SshConfigFile, display: &str) -> bool {
let needle = format!("# purple:group {display}");
config
.elements
.iter()
.any(|e| matches!(e, ConfigElement::GlobalLine(l) if l.trim() == needle))
}
#[test]
fn every_provider_group_header_survives_startup_cleanup_with_active_host() {
let mut broken = Vec::new();
for &name in PROVIDER_NAMES {
let display = provider_display_name(name);
let cfg = format!(
"# purple:group {display}\n\nHost test-{name}\n HostName 1.1.1.1\n # purple:provider {name}:123\n"
);
let mut config = parse(&cfg);
let removed = config.remove_all_orphaned_group_headers();
if !header_present(&config, display) {
broken.push(format!("{name} -> '{display}' (removed={removed})"));
}
}
assert!(
broken.is_empty(),
"{} of {} providers lose their group header on startup despite active hosts: {:#?}",
broken.len(),
PROVIDER_NAMES.len(),
broken
);
}
#[test]
fn every_provider_orphan_header_removed_when_no_hosts() {
let mut broken = Vec::new();
for &name in PROVIDER_NAMES {
let display = provider_display_name(name);
let cfg = format!("# purple:group {display}\n\nHost unrelated\n HostName 9.9.9.9\n");
let mut config = parse(&cfg);
config.remove_all_orphaned_group_headers();
if header_present(&config, display) {
broken.push(format!("{name} -> '{display}'"));
}
}
assert!(
broken.is_empty(),
"{} of {} providers leave a stale orphan group header behind: {:#?}",
broken.len(),
PROVIDER_NAMES.len(),
broken
);
}