//! Tests for grant files. Do not edit these or the fixtures. use proto::{Constraints, DataClass, Grant, Mode, Timestamp}; fn parse(name: &str) -> Result { let path = format!("{}/tests/fixtures/grant/{name}", env!("CARGO_MANIFEST_DIR")); let text = std::fs::read_to_string(&path).unwrap_or_else(|e| panic!("{path}: {e}")); toml::from_str(&text) } #[test] fn minimal_grant_gets_safe_defaults() { let want = Grant { tool: "read_file".to_string(), mode: Mode::Auto, max_taint: DataClass::Private, result_class: DataClass::Private, untrusted: true, expires: None, secret: None, constraints: Constraints::default(), }; assert_eq!(parse("minimal.toml").unwrap(), want); assert_eq!(Constraints::default().paths, Vec::::new()); } #[test] fn full_grant() { let want = Grant { tool: "http_fetch".to_string(), mode: Mode::Ask, max_taint: DataClass::Secret, result_class: DataClass::Public, untrusted: false, expires: Some(Timestamp::parse("2026-12-31T00:00:00.000Z").unwrap()), secret: Some("example-api-token".to_string()), constraints: Constraints { paths: vec!["/home/kyle/notes/**".to_string()], hosts: vec!["example.com".to_string(), "api.example.com".to_string()], patterns: vec!["^GET ".to_string()], }, }; assert_eq!(parse("full.toml").unwrap(), want); } #[test] fn mistakes_in_grant_files_are_errors() { for name in [ "unknown_field.toml", "unknown_constraint.toml", "bad_mode.toml", "missing_max_taint.toml", ] { assert!(parse(name).is_err(), "{name} was accepted"); } } #[test] fn modes_are_lowercase() { for (mode, text) in [ (Mode::Auto, "auto"), (Mode::Ask, "ask"), (Mode::Deny, "deny"), ] { assert_eq!(serde_json::to_string(&mode).unwrap(), format!("\"{text}\"")); } }