use std::fs;
use assert_cmd::Command;
use predicates::prelude::*;
use serde_json::Value;
use tempfile::tempdir;
const TLS_SEED: &str = "tls-profile-integration-seed";
const TLS_LABEL: &str = "tls-integration";
fn run_bundle(bundle_dir: &std::path::Path) {
let mut cmd = Command::cargo_bin("uselesskey").expect("bin exists");
cmd.args([
"bundle",
"--profile",
"tls",
"--seed",
TLS_SEED,
"--label",
TLS_LABEL,
"--out",
bundle_dir.to_str().expect("utf-8 path"),
]);
cmd.assert().success();
}
#[test]
fn tls_bundle_emits_expected_layout() {
let dir = tempdir().expect("tempdir");
let bundle_dir = dir.path().join("tls");
run_bundle(&bundle_dir);
for relative in [
"certs/valid-leaf.pem",
"certs/valid-chain.pem",
"certs/negative-expired-leaf.pem",
"certs/negative-not-yet-valid.pem",
"certs/negative-wrong-hostname.pem",
"certs/negative-untrusted-root.pem",
"evidence/tls-profile.md",
"receipts/materialization.json",
"receipts/audit-surface.json",
"manifest.json",
] {
let path = bundle_dir.join(relative);
assert!(
path.exists(),
"expected bundle file missing: {}",
path.display()
);
let meta = fs::metadata(&path).expect("stat fixture");
assert!(meta.len() > 0, "fixture {} should not be empty", relative);
}
let manifest: Value =
serde_json::from_slice(&fs::read(bundle_dir.join("manifest.json")).expect("read manifest"))
.expect("manifest json");
assert_eq!(manifest["profile"], "tls");
assert_eq!(manifest["seed"], TLS_SEED);
assert_eq!(manifest["label"], TLS_LABEL);
let artifacts = manifest["artifacts"].as_array().expect("artifacts array");
assert_eq!(artifacts.len(), 7); assert!(
artifacts
.iter()
.all(|artifact| artifact["profile"] == "tls" && artifact["scanner_safe"] == true)
);
}
#[test]
fn tls_bundle_certificate_fixtures_parse_as_pem_certificates() {
let dir = tempdir().expect("tempdir");
let bundle_dir = dir.path().join("tls");
run_bundle(&bundle_dir);
for single_cert in [
"certs/valid-leaf.pem",
"certs/negative-expired-leaf.pem",
"certs/negative-not-yet-valid.pem",
"certs/negative-wrong-hostname.pem",
"certs/negative-untrusted-root.pem",
] {
let text = fs::read_to_string(bundle_dir.join(single_cert)).expect("read cert");
let begin_count = text.matches("-----BEGIN CERTIFICATE-----").count();
let end_count = text.matches("-----END CERTIFICATE-----").count();
assert_eq!(
begin_count, 1,
"{single_cert} should contain exactly one BEGIN CERTIFICATE block",
);
assert_eq!(
end_count, 1,
"{single_cert} should contain exactly one END CERTIFICATE block",
);
}
let chain = fs::read_to_string(bundle_dir.join("certs/valid-chain.pem")).expect("read chain");
let chain_count = chain.matches("-----BEGIN CERTIFICATE-----").count();
assert_eq!(
chain_count, 3,
"valid-chain.pem should contain leaf + intermediate + root"
);
let wrong = fs::read_to_string(bundle_dir.join("certs/negative-wrong-hostname.pem"))
.expect("read wrong-hostname");
assert!(!wrong.is_empty(), "wrong-hostname leaf should be non-empty");
let valid_leaf =
fs::read_to_string(bundle_dir.join("certs/valid-leaf.pem")).expect("read valid leaf");
let untrusted_leaf = fs::read_to_string(bundle_dir.join("certs/negative-untrusted-root.pem"))
.expect("read untrusted leaf");
assert_ne!(
valid_leaf, untrusted_leaf,
"untrusted-root leaf must differ from happy-path valid leaf"
);
}
#[test]
fn tls_bundle_is_deterministic_across_runs() {
let first = tempdir().expect("tempdir1");
let second = tempdir().expect("tempdir2");
let first_dir = first.path().join("tls");
let second_dir = second.path().join("tls");
run_bundle(&first_dir);
run_bundle(&second_dir);
for relative in [
"certs/valid-leaf.pem",
"certs/valid-chain.pem",
"certs/negative-expired-leaf.pem",
"certs/negative-not-yet-valid.pem",
"certs/negative-wrong-hostname.pem",
"certs/negative-untrusted-root.pem",
"evidence/tls-profile.md",
"receipts/materialization.json",
"receipts/audit-surface.json",
"manifest.json",
] {
let a = fs::read(first_dir.join(relative)).expect("read first");
let b = fs::read(second_dir.join(relative)).expect("read second");
assert_eq!(
a, b,
"{relative} must be byte-identical across two bundle invocations \
with the same seed",
);
}
}
#[test]
fn tls_evidence_markdown_lists_all_fixtures_with_failure_classes() {
let dir = tempdir().expect("tempdir");
let bundle_dir = dir.path().join("tls");
run_bundle(&bundle_dir);
let evidence =
fs::read_to_string(bundle_dir.join("evidence/tls-profile.md")).expect("read evidence doc");
assert!(
evidence.contains("# TLS contract-pack profile evidence"),
"evidence doc must carry its title heading"
);
assert!(
evidence.contains("docs/release/v0.8.0-tls-profile-design.md"),
"evidence doc must point at the design doc"
);
assert!(
evidence.contains("uselesskey bundle --profile tls"),
"evidence doc must name the command that produces the bundle"
);
assert!(
evidence.contains("Expected hostname:"),
"evidence doc must declare the expected hostname"
);
assert!(
evidence.contains("Hostname-mismatch wrong hostname:"),
"evidence doc must declare the wrong hostname used by the negative fixture"
);
assert!(
evidence.contains("| File | Role | Failure class |"),
"evidence doc must include the per-fixture table header"
);
for fixture in [
"`certs/valid-leaf.pem`",
"`certs/valid-chain.pem`",
"`certs/negative-expired-leaf.pem`",
"`certs/negative-not-yet-valid.pem`",
"`certs/negative-wrong-hostname.pem`",
"`certs/negative-untrusted-root.pem`",
] {
assert!(
evidence.contains(fixture),
"evidence doc must mention fixture path {fixture}"
);
}
for failure_class in [
"expired",
"not yet valid",
"hostname mismatch",
"unknown CA",
] {
assert!(
evidence.contains(failure_class),
"evidence doc must name failure class {failure_class:?}"
);
}
assert!(
evidence.contains("(none - happy path)"),
"evidence doc must mark happy-path fixtures with no failure class"
);
}
#[test]
fn tls_bundle_round_trips_through_verify_bundle() {
let dir = tempdir().expect("tempdir");
let bundle_dir = dir.path().join("tls");
run_bundle(&bundle_dir);
let mut verify = Command::cargo_bin("uselesskey").expect("bin exists");
verify.args([
"verify-bundle",
"--path",
bundle_dir.to_str().expect("utf-8 path"),
]);
verify
.assert()
.success()
.stdout(predicate::str::contains("\"status\": \"ok\""));
fs::write(
bundle_dir.join("certs/negative-expired-leaf.pem"),
"not a certificate\n",
)
.expect("mutate negative leaf");
let mut verify_bad = Command::cargo_bin("uselesskey").expect("bin exists");
verify_bad.args([
"verify-bundle",
"--path",
bundle_dir.to_str().expect("utf-8 path"),
]);
verify_bad
.assert()
.failure()
.stderr(predicate::str::contains("content mismatch"));
}