ci/verbs/tests/scorecard_summary.rs
//! The nightly Scorecard step's page: the aggregate, a row per check that ran, and by
//! name every check local mode cannot run.
use serde_json::json;
#[test]
fn the_summary_scores_each_check_and_names_what_local_mode_cannot_run() {
let answer = json!({
"scorecard": { "version": "v5.6.0" },
"repo": { "name": "file:///src/gunnar", "commit": "34493f5c0123" },
"score": 4.4,
"checks": [
{ "name": "Binary-Artifacts", "score": 10, "reason": "no binaries found in the repo" },
{ "name": "Packaging", "score": -1, "reason": "packaging workflow not detected" },
{ "name": "Vulnerabilities", "score": 0, "reason": "40 existing vulnerabilities | detected" }
]
});
let md = ci_verbs::scorecard::summary(&answer, "gunnar");
assert!(md.starts_with("OpenSSF Scorecard v5.6.0, local mode, on `gunnar` at `34493f5c`: **4.4 / 10**"), "{md}");
assert!(md.contains("| Binary-Artifacts | 10 / 10 | no binaries found in the repo |"), "{md}");
assert!(md.contains("| Packaging | inconclusive |"), "{md}");
assert!(md.contains("40 existing vulnerabilities \\| detected"), "a pipe is escaped: {md}");
let missing = ci_verbs::scorecard::not_run(&answer);
for k in ["Branch-Protection", "Code-Review", "Maintained", "Signed-Releases", "Webhooks", "CI-Tests", "Contributors"] {
assert!(missing.contains(&k), "{k} is not run in local mode: {missing:?}");
assert!(md.contains(k), "{k} is named on the page: {md}");
}
assert!(!missing.contains(&"Binary-Artifacts"));
assert_eq!(missing.len(), ci_verbs::scorecard::KNOWN_CHECKS.len() - 3);
}
#[test]
fn the_verb_fails_by_name_when_scorecard_cannot_run() {
let d = std::env::temp_dir().join(format!("ci-verbs-sc-{}", std::process::id()));
let args: Vec<String> = ["--checkout", ".", "--out", d.to_str().unwrap(), "--bin", "/nonexistent/scorecard"].iter().map(|s| s.to_string()).collect();
assert_eq!(ci_verbs::scorecard::verb(&args), 1);
assert_eq!(ci_verbs::scorecard::verb(&[]), 2, "usage");
let _ = std::fs::remove_dir_all(d);
}