Files
MetaCrate/crates/metacrate-grid-agent/tests/preferences_config.rs
Chili Palmer db25a977b7
Some checks failed
CI / rust-skia (Rust only) (push) Successful in 2m46s
CI / required (push) Failing after 54s
fix(grid-agent): move setup into YAML preferences (#135)
2026-08-18 21:34:14 +02:00

111 lines
3.9 KiB
Rust

use metacrate_grid_agent::{
AgentPreferences, ConfigLoader, MapEnvironment, OperatingMode, OperatorScreen, OperatorTui,
PreferencesPanel, TuiInput, TuiRenderOptions,
};
use std::fs;
use std::path::PathBuf;
use std::time::{SystemTime, UNIX_EPOCH};
fn temporary(name: &str) -> PathBuf {
let directory = std::env::temp_dir().join(format!(
"metacrate-preferences-{}-{name}",
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos()
));
fs::create_dir_all(&directory).unwrap();
directory
}
#[test]
fn yaml_is_primary_and_preferences_preserve_unknown_settings() {
let directory = temporary("yaml");
let path = directory.join("config.yml");
fs::write(
&path,
r"schema_version: 1
integrated: true
llm:
endpoint_url: https://ai.invalid/v1/chat/completions
api_key: private-key
model: local-model
grid:
login_url: https://grid.invalid/login
avatar_name: Service Avatar
password: private-password
authorized_avatar_uuids:
- 00000000-0000-4000-8000-000000000001
behavior:
idle_interval_seconds: 321
",
)
.unwrap();
let config = ConfigLoader::new()
.with_file(&path)
.with_environment(MapEnvironment::default())
.load()
.unwrap();
assert_eq!(config.mode, OperatingMode::Integrated);
assert_eq!(config.llm.model.as_deref(), Some("local-model"));
assert_eq!(config.behavior.idle_interval.as_secs(), 321);
let mut preferences = AgentPreferences::load(&path).unwrap();
preferences.set_llm_model("replacement-model".into());
preferences.save(&path).unwrap();
let saved = fs::read_to_string(&path).unwrap();
assert!(saved.contains("idle_interval_seconds: 321"));
assert!(saved.contains("model: replacement-model"));
assert!(!format!("{preferences:?}").contains("private-key"));
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt as _;
assert_eq!(
fs::metadata(&path).unwrap().permissions().mode() & 0o777,
0o600
);
}
fs::remove_dir_all(directory).unwrap();
}
#[test]
fn dotenv_import_is_explicit_and_preferences_panel_never_renders_secrets() {
let directory = temporary("import");
let dotenv = directory.join("legacy.env");
let config = directory.join("config.yml");
fs::write(
&dotenv,
"OPENAPI_URL=https://ai.invalid/v1/chat/completions\nOPENAPI_KEY=very-secret-key\nOPENAPI_MODEL=test-model\nGRID_LOGIN_URL=https://grid.invalid/login\nGRID_USER=Test Avatar\nGRID_PASSWORD=very-secret-password\n",
)
.unwrap();
let mut preferences = AgentPreferences::load(&config).unwrap();
preferences.import_dotenv(&dotenv).unwrap();
preferences.set_privileged_users(vec!["00000000-0000-4000-8000-000000000001".into()]);
preferences.save(&config).unwrap();
let panel = PreferencesPanel::open(config.clone()).unwrap();
let summary = panel.summary();
assert_eq!(summary.llm_model.as_deref(), Some("test-model"));
assert!(summary.llm_api_key_configured && summary.grid_password_configured);
assert_eq!(summary.privileged_users.len(), 1);
let mut tui = OperatorTui::with_preferences(config).unwrap();
tui.screen = OperatorScreen::Preferences;
let rendered = tui.render(TuiRenderOptions {
width: 120,
height: 30,
color: false,
});
assert!(rendered.contains("LLM API key: [configured]"));
assert!(rendered.contains("grid password: [configured]"));
assert!(!rendered.contains("very-secret"));
let _ = tui.reduce(TuiInput::PreferenceNext);
let _ = tui.reduce(TuiInput::PreferenceEditOrCommit);
for value in "https://replacement.invalid/v1/chat".chars() {
let _ = tui.reduce(TuiInput::PreferenceCharacter(value));
}
let _ = tui.reduce(TuiInput::PreferenceEditOrCommit);
let _ = tui.reduce(TuiInput::PreferenceSave);
fs::remove_dir_all(directory).unwrap();
}