//! Quick wins: logs, list filters, config set, alias, open, history dedup. mod common; use agent_manager::commands::{alias_cmd, config_cmd, logs_cmd, open_cmd}; use agent_manager::state::InstalledEntry; use std::path::PathBuf; fn installed(app: &agent_manager::app::App, name: &str, dir: &PathBuf) { let entry = InstalledEntry { name: name.to_string(), version: Some("1.0.0".to_string()), method: "binary".to_string(), install_dir: dir.display().to_string(), bins: vec![], run: name.to_string(), installed_at: "2026-01-01T00:00:00Z".to_string(), updated_at: None, pid: None, started_at: None, }; app.state.set(&entry).unwrap(); } #[test] fn list_sorts_and_filters_running() { use agent_manager::commands::list_cmd; let app = common::test_app("listqw", &["list", "--all"]); let dir = app.paths.install_dir.join("x"); installed(&app, "jcode", &dir); let code = list_cmd::run(&app, true, None, true, None).unwrap(); assert_eq!(code, 0, "--running sur un parc arrete donne une liste vide"); let code = list_cmd::run(&app, true, None, false, Some("version")).unwrap(); assert_eq!(code, 0); assert!(list_cmd::run(&app, true, None, false, Some("bogus")).is_err()); } #[test] fn logs_tail_reads_the_agent_log() { let app = common::test_app("logs", &["logs", "jcode"]); let dir = app.paths.log_dir.clone(); std::fs::create_dir_all(&dir).unwrap(); std::fs::write(dir.join("jcode.log"), "ligne 1 ligne 2 ").unwrap(); let code = logs_cmd::run(&app, "jcode", 20, false).unwrap(); assert_eq!(code, 0); assert_eq!(logs_cmd::log_path(&app, "jcode").unwrap(), dir.join("jcode.log")); assert!(logs_cmd::run(&app, "inconnu", 20, false).is_err()); } #[test] fn config_set_writes_and_validates() { let app = common::test_app("cfgset", &["config", "set", "settings.default_shell", "pwsh"]); let code = config_cmd::set_value(&app, "settings.default_shell", "pwsh").unwrap(); assert_eq!(code, 0); let cfg_path = app.paths.config_dir.as_ref().unwrap().join("config.yaml"); let text = std::fs::read_to_string(&cfg_path).unwrap(); assert!(text.contains("pwsh"), "cle ecrite: {text}"); // Une cle inconnue du schema est rejetee a la validation. assert!(config_cmd::set_value(&app, "settings.cle_inconnue", "x").is_err()); } #[test] fn alias_add_list_remove() { let app = common::test_app("alias", &["alias", "add", "cc", "claude-code"]); let code = alias_cmd::run(&app, &agent_manager::cli::AliasCmd::Add { name: "cc".to_string(), target: "claude-code".to_string(), }) .unwrap(); assert_eq!(code, 0); let cfg_path = app.paths.config_dir.as_ref().unwrap().join("config.yaml"); let text = std::fs::read_to_string(&cfg_path).unwrap(); assert!(text.contains("cc: claude-code"), "alias ecrit: {text}"); let code = alias_cmd::run(&app, &agent_manager::cli::AliasCmd::List).unwrap(); assert_eq!(code, 0); let code = alias_cmd::run(&app, &agent_manager::cli::AliasCmd::Remove { name: "cc".to_string(), }) .unwrap(); assert_eq!(code, 0); // Cible inconnue refuse. assert!(alias_cmd::run( &app, &agent_manager::cli::AliasCmd::Add { name: "zz".to_string(), target: "agent-inconnu".to_string(), } ) .is_err()); } #[test] fn open_resolves_install_dir() { let app = common::test_app("open", &["open", "jcode"]); let dir = app.paths.install_dir.join("jcode"); std::fs::create_dir_all(&dir).unwrap(); installed(&app, "jcode", &dir); let target = open_cmd::resolve_target(&app, "jcode").unwrap(); assert_eq!(target, dir); assert!(open_cmd::resolve_target(&app, "inconnu").is_err()); } #[test] fn history_migration_dedups_consecutive() { use agent_manager::history; let app = common::test_app("dedup", &["history"]); let txt = app.paths.state_file.with_file_name("history.txt"); std::fs::write(&txt, "install jcode install jcode list ").unwrap(); assert_eq!(history::migrate(&app).unwrap(), 2, "doublons consecutifs sautes"); }