Files
codex/codex-rs/connectors/src/snapshot_tests.rs
T
Matthew Zeng 8570091e14 Honor thread-level plugin exclusions across runtime capabilities (#44655)
## What changed

- Apply `disabled_plugin_ids` to plugin skills, recommendations, hooks, and MCP servers without modifying shared plugin state.
- Activate selection changes when the next task starts, keeping pending settings from changing the active runtime.
- Hide app tools contributed only by disabled plugins from model tool catalogs and search. Preserve connectors shared with enabled plugins and existing direct Apps RPC behavior.
- Include plugin identity in MCP approval keys and use that identity when persisting plugin tool approvals.

## Testing

Add regression coverage for disabling and re-enabling plugin skills and tools, deferred activation of settings, shared connector ownership, selected plugin servers, executor hooks, and plugin-specific approval keys and persistence.

GitOrigin-RevId: 1153ff6aa7ab6953d50e838da05203904ecd2956
2026-09-10 21:51:34 +00:00

82 lines
2.4 KiB
Rust

use codex_plugin::AppConnectorId;
use pretty_assertions::assert_eq;
use super::ConnectorSnapshot;
use super::PluginConnectorSource;
#[test]
fn snapshot_merges_sources_in_order_and_dedupes_provenance() {
let host = [
source("skills", "Skills only", &[]),
source("host", "Zulu", &["calendar", "calendar"]),
];
let selected = [
source("selected-a", "Alpha", &["drive", "calendar"]),
source("selected-b", "Alpha", &["calendar"]),
];
let merged = ConnectorSnapshot::from_plugin_sources(host.into_iter().chain(selected), &[]);
assert_eq!(
merged.connector_ids(),
&[
AppConnectorId("calendar".to_string()),
AppConnectorId("drive".to_string()),
]
);
assert_eq!(
merged.plugin_display_names_for_connector_id("calendar"),
&["Alpha".to_string(), "Zulu".to_string()]
);
assert_eq!(
merged.plugin_display_names_for_connector_id("missing"),
&[] as &[String]
);
}
#[test]
fn disabled_plugins_preserve_shared_connectors() {
let sources = [
source("alpha", "Alpha", &["exclusive", "shared"]),
source("beta", "Beta", &["other", "shared"]),
];
let filtered = ConnectorSnapshot::from_plugin_sources(sources.clone(), &["alpha".to_string()]);
let expected = ConnectorSnapshot {
disabled_connector_ids: std::collections::HashSet::from(["exclusive".to_string()]),
..ConnectorSnapshot::from_plugin_sources(
[source("beta", "Beta", &["other", "shared"])],
&[],
)
};
assert_eq!(filtered, expected);
assert_eq!(
ConnectorSnapshot::from_plugin_sources(
sources.iter().rev().cloned(),
&["alpha".to_string()],
),
expected
);
assert_eq!(
ConnectorSnapshot::from_plugin_sources(sources, &["alpha".to_string(), "beta".to_string()],),
ConnectorSnapshot {
disabled_connector_ids: std::collections::HashSet::from([
"exclusive".to_string(),
"other".to_string(),
"shared".to_string(),
]),
..ConnectorSnapshot::default()
}
);
}
fn source(id: &str, display_name: &str, connector_ids: &[&str]) -> PluginConnectorSource {
PluginConnectorSource::from_connector_ids(
id,
display_name,
connector_ids
.iter()
.map(|id| AppConnectorId((*id).to_string())),
)
}