use super::*;
use parlov_core::Signal;
fn signal(kind: SignalKind, evidence: &str) -> Signal {
Signal { kind, evidence: evidence.into(), rfc_basis: None }
}
#[test]
fn etag_presence_weight() {
let s = signal(SignalKind::HeaderPresence, "etag present in baseline");
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 10.0).abs() < 0.01);
assert_eq!(c.impact, 5);
assert_eq!(c.family, SignalFamily::CacheValidator);
}
#[test]
fn content_range_size_leak_weight() {
let s = signal(
SignalKind::MetadataLeak,
"Content-Range leaks total resource size: 1024 bytes",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 5.0).abs() < 0.01);
assert_eq!(c.impact, 15);
assert_eq!(c.family, SignalFamily::Range);
}
#[test]
fn normative_should_reduces_confidence() {
let s = signal(SignalKind::HeaderPresence, "etag present in baseline");
let c = weight_signal(&s, NormativeStrength::Should, 1.0);
assert!((c.confidence - 9.0).abs() < 0.01);
}
#[test]
fn normative_may_reduces_confidence() {
let s = signal(SignalKind::HeaderPresence, "etag present in baseline");
let c = weight_signal(&s, NormativeStrength::May, 1.0);
assert!((c.confidence - 7.5).abs() < 0.01);
}
#[test]
fn reproducibility_reduces_confidence() {
let s = signal(SignalKind::HeaderPresence, "etag present in baseline");
let c = weight_signal(&s, NormativeStrength::Must, 0.7);
assert!((c.confidence - 7.0).abs() < 0.01);
assert_eq!(c.impact, 5);
}
#[test]
fn www_authenticate_weight() {
let s = signal(
SignalKind::HeaderPresence,
"www-authenticate present in baseline, absent in probe",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 8.0).abs() < 0.01);
assert_eq!(c.impact, 8);
assert_eq!(c.family, SignalFamily::Auth);
}
#[test]
fn location_presence_weight() {
let s = signal(
SignalKind::HeaderPresence,
"location present in baseline, absent in probe",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 8.0).abs() < 0.01);
assert_eq!(c.impact, 5);
assert_eq!(c.family, SignalFamily::Redirect);
}
#[test]
fn location_in_evidence_maps_to_redirect_family() {
let s = signal(
SignalKind::HeaderValue,
"location: \"https://a.com\" (baseline) vs \"https://b.com\" (probe)",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert_eq!(c.family, SignalFamily::Redirect);
}
#[test]
fn body_diff_content_weight() {
let s = signal(
SignalKind::BodyDiff,
"body length: 27 (baseline) vs 45 (probe)",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 70.0).abs() < 0.01);
assert_eq!(c.impact, 15);
assert_eq!(c.family, SignalFamily::ErrorBody);
}
#[test]
fn body_diff_content_type_weight() {
let s = signal(
SignalKind::BodyDiff,
"content-type: application/json (baseline) vs text/html (probe)",
);
let c = weight_signal(&s, NormativeStrength::Must, 1.0);
assert!((c.confidence - 25.0).abs() < 0.01);
assert_eq!(c.impact, 10);
assert_eq!(c.family, SignalFamily::ErrorBody);
}
#[test]
fn body_diff_normative_may_reduces_confidence() {
let s = signal(
SignalKind::BodyDiff,
"body content differs (same length: 100 bytes)",
);
let c = weight_signal(&s, NormativeStrength::May, 1.0);
assert!((c.confidence - 52.5).abs() < 0.01);
}