use super::*;
use crate::config::{ConfigEntry, Environment, Group, Server};
fn make_app_with_group() -> App {
let config = Config {
defaults: None,
includes: vec![],
groups: vec![ConfigEntry::Group(Group {
name: "Grp".to_string(),
user: None,
ssh_key: None,
mode: None,
ssh_port: None,
ssh_options: None,
wallix: None,
wallix_group: None,
jump: None,
probe_filesystems: None,
environments: Some(vec![Environment {
name: "Env1".to_string(),
user: None,
ssh_key: None,
mode: None,
ssh_port: None,
ssh_options: None,
wallix: None,
wallix_group: None,
jump: None,
probe_filesystems: None,
tunnels: None,
tags: None,
servers: vec![Server {
name: "srv1".to_string(),
host: "10.0.0.1".to_string(),
user: None,
ssh_key: None,
ssh_port: None,
ssh_options: None,
mode: None,
wallix: None,
jump: None,
probe_filesystems: None,
tunnels: None,
tags: None,
..Default::default()
}],
}]),
servers: None,
tunnels: None,
tags: None,
})],
vars: Default::default(),
};
let mut app = App::new(config, vec![], std::path::PathBuf::from("/fake"), vec![]).unwrap();
app.expanded_items.insert("Group:Grp".to_string());
app.expanded_items.insert("Env:Grp:Env1".to_string());
app.items_dirty = true;
app.get_visible_items();
app
}
#[test]
fn close_overview_clears_state() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "Grp".to_string(),
entries: vec![],
scroll: 0,
});
let (_, rx) = std::sync::mpsc::channel::<(usize, Result<crate::probe::ProbeResult, String>)>();
app.overview_rx = Some(rx);
app.close_overview();
assert!(app.overview.is_none());
assert!(app.overview_rx.is_none());
}
#[test]
fn open_overview_server_selected_noop() {
let mut app = make_app_with_group();
app.select(2);
let items = app.get_visible_items();
assert!(matches!(items.get(2), Some(ConfigItem::Server(_))));
app.open_overview();
assert!(app.overview.is_none());
}
#[test]
fn open_overview_no_items_noop() {
let config = Config {
defaults: None,
includes: vec![],
groups: vec![],
vars: Default::default(),
};
let mut app = App::new(config, vec![], std::path::PathBuf::from("/fake"), vec![]).unwrap();
app.open_overview();
assert!(app.overview.is_none());
}
#[test]
fn open_overview_group_opens_with_entries() {
let mut app = make_app_with_group();
app.select(0);
let items = app.get_visible_items();
assert!(matches!(items.first(), Some(ConfigItem::Group(..))));
app.open_overview();
assert!(app.overview.is_some());
let ov = app.overview.as_ref().unwrap();
assert!(!ov.entries.is_empty());
assert_eq!(ov.entries[0].server_name, "srv1");
}
#[test]
fn open_overview_env_opens_with_entries() {
let mut app = make_app_with_group();
app.select(1);
let items = app.get_visible_items();
assert!(matches!(items.get(1), Some(ConfigItem::Environment(..))));
app.open_overview();
assert!(app.overview.is_some());
let ov = app.overview.as_ref().unwrap();
assert!(ov.group_name.contains("Env1"));
}
#[test]
fn overview_scroll_down_increments() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "G".to_string(),
entries: vec![],
scroll: 0,
});
app.overview_scroll_down();
assert_eq!(app.overview.as_ref().unwrap().scroll, 1);
app.overview_scroll_down();
assert_eq!(app.overview.as_ref().unwrap().scroll, 2);
}
#[test]
fn overview_scroll_up_decrements() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "G".to_string(),
entries: vec![],
scroll: 3,
});
app.overview_scroll_up();
assert_eq!(app.overview.as_ref().unwrap().scroll, 2);
}
#[test]
fn overview_scroll_up_saturates_at_zero() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "G".to_string(),
entries: vec![],
scroll: 0,
});
app.overview_scroll_up();
assert_eq!(app.overview.as_ref().unwrap().scroll, 0);
}
#[test]
fn overview_scroll_noop_when_closed() {
let mut app = make_app_with_group();
assert!(app.overview.is_none());
app.overview_scroll_down();
app.overview_scroll_up();
}
#[test]
fn poll_overview_no_rx_noop() {
let mut app = make_app_with_group();
app.overview_rx = None;
app.poll_overview();
}
#[test]
fn poll_overview_delivers_ok_result() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "G".to_string(),
entries: vec![OverviewEntry {
server_name: "srv1".to_string(),
host: "10.0.0.1".to_string(),
status: OverviewStatus::Pending,
}],
scroll: 0,
});
let (tx, rx) = std::sync::mpsc::channel::<(usize, Result<crate::probe::ProbeResult, String>)>();
app.overview_rx = Some(rx);
let probe_result = crate::probe::ProbeResult {
load: "0.5".to_string(),
ram_pct: 60,
disk_pct: 40,
profile: crate::probe::ProbeProfile::Standard,
kernel: String::new(),
cpu_model: String::new(),
cpu_cores: 1,
os_name: String::new(),
ram_total_gb: 0.0,
disk_total_gb: 0.0,
extra_fs: vec![],
notes: vec![],
control_master_active: false,
};
tx.send((0, Ok(probe_result))).unwrap();
drop(tx);
app.poll_overview();
let ov = app.overview.as_ref().unwrap();
assert!(matches!(
ov.entries[0].status,
OverviewStatus::Ok {
ram_pct: 60,
disk_pct: 40,
..
}
));
}
#[test]
fn poll_overview_delivers_error_result() {
let mut app = make_app_with_group();
app.overview = Some(OverviewState {
group_name: "G".to_string(),
entries: vec![OverviewEntry {
server_name: "srv1".to_string(),
host: "10.0.0.1".to_string(),
status: OverviewStatus::Pending,
}],
scroll: 0,
});
let (tx, rx) = std::sync::mpsc::channel::<(usize, Result<crate::probe::ProbeResult, String>)>();
app.overview_rx = Some(rx);
tx.send((0, Err("timeout".to_string()))).unwrap();
drop(tx);
app.poll_overview();
let ov = app.overview.as_ref().unwrap();
assert!(matches!(&ov.entries[0].status, OverviewStatus::Error(e) if e == "timeout"));
}