An AI agent built to do Ralph loops - plan mode for planning and ralph mode for implementing.
at new-directions 168 lines 5.0 kB view raw
1use rustagent::agent::builtin_profiles; 2use rustagent::security::scope::{FileOperation, ScopeCheck}; 3 4#[test] 5fn test_planner_profile_readonly_scope() { 6 let profile = builtin_profiles::planner(); 7 8 // Planner has read_only: true 9 assert!(profile.security.read_only); 10 assert!(!profile.security.can_create_files); 11 12 // Should deny writes 13 let result = profile 14 .security 15 .check_path("src/main.rs", FileOperation::Write); 16 assert_eq!(result, ScopeCheck::Denied("read-only scope".to_string())); 17 18 // Should allow reads 19 let result = profile 20 .security 21 .check_path("src/main.rs", FileOperation::Read); 22 assert_eq!(result, ScopeCheck::Allowed); 23 24 // Should deny file creation (read-only takes precedence) 25 let result = profile 26 .security 27 .check_path("src/newfile.rs", FileOperation::Create); 28 assert!(matches!(result, ScopeCheck::Denied(_))); 29} 30 31#[test] 32fn test_coder_profile_writable_scope() { 33 let profile = builtin_profiles::coder(); 34 35 // Coder should allow writes 36 assert!(!profile.security.read_only); 37 assert!(profile.security.can_create_files); 38 39 // Should allow writes 40 let result = profile 41 .security 42 .check_path("src/main.rs", FileOperation::Write); 43 assert_eq!(result, ScopeCheck::Allowed); 44 45 // Should allow reads 46 let result = profile 47 .security 48 .check_path("src/main.rs", FileOperation::Read); 49 assert_eq!(result, ScopeCheck::Allowed); 50 51 // Should allow file creation 52 let result = profile 53 .security 54 .check_path("src/newfile.rs", FileOperation::Create); 55 assert_eq!(result, ScopeCheck::Allowed); 56} 57 58#[test] 59fn test_coder_profile_commands() { 60 let profile = builtin_profiles::coder(); 61 62 // Coder allows cargo commands 63 let result = profile.security.check_command("cargo test"); 64 assert_eq!(result, ScopeCheck::Allowed); 65 66 // Coder allows any command (wildcard) 67 let result = profile.security.check_command("any command"); 68 assert_eq!(result, ScopeCheck::Allowed); 69} 70 71#[test] 72fn test_reviewer_profile_readonly_scope() { 73 let profile = builtin_profiles::reviewer(); 74 75 // Reviewer has read_only: true 76 assert!(profile.security.read_only); 77 assert!(!profile.security.can_create_files); 78 79 // Should deny writes 80 let result = profile 81 .security 82 .check_path("src/main.rs", FileOperation::Write); 83 assert_eq!(result, ScopeCheck::Denied("read-only scope".to_string())); 84 85 // Should allow reads 86 let result = profile 87 .security 88 .check_path("src/main.rs", FileOperation::Read); 89 assert_eq!(result, ScopeCheck::Allowed); 90} 91 92#[test] 93fn test_researcher_profile_readonly_scope() { 94 let profile = builtin_profiles::researcher(); 95 96 // Researcher has read_only: true 97 assert!(profile.security.read_only); 98 assert!(!profile.security.can_create_files); 99 100 // Should deny writes 101 let result = profile 102 .security 103 .check_path("src/main.rs", FileOperation::Write); 104 assert_eq!(result, ScopeCheck::Denied("read-only scope".to_string())); 105 106 // Should allow reads 107 let result = profile 108 .security 109 .check_path("src/main.rs", FileOperation::Read); 110 assert_eq!(result, ScopeCheck::Allowed); 111} 112 113#[test] 114fn test_tester_profile_writable_scope() { 115 let profile = builtin_profiles::tester(); 116 117 // Tester should allow writes (for writing tests) 118 assert!(!profile.security.read_only); 119 assert!(profile.security.can_create_files); 120 121 // Should allow writes 122 let result = profile 123 .security 124 .check_path("tests/test.rs", FileOperation::Write); 125 assert_eq!(result, ScopeCheck::Allowed); 126 127 // Should allow file creation 128 let result = profile 129 .security 130 .check_path("tests/newtest.rs", FileOperation::Create); 131 assert_eq!(result, ScopeCheck::Allowed); 132} 133 134#[test] 135fn test_all_profiles_have_wildcard_paths() { 136 // All built-in profiles allow wildcard paths for maximum flexibility 137 let profiles = vec![ 138 builtin_profiles::planner(), 139 builtin_profiles::coder(), 140 builtin_profiles::reviewer(), 141 builtin_profiles::tester(), 142 builtin_profiles::researcher(), 143 ]; 144 145 for profile in profiles { 146 // All should have wildcard in allowed_paths 147 assert!( 148 profile.security.allowed_paths.contains(&"*".to_string()), 149 "Profile {} missing wildcard in allowed_paths", 150 profile.name 151 ); 152 153 // All should have wildcard in allowed_commands 154 assert!( 155 profile.security.allowed_commands.contains(&"*".to_string()), 156 "Profile {} missing wildcard in allowed_commands", 157 profile.name 158 ); 159 160 // All should deny network access by default 161 assert_eq!( 162 profile.security.check_network(), 163 ScopeCheck::Denied("network access not allowed".to_string()), 164 "Profile {} should deny network access", 165 profile.name 166 ); 167 } 168}