diff --git a/apps/desktop-tauri/src-tauri/src/commands/bridge.rs b/apps/desktop-tauri/src-tauri/src/commands/bridge.rs index ab5efbef8a..d426971d37 100644 --- a/apps/desktop-tauri/src-tauri/src/commands/bridge.rs +++ b/apps/desktop-tauri/src-tauri/src/commands/bridge.rs @@ -721,7 +721,10 @@ pub struct SettingsSnapshot { #[tauri::command] pub fn get_bootstrap_state() -> BootstrapState { - let settings = Settings::load(); + bootstrap_state_for(Settings::load()) +} + +pub(crate) fn bootstrap_state_for(settings: Settings) -> BootstrapState { BootstrapState { contract_version: "v1", providers: provider_catalog_for(&settings), diff --git a/apps/desktop-tauri/src-tauri/src/commands/tests.rs b/apps/desktop-tauri/src-tauri/src/commands/tests.rs index d25a0a064a..b2439a066d 100644 --- a/apps/desktop-tauri/src-tauri/src/commands/tests.rs +++ b/apps/desktop-tauri/src-tauri/src/commands/tests.rs @@ -1905,7 +1905,10 @@ fn external_url_validator_rejects_non_web_and_control_urls() { #[test] fn bootstrap_payload_exposes_every_provider_variant() { - let payload = super::get_bootstrap_state(); + // Built from default settings instead of `Settings::load()` so a retired + // provider enabled in the developer's real settings.json cannot change + // the catalog size. + let payload = super::bootstrap_state_for(Settings::default()); let catalog_ids: std::collections::HashSet = payload .providers @@ -1952,3 +1955,46 @@ fn bootstrap_payload_exposes_every_provider_variant() { assert!(encoded.contains("\"providers\"")); assert!(encoded.contains("\"settings\"")); } + +// Issue #684: the catalog size depends only on the settings passed in. A +// deprecated provider that is still enabled (the state that made the old +// test read 79 entries on a developer machine) is listed exactly once, and +// building the payload twice from the same settings gives the same catalog. +#[test] +fn bootstrap_catalog_depends_only_on_supplied_settings() { + let active_count = ProviderId::all() + .iter() + .filter(|provider| !provider.is_deprecated()) + .count(); + + let mut settings = Settings::default(); + settings + .enabled_providers + .insert(ProviderId::KimiK2.cli_name().to_string()); + + let first = super::bootstrap_state_for(settings.clone()); + let second = super::bootstrap_state_for(settings); + + let ids = |payload: &super::BootstrapState| -> Vec { + payload + .providers + .iter() + .map(|entry| entry.id.clone()) + .collect() + }; + assert_eq!(ids(&first), ids(&second)); + assert_eq!(first.providers.len(), active_count + 1); + assert_eq!( + ids(&first) + .iter() + .filter(|id| id.as_str() == ProviderId::KimiK2.cli_name()) + .count(), + 1 + ); + assert!( + !ids(&first) + .iter() + .any(|id| id.as_str() == ProviderId::CrossModel.cli_name()), + "a deprecated provider that is not enabled stays hidden" + ); +}