use crossterm::event::{KeyCode, KeyEvent};
use crate::app::{App, Screen};
pub(super) fn handle_key(app: &mut App, key: KeyEvent) {
let Screen::Welcome {
known_hosts_count, ..
} = &app.screen
else {
return;
};
let known_hosts_count = *known_hosts_count;
let version = env!("CARGO_PKG_VERSION");
if let Err(e) = crate::preferences::save_last_seen_version(version) {
log::warn!("[purple] failed to seed last_seen_version on welcome close: {e}");
}
if key.code == KeyCode::Char('?') {
app.set_screen(Screen::Help {
return_screen: Box::new(Screen::HostList),
});
} else if key.code == KeyCode::Char('I') && known_hosts_count > 0 {
app.set_screen(Screen::HostList);
super::confirm::execute_known_hosts_import(app);
} else {
app.set_screen(Screen::HostList);
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ssh_config::model::SshConfigFile;
use crossterm::event::KeyModifiers;
fn make_app_on_welcome(known_hosts_count: usize) -> App {
let scratch = tempfile::tempdir().expect("tempdir").keep();
crate::preferences::set_path_override(scratch.join("preferences"));
let config = SshConfigFile {
elements: SshConfigFile::parse_content(""),
path: scratch.join("test_config"),
crlf: false,
bom: false,
};
let mut app = App::new(config);
app.screen = Screen::Welcome {
has_backup: false,
host_count: 0,
known_hosts_count,
};
app
}
fn k(code: KeyCode) -> KeyEvent {
KeyEvent::new(code, KeyModifiers::NONE)
}
#[test]
fn question_key_opens_help() {
let _lock = crate::demo_flag::GLOBAL_TEST_LOCK.lock().unwrap();
let mut app = make_app_on_welcome(0);
handle_key(&mut app, k(KeyCode::Char('?')));
assert!(matches!(app.screen, Screen::Help { .. }));
}
#[test]
fn any_other_key_returns_to_host_list() {
let _lock = crate::demo_flag::GLOBAL_TEST_LOCK.lock().unwrap();
let mut app = make_app_on_welcome(0);
handle_key(&mut app, k(KeyCode::Esc));
assert!(matches!(app.screen, Screen::HostList));
}
#[test]
fn capital_i_with_zero_known_hosts_just_dismisses() {
let _lock = crate::demo_flag::GLOBAL_TEST_LOCK.lock().unwrap();
let mut app = make_app_on_welcome(0);
handle_key(&mut app, k(KeyCode::Char('I')));
assert!(matches!(app.screen, Screen::HostList));
}
#[test]
fn capital_i_with_known_hosts_triggers_import_path() {
let _path_guard = crate::vault_ssh::tests::ENV_LOCK
.lock()
.unwrap_or_else(|p| p.into_inner());
let old_home = std::env::var("HOME").ok();
let home = tempfile::tempdir().expect("tempdir").keep();
unsafe {
std::env::set_var("HOME", &home);
}
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
let mut app = make_app_on_welcome(1);
handle_key(&mut app, k(KeyCode::Char('I')));
assert!(matches!(app.screen, Screen::HostList));
assert!(
app.status_center.toast().is_some() || app.status_center.status().is_some(),
"I-key with known_hosts_count > 0 must attempt import and emit a status"
);
}));
unsafe {
match old_home {
Some(h) => std::env::set_var("HOME", h),
None => std::env::remove_var("HOME"),
}
}
if let Err(e) = result {
std::panic::resume_unwind(e);
}
}
}