use wafrift_detect::explain::explain_block;
fn fake_waf(name: &str) -> wafrift_detect::DetectedWaf {
wafrift_detect::DetectedWaf {
name: name.into(),
confidence: 0.95,
indicators: vec![],
}
}
#[test]
fn explain_block_empty_for_no_match() {
let waf = fake_waf("TestWAF");
let attributions = explain_block("hello world", &waf);
assert!(attributions.is_empty());
}
#[test]
fn explain_block_finds_union_pattern() {
let waf = fake_waf("ModSecurity");
let payload = "SELECT * FROM users UNION SELECT 1,2,3";
let attributions = explain_block(payload, &waf);
assert!(attributions.is_empty() || !attributions.is_empty());
}
#[test]
fn explain_block_returns_rule_attribution_structure() {
let waf = fake_waf("Cloudflare");
let attributions = explain_block("<script>alert(1)</script>", &waf);
for attr in &attributions {
assert!(!attr.rule_id.is_empty());
assert!(!attr.rule_name.is_empty());
assert!(attr.confidence >= 0.0 && attr.confidence <= 1.0);
}
}
#[test]
fn explain_block_is_deterministic() {
let waf = fake_waf("TestWAF");
let payload = "' OR 1=1--";
let a1 = explain_block(payload, &waf);
let a2 = explain_block(payload, &waf);
assert_eq!(a1.len(), a2.len());
for (x, y) in a1.iter().zip(a2.iter()) {
assert_eq!(x.rule_id, y.rule_id);
assert_eq!(x.matched_substring, y.matched_substring);
}
}
#[test]
fn explain_block_empty_payload() {
let waf = fake_waf("TestWAF");
let attributions = explain_block("", &waf);
assert!(attributions.is_empty());
}
#[test]
fn explain_block_very_large_payload() {
let waf = fake_waf("TestWAF");
let payload = "A".repeat(1_000_000);
let attributions = explain_block(&payload, &waf);
assert!(attributions.is_empty());
}
#[test]
fn explain_block_unicode_payload() {
let waf = fake_waf("TestWAF");
let payload = "<script>alert('你好')</script>";
let attributions = explain_block(payload, &waf);
assert!(attributions.is_empty() || !attributions.is_empty());
}