Files
galaxy/crates/acp/src/permissions_tests.rs
T

127 lines
3.8 KiB
Rust

use agent_client_protocol::schema::v1::{
PermissionOption, PermissionOptionKind, RequestPermissionOutcome, RequestPermissionRequest,
ToolCallUpdate, ToolCallUpdateFields, ToolKind,
};
use super::*;
fn permission_request() -> RequestPermissionRequest {
permission_request_for(ToolKind::Other)
}
fn permission_request_for(kind: ToolKind) -> RequestPermissionRequest {
RequestPermissionRequest::new(
"session-1",
ToolCallUpdate::new(
"tool-1",
ToolCallUpdateFields::new().title("Run command").kind(kind),
),
vec![
PermissionOption::new(
"allow-always",
"Always allow",
PermissionOptionKind::AllowAlways,
),
PermissionOption::new("allow-once", "Allow once", PermissionOptionKind::AllowOnce),
PermissionOption::new(
"reject-always",
"Always reject",
PermissionOptionKind::RejectAlways,
),
PermissionOption::new(
"reject-once",
"Reject once",
PermissionOptionKind::RejectOnce,
),
],
)
}
#[test]
fn default_handler_denies_interactive_turns() {
let request = permission_request();
let decision =
futures::executor::block_on(DenyByDefaultPermissionHandler.decide(PermissionContext {
request,
auto_approve: false,
policy: AcpPermissionPolicy::default(),
}));
assert_eq!(decision, PermissionDecision::Deny);
}
#[test]
fn default_handler_allows_only_explicit_autonomous_turns() {
let request = permission_request();
let decision =
futures::executor::block_on(DenyByDefaultPermissionHandler.decide(PermissionContext {
request,
auto_approve: true,
policy: AcpPermissionPolicy::default(),
}));
assert_eq!(decision, PermissionDecision::Allow);
}
#[test]
fn default_handler_honors_only_the_matching_profile_category() {
let policy = AcpPermissionPolicy {
read: true,
..Default::default()
};
let read =
futures::executor::block_on(DenyByDefaultPermissionHandler.decide(PermissionContext {
request: permission_request_for(ToolKind::Read),
auto_approve: false,
policy,
}));
let execute =
futures::executor::block_on(DenyByDefaultPermissionHandler.decide(PermissionContext {
request: permission_request_for(ToolKind::Execute),
auto_approve: false,
policy,
}));
assert_eq!(read, PermissionDecision::Allow);
assert_eq!(execute, PermissionDecision::Deny);
}
#[test]
fn allow_and_deny_prefer_one_shot_options() {
let request = permission_request();
let allow = outcome_for_decision(&request, PermissionDecision::Allow);
let deny = outcome_for_decision(&request, PermissionDecision::Deny);
assert_eq!(
allow,
RequestPermissionOutcome::Selected(SelectedPermissionOutcome::new("allow-once"))
);
assert_eq!(
deny,
RequestPermissionOutcome::Selected(SelectedPermissionOutcome::new("reject-once"))
);
}
#[test]
fn allow_never_silently_selects_a_persistent_option() {
let mut request = permission_request();
request
.options
.retain(|option| option.kind != PermissionOptionKind::AllowOnce);
let outcome = outcome_for_decision(&request, PermissionDecision::Allow);
assert_eq!(outcome, RequestPermissionOutcome::Cancelled);
}
#[test]
fn unknown_selected_option_is_cancelled() {
let outcome = outcome_for_decision(
&permission_request(),
PermissionDecision::Select(PermissionOptionId::new("not-advertised")),
);
assert_eq!(outcome, RequestPermissionOutcome::Cancelled);
}