#![allow(clippy::unwrap_used)]
mod common;
use common::run_rippy;
#[test]
fn claude_allow_safe_command() {
let json = r#"{"tool_name":"Bash","tool_input":{"command":"git status"}}"#;
let (stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "allow");
}
#[test]
fn claude_ask_dangerous_command() {
let json = r#"{"tool_name":"Bash","tool_input":{"command":"rm -rf /"}}"#;
let (stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 2);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "ask");
}
#[test]
fn claude_pipeline_safe() {
let json = r#"{"tool_name":"Bash","tool_input":{"command":"cat file | grep pattern | sort"}}"#;
let (stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "allow");
}
#[test]
fn claude_git_push_asks() {
let json = r#"{"tool_name":"Bash","tool_input":{"command":"git push origin main"}}"#;
let (stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 2);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "ask");
}
#[test]
fn gemini_allow_safe() {
let json = r#"{"tool_name":"bash","tool_input":"ls -la"}"#;
let (stdout, code) = run_rippy(json, "gemini", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["decision"], "allow");
}
#[test]
fn gemini_deny_dangerous() {
let json = r#"{"tool_name":"bash","tool_input":"rm -rf /"}"#;
let (stdout, code) = run_rippy(json, "gemini", &[]);
assert_eq!(code, 2);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["decision"], "deny");
}
#[test]
fn cursor_allow_safe() {
let json = r#"{"tool_name":"bash","command":"echo hello"}"#;
let (stdout, code) = run_rippy(json, "cursor", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["permission"], "allow");
}
#[test]
fn codex_mode_safe_command() {
let json = r#"{"tool_name":"bash","tool_input":"ls -la"}"#;
let (stdout, code) = run_rippy(json, "codex", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["decision"], "allow");
}
#[test]
fn codex_mode_dangerous_command() {
let json = r#"{"tool_name":"bash","tool_input":"rm -rf /"}"#;
let (stdout, code) = run_rippy(json, "codex", &[]);
assert_eq!(code, 2);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["decision"], "deny");
}
#[test]
fn post_tool_use_returns_allow() {
let json =
r#"{"tool_name":"Bash","tool_input":{"command":"ls"},"tool_result":{"output":"file.txt"}}"#;
let (stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 0);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "allow");
}
#[test]
fn dippy_config_file_loaded() {
let dir = tempfile::tempdir().unwrap();
let config_path = dir.path().join(".dippy");
std::fs::write(&config_path, "deny rm -rf \"blocked by dippy config\"").unwrap();
let json = r#"{"tool_name":"Bash","tool_input":{"command":"rm -rf /tmp"}}"#;
let (stdout, code) = run_rippy(json, "claude", &["--config", config_path.to_str().unwrap()]);
assert_eq!(code, 2);
let v: serde_json::Value = serde_json::from_str(&stdout).unwrap();
assert_eq!(v["hookSpecificOutput"]["permissionDecision"], "deny");
}
#[test]
fn empty_command_in_payload() {
let json = r#"{"tool_name":"Bash","tool_input":{"command":""}}"#;
let (_stdout, code) = run_rippy(json, "claude", &[]);
assert_eq!(code, 0);
}