use anyhow::Result; use assert_cmd::Command; use serde_json::Value; #[test] fn scan_rules_has_no_validated_findings() -> Result<()> { let output = Command::new(assert_cmd::cargo::cargo_bin!("kingfisher")) .args([ "scan", "crates/kingfisher-rules/data/rules", "--format", "json", "--no-update-check", "--only-valid", ]) .output()?; let stdout = String::from_utf8_lossy(&output.stdout); // Find the first '[' — start of array let start = match stdout.find('[') { Some(i) => i, None => return Ok(()), // no array found }; let mut depth = 0usize; let mut end = None; for (i, ch) in stdout.char_indices().skip(start) { match ch { '[' => depth += 1, ']' => { depth -= 1; if depth == 0 { end = Some(i); break; } } _ => {} } } let json_array_str = match end { Some(end_idx) => &stdout[start..=end_idx], None => return Ok(()), // no matching close found }; if json_array_str.trim().is_empty() { return Ok(()); } let findings: Vec = serde_json::from_str(json_array_str)?; let validated_rule_ids: Vec = findings .iter() .filter_map(|finding| { let status = finding["finding"]["validation"]["status"] .as_str() .unwrap_or("") .to_ascii_lowercase(); if status == "active credential" { Some(finding["rule"]["id"].as_str().unwrap_or("unknown").to_string()) } else { None } }) .collect(); assert!( validated_rule_ids.is_empty(), "Validated findings detected in rules: {}", validated_rule_ids.join(", ") ); if !output.status.success() { let stderr = String::from_utf8_lossy(&output.stderr); panic!( "kingfisher scan exited non-zero without validated findings in output.\nstdout:\n{}\nstderr:\n{}", stdout, stderr ); } Ok(()) }