use permissions::{PermissionManager, Mode, Tool, PermissionDecision}; #[test] fn plan_mode_blocks_write_bash_by_default() { let mgr = PermissionManager::new(Mode::Plan); // Plan mode should allow read operations assert_eq!(mgr.check(Tool::Read, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Grep, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Glob, None), PermissionDecision::Allow); // Plan mode should ask for write operations assert_eq!(mgr.check(Tool::Write, None), PermissionDecision::Ask); assert_eq!(mgr.check(Tool::Edit, None), PermissionDecision::Ask); // Plan mode should ask for Bash assert_eq!(mgr.check(Tool::Bash, None), PermissionDecision::Ask); } #[test] fn accept_edits_mode_allows_edit_write() { let mgr = PermissionManager::new(Mode::AcceptEdits); // AcceptEdits mode should allow read operations assert_eq!(mgr.check(Tool::Read, None), PermissionDecision::Allow); // AcceptEdits mode should allow edit/write assert_eq!(mgr.check(Tool::Edit, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Write, None), PermissionDecision::Allow); // But still ask for Bash assert_eq!(mgr.check(Tool::Bash, None), PermissionDecision::Ask); } #[test] fn code_mode_allows_everything() { let mgr = PermissionManager::new(Mode::Code); assert_eq!(mgr.check(Tool::Read, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Write, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Edit, None), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Bash, None), PermissionDecision::Allow); } #[test] fn bash_pattern_matching() { let mut mgr = PermissionManager::new(Mode::Plan); // Add a rule to allow "npm test" mgr.add_rule(Tool::Bash, Some("npm test".to_string()), permissions::Action::Allow); // Should allow the exact command assert_eq!(mgr.check(Tool::Bash, Some("npm test")), PermissionDecision::Allow); // Should still ask for other commands assert_eq!(mgr.check(Tool::Bash, Some("rm -rf /")), PermissionDecision::Ask); } #[test] fn bash_prefix_matching() { let mut mgr = PermissionManager::new(Mode::Plan); // Add a rule to allow "npm test:*" (prefix match) mgr.add_rule(Tool::Bash, Some("npm test:*".to_string()), permissions::Action::Allow); // Should allow commands matching the prefix assert_eq!(mgr.check(Tool::Bash, Some("npm test:unit")), PermissionDecision::Allow); assert_eq!(mgr.check(Tool::Bash, Some("npm test:integration")), PermissionDecision::Allow); // Should not allow non-matching commands assert_eq!(mgr.check(Tool::Bash, Some("npm install")), PermissionDecision::Ask); } #[test] fn deny_rules_take_precedence() { let mut mgr = PermissionManager::new(Mode::Code); // Even in Code mode, we can deny specific operations mgr.add_rule(Tool::Bash, Some("rm -rf*".to_string()), permissions::Action::Deny); assert_eq!(mgr.check(Tool::Bash, Some("rm -rf /")), PermissionDecision::Deny); // But other commands are still allowed assert_eq!(mgr.check(Tool::Bash, Some("ls")), PermissionDecision::Allow); }