use wasm_capability_contract::{CapabilityGrant, CapabilityScope, EgressIdentity};
const GRANTED_CAPABILITIES_JSON: &str = r#"[
{ "name": "http-egress", "scope": { "type": "http", "allowed_hosts": ["api.example.com"],
"identity": { "type": "sst_m2m", "client_id": "agent-runtime-invoice-processor" } } },
{ "name": "grpc-egress", "scope": { "type": "grpc", "allowed_methods": ["inventory.Inventory/Get"],
"identity": { "type": "sst_m2m", "client_id": "agent-runtime-invoice-processor" } } },
{ "name": "llm-complete", "scope": { "type": "complete", "allowed_models": ["claude-sonnet-5"] } },
{ "name": "mcp-egress", "scope": { "type": "mcp", "allowed_tools": ["search-docs"] } },
{ "name": "database", "scope": { "type": "database", "allowed_queries": ["get_invoice_by_id"] } },
{ "name": "secrets", "scope": { "type": "secrets", "allowed_secrets": ["invoice-api-key"] } }
]"#;
#[test]
fn test_adr_001_manifest_example_deserializes_into_six_grants_with_correct_fields() {
let grants: Vec<CapabilityGrant> = serde_json::from_str(GRANTED_CAPABILITIES_JSON)
.unwrap_or_else(|e| panic!("ADR-001's own manifest example must deserialize: {e}"));
assert_eq!(grants.len(), 6, "expected exactly six grants");
let by_name = |name: &str| {
grants
.iter()
.find(|g| g.name == name)
.unwrap_or_else(|| panic!("expected a grant named '{name}'"))
};
match &by_name("http-egress").scope {
CapabilityScope::Http {
allowed_hosts,
identity,
} => {
assert_eq!(allowed_hosts, &["api.example.com".to_string()]);
match identity {
EgressIdentity::SstM2m { client_id } => {
assert_eq!(client_id, "agent-runtime-invoice-processor");
}
other => panic!("expected SstM2m identity, got {other:?}"),
}
}
other => panic!("expected Http scope, got {other:?}"),
}
match &by_name("grpc-egress").scope {
CapabilityScope::Grpc {
allowed_methods, ..
} => {
assert_eq!(allowed_methods, &["inventory.Inventory/Get".to_string()]);
}
other => panic!("expected Grpc scope, got {other:?}"),
}
match &by_name("llm-complete").scope {
CapabilityScope::Complete { allowed_models } => {
assert_eq!(allowed_models, &["claude-sonnet-5".to_string()]);
}
other => panic!("expected Complete scope, got {other:?}"),
}
match &by_name("mcp-egress").scope {
CapabilityScope::Mcp { allowed_tools } => {
assert_eq!(allowed_tools, &["search-docs".to_string()]);
}
other => panic!("expected Mcp scope, got {other:?}"),
}
match &by_name("database").scope {
CapabilityScope::Database { allowed_queries } => {
assert_eq!(allowed_queries, &["get_invoice_by_id".to_string()]);
}
other => panic!("expected Database scope, got {other:?}"),
}
match &by_name("secrets").scope {
CapabilityScope::Secrets { allowed_secrets } => {
assert_eq!(allowed_secrets, &["invoice-api-key".to_string()]);
}
other => panic!("expected Secrets scope, got {other:?}"),
}
}
#[test]
fn test_full_granted_capabilities_list_round_trips_unchanged() {
let grants: Vec<CapabilityGrant> = serde_json::from_str(GRANTED_CAPABILITIES_JSON)
.unwrap_or_else(|e| panic!("must deserialize: {e}"));
let json = serde_json::to_string(&grants).unwrap_or_else(|e| panic!("must serialize: {e}"));
let restored: Vec<CapabilityGrant> =
serde_json::from_str(&json).unwrap_or_else(|e| panic!("must re-deserialize: {e}"));
assert_eq!(restored, grants);
}