use crate::config::profile::with_home_override;
use crate::tui::onboarding::{OnboardingStep, OnboardingWizard, SttProvider};
fn temp_home() -> (tempfile::TempDir, std::path::PathBuf) {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create .opencrabs");
(dir, home)
}
fn flag(home: &std::path::Path, segments: &[&str], key: &str) -> Option<bool> {
let raw = std::fs::read_to_string(home.join("config.toml")).ok()?;
let doc: toml_edit::DocumentMut = raw.parse().expect("valid TOML");
let mut table: &dyn toml_edit::TableLike = doc.as_table();
for seg in segments {
table = table.get(seg)?.as_table_like()?;
}
match table.get(key)? {
toml_edit::Item::Value(v) => v.as_bool().or_else(|| v.as_str().map(|s| s == "true")),
_ => None,
}
}
#[test]
fn groq_voice_onboard_persists_enabled_true() {
let (_temp, home) = temp_home();
with_home_override(home.clone(), || {
let result =
crate::brain::tools::slash_onboard::onboard_voice("stt groq groq-test-key-123")
.expect("dispatch succeeds");
assert!(
format!("{result:?}").contains("success"),
"onboard reports success: {result:?}"
);
let raw = std::fs::read_to_string(home.join("config.toml")).expect("config.toml written");
let doc: toml_edit::DocumentMut = raw.parse().expect("valid TOML");
assert_eq!(
doc["providers"]["stt"]["groq"]["enabled"].as_bool(),
Some(true),
"the arm that promises 'enabled' must actually write enabled=true"
);
});
}
#[test]
fn voice_flag_round_trips_through_disk_reload() {
let (_temp, home) = temp_home();
with_home_override(home.clone(), || {
crate::config::Config::write_key("providers.stt.groq", "enabled", "true")
.expect("flag written");
assert_eq!(
flag(&home, &["providers", "stt", "groq"], "enabled"),
Some(true)
);
});
}
#[test]
fn complete_without_touching_voice_preserves_disk_voice_flags() {
let (_temp, home) = temp_home();
with_home_override(home.clone(), || {
crate::config::Config::write_key("providers.stt.groq", "enabled", "true").unwrap();
crate::config::Config::write_key("providers.tts.openai", "enabled", "true").unwrap();
let w = OnboardingWizard {
step: OnboardingStep::Complete,
..OnboardingWizard::default()
};
w.apply_config().expect("apply succeeds");
assert_eq!(
flag(&home, &["providers", "stt", "groq"], "enabled"),
Some(true),
"Complete must not stomp providers.stt.groq.enabled when voice was never touched"
);
assert_eq!(
flag(&home, &["providers", "tts", "openai"], "enabled"),
Some(true),
"Complete must not stomp providers.tts.openai.enabled when voice was never touched"
);
});
}
#[test]
fn complete_after_touching_voice_writes_current_selection() {
let (_temp, home) = temp_home();
with_home_override(home.clone(), || {
let mut w = OnboardingWizard {
step: OnboardingStep::VoiceSetup,
..OnboardingWizard::default()
};
w.stt_provider = SttProvider::Groq;
w.groq_api_key_input = "key".into();
w.next_step();
assert!(w.voice_step_touched, "leaving VoiceSetup marks the run");
w.step = OnboardingStep::Complete;
w.apply_config().expect("apply succeeds");
assert_eq!(
flag(&home, &["providers", "stt", "groq"], "enabled"),
Some(true),
"an explicit voice selection IS written at Complete"
);
});
}