use crate::approval_facts::{ApprovalFacts, HostFacts};
use serde_json::json;
use std::path::PathBuf;
const SHELL_TYPED_ARGV_LINE: &str = " typed argv: no shell of saya's own, one element per argument — the program is itself a shell or interpreter, unsandboxed like the lane, and it interprets what it receives: metacharacters, pipes, redirects and all";
const PLAIN_TYPED_ARGV_LINE: &str =
" typed argv: no shell, no interpolation, one element per argument";
fn host_facts() -> ApprovalFacts {
ApprovalFacts {
host: Some(HostFacts {
workspace_root: PathBuf::from("/home/user/proj"),
timeout_seconds: 600,
pass_env: Vec::new(),
}),
..ApprovalFacts::default()
}
}
fn body_for(program: &str, args: &[&str]) -> String {
let arguments = json!({"program": program, "args": args});
crate::approval_facts::call_facts(
"run_command",
&arguments,
Some(format!("command:{program}").as_str()),
&host_facts(),
None,
None,
)
.expect("the host lane states its own facts")
}
#[test]
fn a_shell_program_does_not_claim_no_shell() {
let body = body_for("bash", &["-c", "echo hi"]);
assert!(
!body.contains(PLAIN_TYPED_ARGV_LINE),
"a shell program must not claim the unqualified no-shell line: {body}"
);
}
#[test]
fn a_non_shell_program_keeps_its_typed_argv_bytes() {
let body = body_for("npm", &["install"]);
assert!(
body.contains(PLAIN_TYPED_ARGV_LINE),
"the non-shell line keeps its exact bytes: {body}"
);
}
#[test]
fn the_shell_line_says_the_argument_is_interpreted() {
let body = body_for("bash", &["-c", "echo hi"]);
assert!(
body.contains(SHELL_TYPED_ARGV_LINE),
"the shell line states the argv contract and the interpretation fact: {body}"
);
}
#[test]
fn the_interpreter_warning_still_rides_alongside() {
let body = body_for("bash", &["-c", "echo hi"]);
assert!(
body.contains(SHELL_TYPED_ARGV_LINE),
"the shell typed-argv line rides: {body}"
);
assert!(
body.contains("interpreter approval:"),
"the existing interpreter-approval line still rides alongside: {body}"
);
}
#[test]
fn every_refused_runner_program_gets_the_shell_line_not_just_bash() {
for program in [
"sh", "bash", "dash", "zsh", "fish", "python3", "node", "perl",
] {
let body = body_for(program, &["-c", "echo hi"]);
assert!(
!body.contains(PLAIN_TYPED_ARGV_LINE),
"{program} must not claim the unqualified no-shell line: {body}"
);
assert!(
body.contains(SHELL_TYPED_ARGV_LINE),
"{program} carries the shell typed-argv line: {body}"
);
}
}