use crate::config::profile::with_home_override;
use crate::config::{Config, ProviderConfig};
use crate::tui::onboarding::OnboardingWizard;
use crate::tui::provider_selector::{CUSTOM_INSTANCES_START, index_of_provider};
use std::collections::HashMap;
fn in_temp_home<T>(f: impl FnOnce() -> T) -> T {
let dir = tempfile::tempdir().expect("tempdir");
let home = dir.path().join(".opencrabs");
std::fs::create_dir_all(&home).expect("create .opencrabs");
with_home_override(home, f)
}
fn enabled() -> ProviderConfig {
ProviderConfig {
enabled: true,
..Default::default()
}
}
fn custom(base: &str, enabled: bool) -> ProviderConfig {
ProviderConfig {
enabled,
base_url: Some(base.to_string()),
..Default::default()
}
}
#[test]
fn an_enabled_builtin_opencrabs_provider_is_the_one_opened() {
in_temp_home(|| {
let mut config = Config::default();
config.providers.opencrabs = Some(enabled());
let wizard = OnboardingWizard::from_config(&config);
assert_eq!(
wizard.ps.selected_provider,
index_of_provider("opencrabs").expect("opencrabs is a provider")
);
});
}
#[test]
fn a_config_on_disk_never_wins_over_the_config_handed_in() {
in_temp_home(|| {
let home = crate::config::opencrabs_home();
std::fs::create_dir_all(&home).expect("create home");
std::fs::write(
home.join("config.toml"),
"[providers.claude_cli]\nenabled = true\n",
)
.expect("write the disk config");
let from_disk = Config::load().expect("load the temp-home config");
assert!(
from_disk
.providers
.claude_cli
.as_ref()
.is_some_and(|p| p.enabled),
"fixture must actually enable claude-cli on disk"
);
let mut config = Config::default();
config.providers.opencrabs = Some(enabled());
let wizard = OnboardingWizard::from_config(&config);
assert_eq!(
wizard.ps.selected_provider,
index_of_provider("opencrabs").expect("opencrabs is a provider"),
"the wizard must follow the config it was handed, not the one on disk (#2077)"
);
});
}
#[test]
fn a_disabled_custom_provider_is_never_selected_by_fallback() {
in_temp_home(|| {
let mut config = Config::default();
let mut customs = HashMap::new();
customs.insert(
"baidu-ernie".to_string(),
custom("https://qianfan.example/v2", false),
);
config.providers.custom = Some(customs.into_iter().collect());
let wizard = OnboardingWizard::from_config(&config);
assert!(
wizard.ps.selected_provider < CUSTOM_INSTANCES_START,
"a disabled custom provider must not be opened; got index {}",
wizard.ps.selected_provider
);
});
}
#[test]
fn the_session_custom_provider_is_selected_by_name() {
in_temp_home(|| {
let mut customs = HashMap::new();
customs.insert("alpha".to_string(), custom("https://a.example/v1", true));
customs.insert("beta".to_string(), custom("https://b.example/v1", true));
let mut config = Config::default();
config.providers.custom = Some(customs.into_iter().collect());
let mut wizard = OnboardingWizard::from_config(&config);
let found = wizard.select_session_pair("custom:beta", "gpt-x", &config);
assert!(found);
let pos = config
.providers
.custom
.as_ref()
.unwrap()
.keys()
.position(|k| k == "beta")
.unwrap();
assert_eq!(wizard.ps.selected_provider, CUSTOM_INSTANCES_START + pos);
assert_eq!(wizard.ps.custom_name, "beta");
assert_eq!(wizard.ps.base_url, "https://b.example/v1");
assert_eq!(wizard.ps.custom_model, "gpt-x");
});
}
#[test]
fn the_session_builtin_model_is_the_one_selected_even_when_unlisted() {
in_temp_home(|| {
let config = Config::default();
let mut wizard = OnboardingWizard::from_config(&config);
let found = wizard.select_session_pair("zai", "glm-session-only", &config);
assert!(found);
assert_eq!(
wizard.ps.selected_provider,
index_of_provider("zai").unwrap()
);
let all = wizard.ps.all_model_names();
assert_eq!(all[wizard.ps.selected_model], "glm-session-only");
});
}
#[test]
fn an_unknown_session_provider_leaves_the_dialog_alone() {
in_temp_home(|| {
let config = Config::default();
let mut wizard = OnboardingWizard::from_config(&config);
let before = wizard.ps.selected_provider;
let found = wizard.select_session_pair("custom:gone", "m", &config);
assert!(!found);
assert_eq!(wizard.ps.selected_provider, before);
});
}