use super::*;
use std::fs;
use serde_json::{Value, json};
use crate::profile::{claude_dir, home_dir};
use crate::testutil::HomeSandbox;
fn write_json(path: &std::path::Path, value: &Value) {
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).expect("mkdir");
}
fs::write(path, serde_json::to_vec_pretty(value).expect("serialize")).expect("write");
}
fn plugins_path(file: &str) -> std::path::PathBuf {
claude_dir().expect("claude dir").join("plugins").join(file)
}
#[test]
fn installed_records_parses_entry() {
let _home = HomeSandbox::new();
write_json(
&plugins_path("installed_plugins.json"),
&json!({
"plugins": {
"clauth@clauth": [{
"scope": "user",
"version": "0.1.0",
"gitCommitSha": "aab3e45deadbeef",
"installedAt": "2026-06-19T00:00:00Z",
"installPath": "/home/u/.claude/plugins/clauth",
}]
}
}),
);
let records = installed_records();
assert_eq!(records.len(), 1);
let rec = &records[0];
assert_eq!(rec.scope.as_deref(), Some("user"));
assert_eq!(rec.version.as_deref(), Some("0.1.0"));
assert_eq!(rec.git_commit_sha.as_deref(), Some("aab3e45deadbeef"));
assert!(rec.project_path.is_none());
}
#[test]
fn installed_records_empty_when_absent_or_other_plugin() {
let _home = HomeSandbox::new();
assert!(installed_records().is_empty());
write_json(
&plugins_path("installed_plugins.json"),
&json!({ "plugins": { "other@market": [{ "scope": "user" }] } }),
);
assert!(installed_records().is_empty());
}
#[test]
fn marketplace_known_parses_source_repo() {
let _home = HomeSandbox::new();
write_json(
&plugins_path("known_marketplaces.json"),
&json!({
"clauth": {
"source": { "source": "github", "repo": "uwuclxdy/clauth" },
"installLocation": "/home/u/.claude/plugins/marketplaces/clauth"
}
}),
);
let info = marketplace_known().expect("marketplace present");
assert_eq!(info.repo.as_deref(), Some("uwuclxdy/clauth"));
assert!(info.install_location.is_some());
fs::remove_file(plugins_path("known_marketplaces.json")).expect("rm");
assert!(marketplace_known().is_none());
}
#[test]
fn manual_mcp_wiring_detects_global_config() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
assert_eq!(manual_mcp_wiring(), McpWiring::None);
write_json(
&path,
&json!({ "mcpServers": { "clauth": { "command": "clauth", "args": ["mcp"] } } }),
);
assert_eq!(manual_mcp_wiring(), McpWiring::GlobalConfig);
}
#[test]
fn wire_mcp_server_writes_entry_and_preserves_other_fields() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
write_json(&path, &json!({ "userID": "abc123", "tips": { "x": 1 } }));
wire_mcp_server().expect("wire");
let root: Value = serde_json::from_slice(&fs::read(&path).expect("read")).expect("parse");
assert_eq!(root.get("userID").and_then(Value::as_str), Some("abc123"));
assert!(root.get("tips").is_some());
let entry = &root["mcpServers"]["clauth"];
assert_eq!(entry["command"].as_str(), Some("clauth"));
assert_eq!(entry["args"][0].as_str(), Some("mcp"));
assert_eq!(entry["type"].as_str(), Some("stdio"));
assert_eq!(manual_mcp_wiring(), McpWiring::GlobalConfig);
}
#[test]
fn wire_mcp_server_preserves_other_servers() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
write_json(
&path,
&json!({ "mcpServers": { "other": { "command": "x", "args": [] } } }),
);
wire_mcp_server().expect("wire");
let root: Value = serde_json::from_slice(&fs::read(&path).expect("read")).expect("parse");
assert_eq!(root["mcpServers"]["other"]["command"].as_str(), Some("x"));
assert_eq!(
root["mcpServers"]["clauth"]["command"].as_str(),
Some("clauth")
);
}
#[test]
fn wire_mcp_server_replaces_non_object_mcpservers() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
write_json(&path, &json!({ "mcpServers": "garbage", "userID": "keep" }));
wire_mcp_server().expect("wire");
let root: Value = serde_json::from_slice(&fs::read(&path).expect("read")).expect("parse");
assert_eq!(
root["mcpServers"]["clauth"]["command"].as_str(),
Some("clauth")
);
assert_eq!(root.get("userID").and_then(Value::as_str), Some("keep"));
}
#[test]
fn wire_mcp_server_creates_file_when_absent() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
assert!(!path.exists());
wire_mcp_server().expect("wire");
assert!(path.exists());
assert_eq!(manual_mcp_wiring(), McpWiring::GlobalConfig);
}
#[test]
fn global_entry_drifted_flags_stale_command_and_args() {
let _home = HomeSandbox::new();
let path = home_dir().expect("home").join(".claude.json");
assert_eq!(global_entry_drifted(), None);
wire_mcp_server().expect("wire");
assert_eq!(global_entry_drifted(), Some(false));
write_json(
&path,
&json!({ "mcpServers": { "clauth": { "command": "/old/bin/clauth", "args": ["mcp"] } } }),
);
assert_eq!(global_entry_drifted(), Some(true));
write_json(
&path,
&json!({ "mcpServers": { "clauth": { "command": "clauth", "args": [] } } }),
);
assert_eq!(global_entry_drifted(), Some(true));
}