use a3s_code_core::orchestrator::SubAgentConfig;
use a3s_code_core::permissions::{PermissionDecision, PermissionPolicy};
use a3s_code_core::{load_agents_from_dir, AgentRegistry};
#[tokio::test]
async fn test_permissive_deny_wildcard() {
let policy = PermissionPolicy::permissive().deny("mcp__longvt__*");
assert_eq!(
policy.check("mcp__longvt__search", &serde_json::json!({})),
PermissionDecision::Deny,
"mcp__longvt__search should be denied"
);
assert_eq!(
policy.check("mcp__longvt__create_memory", &serde_json::json!({})),
PermissionDecision::Deny,
"mcp__longvt__create_memory should be denied"
);
assert_eq!(
policy.check("mcp__pencil__draw", &serde_json::json!({})),
PermissionDecision::Allow,
"mcp__pencil__draw should be allowed"
);
assert_eq!(
policy.check("read", &serde_json::json!({"file_path": "test.txt"})),
PermissionDecision::Allow,
"read should be allowed"
);
println!("✅ Test 1: PermissionPolicy with wildcard deny - PASSED");
}
#[tokio::test]
async fn test_agent_definition_deny_with_permissive() {
let registry = AgentRegistry::new();
let temp_dir = tempfile::tempdir().unwrap();
std::fs::write(
temp_dir.path().join("test-permission.yaml"),
r#"
name: test-permission
description: Test agent for permission control
permissions:
allow:
- read
- write
deny:
- mcp__longvt__*
- bash
"#,
)
.unwrap();
let agents = load_agents_from_dir(temp_dir.path());
for def in agents {
registry.register(def);
}
if let Some(def) = registry.get("test-permission") {
println!("✅ Loaded agent: {}", def.name);
println!(" Description: {}", def.description);
println!(" Deny rules: {:?}", def.permissions.deny);
let has_longvt_deny = def
.permissions
.deny
.iter()
.any(|r| r.rule.contains("mcp__longvt__"));
assert!(
has_longvt_deny,
"Agent should have mcp__longvt__* deny rule"
);
assert_eq!(
def.permissions
.check("mcp__longvt__search", &serde_json::json!({})),
PermissionDecision::Deny,
"Agent definition should deny mcp__longvt__search"
);
println!("✅ Test 2: Agent definition deny rules - PASSED");
} else {
panic!("Failed to load test-permission agent from temp file");
}
}
#[tokio::test]
async fn test_subagent_config_permissive_deny() {
let config = SubAgentConfig {
agent_type: "general".to_string(),
description: "Test permission control".to_string(),
workspace: "/tmp/test".to_string(),
prompt: "Test prompt".to_string(),
permissive: true,
permissive_deny: vec!["mcp__longvt__*".to_string()],
max_steps: Some(5),
timeout_ms: None,
parent_id: None,
metadata: serde_json::json!({}),
agent_dirs: vec![],
skill_dirs: vec![],
lane_config: None,
};
assert!(config.permissive, "permissive should be true");
assert_eq!(config.permissive_deny.len(), 1, "should have 1 deny rule");
assert_eq!(config.permissive_deny[0], "mcp__longvt__*");
println!("✅ Test 3: SubAgentConfig structure - PASSED");
}
#[tokio::test]
async fn test_multiple_wildcard_patterns() {
let policy = PermissionPolicy::permissive()
.deny("mcp__longvt__*")
.deny("mcp__dangerous__*")
.deny("bash");
assert_eq!(
policy.check("mcp__longvt__search", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("mcp__longvt__create", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("mcp__dangerous__execute", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("bash", &serde_json::json!({"command": "ls"})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("mcp__pencil__draw", &serde_json::json!({})),
PermissionDecision::Allow
);
assert_eq!(
policy.check("read", &serde_json::json!({"file_path": "test.txt"})),
PermissionDecision::Allow
);
println!("✅ Test 4: Multiple wildcard patterns - PASSED");
}
#[tokio::test]
async fn test_mcp_wildcard_variations() {
let policy = PermissionPolicy::permissive().deny("mcp__*");
assert_eq!(
policy.check("mcp__longvt__search", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("mcp__pencil__draw", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("mcp__any__tool", &serde_json::json!({})),
PermissionDecision::Deny
);
assert_eq!(
policy.check("read", &serde_json::json!({"file_path": "test.txt"})),
PermissionDecision::Allow
);
assert_eq!(
policy.check("bash", &serde_json::json!({"command": "ls"})),
PermissionDecision::Allow
);
println!("✅ Test 5: MCP wildcard variations - PASSED");
}