mirror of
https://github.com/openai/codex.git
synced 2026-05-16 09:12:54 +00:00
179 lines
5.2 KiB
Rust
179 lines
5.2 KiB
Rust
use anyhow::Result;
|
|
use codex_config::CONFIG_TOML_FILE;
|
|
use codex_config::MarketplaceConfigUpdate;
|
|
use codex_config::record_user_marketplace;
|
|
use predicates::str::contains;
|
|
use std::path::Path;
|
|
use tempfile::TempDir;
|
|
|
|
fn codex_command(codex_home: &Path) -> Result<assert_cmd::Command> {
|
|
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
|
|
cmd.env("CODEX_HOME", codex_home);
|
|
Ok(cmd)
|
|
}
|
|
|
|
fn configured_local_marketplace(source: &str) -> MarketplaceConfigUpdate<'_> {
|
|
MarketplaceConfigUpdate {
|
|
last_updated: "2026-05-06T00:00:00Z",
|
|
last_revision: None,
|
|
source_type: "local",
|
|
source,
|
|
ref_name: None,
|
|
sparse_paths: &[],
|
|
}
|
|
}
|
|
|
|
fn write_plugins_enabled_config(codex_home: &Path) -> Result<()> {
|
|
std::fs::write(
|
|
codex_home.join(CONFIG_TOML_FILE),
|
|
r#"[features]
|
|
plugins = true
|
|
"#,
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
fn write_marketplace_source(source: &Path) -> Result<()> {
|
|
std::fs::create_dir_all(source.join(".agents/plugins"))?;
|
|
std::fs::create_dir_all(source.join("plugins/sample/.codex-plugin"))?;
|
|
std::fs::write(
|
|
source.join(".agents/plugins/marketplace.json"),
|
|
r#"{
|
|
"name": "debug",
|
|
"plugins": [
|
|
{
|
|
"name": "sample",
|
|
"source": {
|
|
"source": "local",
|
|
"path": "./plugins/sample"
|
|
}
|
|
}
|
|
]
|
|
}"#,
|
|
)?;
|
|
std::fs::write(
|
|
source.join("plugins/sample/.codex-plugin/plugin.json"),
|
|
r#"{"name":"sample","description":"Sample plugin"}"#,
|
|
)?;
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn marketplace_list_shows_configured_marketplace_names() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_plugins_enabled_config(codex_home.path())?;
|
|
write_marketplace_source(source.path())?;
|
|
let source_path = source.path().to_string_lossy().into_owned();
|
|
record_user_marketplace(
|
|
codex_home.path(),
|
|
"debug",
|
|
&configured_local_marketplace(&source_path),
|
|
)?;
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "marketplace", "list"])
|
|
.assert()
|
|
.success()
|
|
.stdout(contains("debug"))
|
|
.stdout(contains(source.path().display().to_string()));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn plugin_list_shows_plugins_grouped_by_marketplace() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_plugins_enabled_config(codex_home.path())?;
|
|
write_marketplace_source(source.path())?;
|
|
let source_path = source.path().to_string_lossy().into_owned();
|
|
record_user_marketplace(
|
|
codex_home.path(),
|
|
"debug",
|
|
&configured_local_marketplace(&source_path),
|
|
)?;
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "list"])
|
|
.assert()
|
|
.success()
|
|
.stdout(contains("Marketplace `debug`"))
|
|
.stdout(contains("sample@debug (not installed)"));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn plugin_add_and_remove_updates_installed_plugin_config() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_plugins_enabled_config(codex_home.path())?;
|
|
write_marketplace_source(source.path())?;
|
|
let source_path = source.path().to_string_lossy().into_owned();
|
|
record_user_marketplace(
|
|
codex_home.path(),
|
|
"debug",
|
|
&configured_local_marketplace(&source_path),
|
|
)?;
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "add", "sample@debug"])
|
|
.assert()
|
|
.success()
|
|
.stdout(contains("Added plugin `sample` from marketplace `debug`."));
|
|
|
|
let config = std::fs::read_to_string(codex_home.path().join(CONFIG_TOML_FILE))?;
|
|
assert!(config.contains("[plugins.\"sample@debug\"]"));
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "remove", "sample", "--marketplace", "debug"])
|
|
.assert()
|
|
.success()
|
|
.stdout(contains(
|
|
"Removed plugin `sample` from marketplace `debug`.",
|
|
));
|
|
|
|
let config = std::fs::read_to_string(codex_home.path().join(CONFIG_TOML_FILE))?;
|
|
assert!(!config.contains("[plugins.\"sample@debug\"]"));
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn plugin_remove_works_after_marketplace_is_removed() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_plugins_enabled_config(codex_home.path())?;
|
|
write_marketplace_source(source.path())?;
|
|
let source_path = source.path().to_string_lossy().into_owned();
|
|
record_user_marketplace(
|
|
codex_home.path(),
|
|
"debug",
|
|
&configured_local_marketplace(&source_path),
|
|
)?;
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "add", "sample", "--marketplace", "debug"])
|
|
.assert()
|
|
.success();
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "marketplace", "remove", "debug"])
|
|
.assert()
|
|
.success();
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["plugin", "remove", "sample@debug"])
|
|
.assert()
|
|
.success()
|
|
.stdout(contains(
|
|
"Removed plugin `sample` from marketplace `debug`.",
|
|
));
|
|
|
|
let config = std::fs::read_to_string(codex_home.path().join(CONFIG_TOML_FILE))?;
|
|
assert!(!config.contains("[plugins.\"sample@debug\"]"));
|
|
|
|
Ok(())
|
|
}
|