use crate::e2e::support::{binary, write_temp_file};
use std::process::Command;
#[test]
fn scan_malformed_k8s_secret_warns_about_lost_decode_through() {
let (_dir, path) = write_temp_file(
"secret.yaml",
"apiVersion: v1\nkind: Secret\ndata:\n api-key: [unclosed\n",
);
let output = Command::new(binary())
.args([
"scan",
"--backend",
"simd",
"--daemon=off",
"--progress",
"--format",
"json",
])
.arg(&path)
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.output()
.expect("spawn");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("matched a structured format") && stderr.contains("FAILED to parse"),
"a malformed k8s Secret must surface the structured decode-through gap on \
stderr (Law 10), not swallow it; got: {stderr}"
);
assert!(
stderr.contains("NOT decoded"),
"the warning must state that encoded secrets were not decoded; got: {stderr}"
);
}
#[test]
fn scan_malformed_k8s_secret_sarif_reports_lost_decode_through() {
let (_dir, path) = write_temp_file(
"secret.yaml",
"apiVersion: v1\nkind: Secret\ndata:\n api-key: [unclosed\n",
);
let output = Command::new(binary())
.args([
"scan",
"--backend",
"simd",
"--daemon=off",
"--format",
"sarif",
])
.arg(&path)
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.output()
.expect("spawn");
assert_eq!(
output.status.code(),
Some(13),
"malformed k8s Secret raw-text scan must fail closed on incomplete \
decode-through coverage (exit 13); status={:?} stderr={}",
output.status.code(),
String::from_utf8_lossy(&output.stderr)
);
let sarif: serde_json::Value =
serde_json::from_slice(&output.stdout).expect("SARIF stdout must be JSON");
let notifications = sarif["runs"][0]["invocations"][0]["toolExecutionNotifications"]
.as_array()
.expect("scanner structured parse gap must create SARIF notifications");
assert!(
notifications.iter().any(|notification| {
notification["properties"]["reason"].as_str()
== Some("scanner structured parse failed (raw text scanned; encoded structured values not decoded)")
&& notification["properties"]["count"].as_u64() == Some(1)
}),
"SARIF notifications must include the scanner structured parse gap; sarif={sarif}"
);
}
#[test]
fn scan_valid_k8s_secret_does_not_warn() {
let (_dir, path) = write_temp_file(
"secret.yaml",
"apiVersion: v1\nkind: Secret\nmetadata:\n name: s\ndata:\n api-key: YWJjMTIz\n",
);
let output = Command::new(binary())
.args([
"scan",
"--backend",
"simd",
"--daemon=off",
"--progress",
"--format",
"json",
])
.arg(&path)
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.output()
.expect("spawn");
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
!stderr.contains("matched a structured format"),
"a valid k8s Secret must NOT trigger the parse-failure warning; got: {stderr}"
);
}