use super::super::refresh::{
AUTOMATIC_REFRESH_COOLDOWN, automatic_refresh_allowed_at, automatic_refresh_failed_at,
catalog_refresh_outcome_for_selected_model,
};
use super::super::types::ModelCatalogEntry;
use super::super::{
CatalogRefreshFailureCategory, CatalogRefreshOutcome, automatic_refresh_allowed,
automatic_refresh_failed, automatic_refresh_suppressed, refresh_catalog_for_provider,
};
use crate::config::McPaths;
use std::time::{Duration, Instant};
use tempfile::TempDir;
#[test]
fn automatic_refresh_failure_gate_bounds_retries_per_provider() {
let provider = "automatic-refresh-test-provider";
assert!(automatic_refresh_allowed(provider));
automatic_refresh_failed(provider);
assert!(!automatic_refresh_allowed(provider));
assert!(automatic_refresh_allowed("another-refresh-provider"));
}
#[test]
fn automatic_refresh_outcome_tracks_selected_model_after_partial_match() {
let matched = {
let mut entry = ModelCatalogEntry::new("local-ai", "matched");
entry.supports_reasoning = Some(true);
entry
};
let unmatched = ModelCatalogEntry::new("local-ai", "selected-unmatched");
let entries = vec![matched, unmatched];
assert_eq!(
catalog_refresh_outcome_for_selected_model(&entries, "local-ai", "selected-unmatched"),
CatalogRefreshOutcome::NoMatch
);
assert_eq!(
catalog_refresh_outcome_for_selected_model(&entries, "local-ai", "matched"),
CatalogRefreshOutcome::Updated
);
let provider = "selected-model-partial-match-provider";
assert!(automatic_refresh_allowed(provider));
automatic_refresh_suppressed(provider);
assert!(!automatic_refresh_allowed(provider));
}
#[test]
fn automatic_refresh_no_match_gate_bounds_retries_without_affecting_explicit_refresh() {
let provider = "automatic-no-match-test-provider";
assert!(automatic_refresh_allowed(provider));
automatic_refresh_suppressed(provider);
assert!(!automatic_refresh_allowed(provider));
automatic_refresh_failed_at(provider, Instant::now() - AUTOMATIC_REFRESH_COOLDOWN);
assert!(automatic_refresh_allowed(provider));
}
#[test]
fn automatic_refresh_recovery_gate_is_deterministic_without_sleeping() {
let provider = "deterministic-refresh-provider";
let failed_at = Instant::now();
automatic_refresh_failed_at(provider, failed_at);
assert!(!automatic_refresh_allowed_at(provider, failed_at));
assert!(!automatic_refresh_allowed_at(
provider,
failed_at + AUTOMATIC_REFRESH_COOLDOWN - Duration::from_millis(1)
));
assert!(automatic_refresh_allowed_at(
provider,
failed_at + AUTOMATIC_REFRESH_COOLDOWN
));
}
#[test]
fn refresh_failure_reports_safe_settings_category() {
let temp = TempDir::new().unwrap();
std::fs::create_dir_all(temp.path().join("mc")).unwrap();
let paths = McPaths::from_root(temp.path().join("mc"));
std::fs::write(&paths.settings_file, "not json").unwrap();
let error =
refresh_catalog_for_provider(&paths, "custom-provider", "selected-model").unwrap_err();
assert_eq!(error.category(), CatalogRefreshFailureCategory::Settings);
assert_eq!(
error.to_string(),
"settings refresh failed for provider 'custom-provider'"
);
}