use dirigent_fermata::core::{Decision, Op, Policy}; use std::fs; use tempfile::TempDir; fn make_project(botignore: &str, toml_text: &str) -> TempDir { let tmp = TempDir::new().unwrap(); fs::write(tmp.path().join(".botignore"), botignore).unwrap(); if !toml_text.is_empty() { fs::write(tmp.path().join("botignore.toml"), toml_text).unwrap(); } tmp } #[test] fn botignore_blocks_read() { let tmp = make_project(".env\n", ""); let policy = Policy::load(tmp.path()).unwrap(); let target = tmp.path().join(".env"); fs::write(&target, "").unwrap(); let d = policy.check(Op::Read, &target).unwrap(); assert!(matches!(d, Decision::Deny(_))); } #[test] fn botignore_blocks_write_too() { let tmp = make_project(".env\n", ""); let policy = Policy::load(tmp.path()).unwrap(); let target = tmp.path().join(".env"); let d = policy.check(Op::Write, &target).unwrap(); assert!(matches!(d, Decision::Deny(_))); } #[test] fn unmatched_path_allowed() { let tmp = make_project(".env\n", ""); let policy = Policy::load(tmp.path()).unwrap(); let target = tmp.path().join("src/main.rs"); fs::create_dir_all(target.parent().unwrap()).unwrap(); fs::write(&target, "").unwrap(); let d = policy.check(Op::Read, &target).unwrap(); assert_eq!(d, Decision::Allow); } #[test] fn toml_read_block_applies_only_to_read() { let tmp = make_project("", "[read]\npatterns = [\"secrets/**\"]\n"); let policy = Policy::load(tmp.path()).unwrap(); let target = tmp.path().join("secrets/key.pem"); fs::create_dir_all(target.parent().unwrap()).unwrap(); fs::write(&target, "").unwrap(); assert!(matches!(policy.check(Op::Read, &target).unwrap(), Decision::Deny(_))); assert_eq!(policy.check(Op::Write, &target).unwrap(), Decision::Allow); } #[test] fn toml_write_block_applies_only_to_write() { let tmp = make_project("", "[write]\npatterns = [\"vendor/**\"]\n"); let policy = Policy::load(tmp.path()).unwrap(); let target = tmp.path().join("vendor/lib.rs"); fs::create_dir_all(target.parent().unwrap()).unwrap(); fs::write(&target, "").unwrap(); assert_eq!(policy.check(Op::Read, &target).unwrap(), Decision::Allow); assert!(matches!(policy.check(Op::Write, &target).unwrap(), Decision::Deny(_))); }