use super::*;
#[test]
fn the_checker_reads_both_value_types_alike() {
use airs_test_harness::live::gateway as live;
let schemas = [
r#"{"type":"string"}"#,
r#"{"type":["string","null"]}"#,
r#"{"type":[]}"#,
r#"{"type":"basic"}"#,
r#"{"items":{}}"#,
r#""string""#,
];
for text in schemas {
let value: serde_json::Value = serde_json::from_str(text).unwrap();
let own = check::is_schema(&parse(text).unwrap());
assert_eq!(live::is_schema(&value), own, "{text}");
assert_eq!(check::is_schema(&value), own, "{text}");
}
for (received, printed) in PINNED_DOCUMENTS {
for text in [received, printed] {
let value: serde_json::Value = serde_json::from_str(text).unwrap();
assert_eq!(live::withheld(&value), checked(text), "{text}");
assert_eq!(check::withheld(&value), checked(text), "{text}");
}
}
}
#[test]
fn the_live_tier_accepts_what_the_cli_prints() {
for (received, printed) in PINNED_DOCUMENTS {
let (text, _) = applied(received, &PLAIN);
assert_eq!(text, *printed, "received: {received}");
assert!(checked(&text), "printed: {text}");
assert_eq!(
checked(received),
received == printed,
"received: {received}"
);
}
}
#[test]
fn d238_a_planted_credential_never_prints_in_any_format() {
let planted = withhold_rules::corpus::planted();
for case in &planted {
let secrets = SecretSet::default();
let mut doc = parse(&case.document).unwrap();
apply(&mut doc, &PLAIN, &secrets);
assert!(
check::withheld(&doc),
"{}: {}",
case.case,
to_compact(&doc).unwrap()
);
for (format, text) in printed_formats(&doc) {
assert!(
!text.contains(&case.secret),
"{} printed in {format:?}: {text}",
case.case
);
assert!(
text.contains(&case.control),
"{} in {format:?}: {text}",
case.case
);
}
let mut rows = OValue::Array(vec![OValue::Object(vec![(
"request_body".into(),
OValue::String(case.document.clone()),
)])]);
apply_audit(&mut rows, true, &SecretSet::default());
let text = to_compact(&rows).unwrap();
assert!(
!text.contains(&case.secret),
"{} revealed: {text}",
case.case
);
}
}
fn changed_paths(
received: &OValue,
printed: &OValue,
at: &mut check::Path,
out: &mut std::collections::BTreeSet<check::Path>,
) {
use check::Step;
if received == printed {
return;
}
let mut under = |step: Step, received: &OValue, printed: &OValue, at: &mut check::Path| {
at.push(step);
changed_paths(received, printed, at, out);
at.pop();
};
match (received, printed) {
(OValue::Object(a), OValue::Object(b))
if a.len() == b.len() && a.iter().zip(b).all(|(x, y)| x.0 == y.0) =>
{
for ((name, x), (_, y)) in a.iter().zip(b) {
under(Step::Member(name.clone()), x, y, at);
}
}
(OValue::Array(a), OValue::Array(b)) if a.len() == b.len() => {
for (index, (x, y)) in a.iter().zip(b).enumerate() {
under(Step::Item(index), x, y, at);
}
}
(OValue::String(a), OValue::String(b)) => match (json_document(a), json_document(b)) {
(Some(x), Some(y)) => under(Step::Text, &x, &y, at),
_ => {
out.insert(at.clone());
}
},
_ => {
out.insert(at.clone());
}
}
}
#[test]
fn the_checker_names_every_value_the_cli_changes() {
let pinned = PINNED_DOCUMENTS
.iter()
.map(|(received, _)| ((*received).to_owned(), (*received).to_owned()));
let planted = withhold_rules::corpus::planted()
.into_iter()
.map(|case| (case.document, case.case));
let mut documents = 0;
for (document, case) in pinned.chain(planted) {
let received = parse(&document).unwrap();
let mut printed = received.clone();
names_and_urls(&mut printed, &mut Vec::new());
let mut cli = std::collections::BTreeSet::new();
changed_paths(&received, &printed, &mut Vec::new(), &mut cli);
let checker = check::violations(&received);
assert_eq!(cli, checker, "{case}: {document}");
assert!(check::violations(&printed).is_empty(), "{case}: {document}");
documents += 1;
}
assert!(documents > 5000, "{documents}");
}
#[test]
fn d238_real_world_texts_print_as_pinned() {
use check::Step;
for case in withhold_rules::corpus::REAL_WORLD_TEXTS {
let (received, printed) = case.documents();
let (text, secrets) = applied(&received, &PLAIN);
assert_eq!(text, printed, "{}", case.case);
for secret in case.registered {
assert!(secrets.carried_by(secret), "{}: {secret}", case.case);
}
for word in case.kept {
assert!(!secrets.carried_by(word), "{}: {word}", case.case);
}
let as_received = parse(&received).unwrap();
let expected: std::collections::BTreeSet<check::Path> = if case.text == case.printed {
std::collections::BTreeSet::new()
} else {
[vec![Step::Item(0), Step::Member("note".into())]].into()
};
assert_eq!(check::violations(&as_received), expected, "{}", case.case);
let as_printed = parse(&text).unwrap();
assert!(check::violations(&as_printed).is_empty(), "{}", case.case);
for (format, shown) in printed_formats(&as_printed) {
for secret in case.registered {
assert!(!shown.contains(secret), "{} in {format:?}", case.case);
}
}
}
}
#[test]
fn the_rules_compile_outside_the_cli() {
let root = env!("CARGO_MANIFEST_DIR");
let read = |path: &str| std::fs::read_to_string(format!("{root}/{path}")).unwrap();
let dir = format!("{root}/src/gateway/withhold_rules");
let mut files: Vec<String> = std::fs::read_dir(&dir)
.unwrap()
.map(|entry| entry.unwrap().file_name().into_string().unwrap())
.collect();
files.sort();
assert_eq!(
files,
[
"check.rs",
"corpus.rs",
"mod.rs",
"names.rs",
"values.rs",
"view.rs"
],
"a new file needs a `mod` line in mod.rs (and the harness reads it through mod.rs)"
);
for file in &files {
let text = read(&format!("src/gateway/withhold_rules/{file}"));
for (at, line) in text.lines().enumerate() {
let code = line.split("//").next().unwrap_or_default();
for path in ["crate::", "airs_cli_rs::", "scm::", "airs_test_harness::"] {
assert!(
!code.contains(path),
"{file}:{}: `{path}` does not resolve in the harness: {line}",
at + 1
);
}
}
}
let harness = read("crates/airs-test-harness/src/withhold.rs");
for include in [
r#"#[path = "../../../src/gateway/withhold_rules/mod.rs"]"#,
r#"#[path = "../../../src/gateway/withhold_rules/corpus.rs"]"#,
r#"#[path = "../../../src/gateway/withhold_rules/check.rs"]"#,
] {
assert!(harness.contains(include), "{include}");
}
let module = read("src/gateway/withhold_rules/mod.rs");
for declaration in [
"#[cfg(test)]\npub mod check;",
"#[cfg(test)]\npub mod corpus;",
] {
assert!(module.contains(declaration), "{declaration}");
}
let gateway = read("src/gateway/mod.rs");
assert!(
!gateway.contains("dead_code"),
"no blanket allow on the rules module"
);
for manifest in ["Cargo.toml", "crates/airs-test-harness/Cargo.toml"] {
assert!(!read(manifest).contains("withhold"), "{manifest}");
}
}