use proptest::prelude::*;
use secure_privacy::{PiiClassification, PiiClassifier, Pseudonymizer};
proptest! {
#![proptest_config(ProptestConfig::with_cases(1000))]
#[test]
fn prop_pseudonymize_deterministic(input in ".*", salt in proptest::collection::vec(1u8..=255, 1..32)) {
let p = Pseudonymizer::new(&salt).unwrap();
let result1 = p.pseudonymize(&input);
let result2 = p.pseudonymize(&input);
prop_assert_eq!(
result1, result2,
"Same input and salt must produce identical pseudonyms",
);
}
#[test]
fn prop_pseudonymize_not_reversible(
input in "[a-zA-Z0-9]{1,50}",
salt in proptest::collection::vec(1u8..=255, 1..32),
) {
let p = Pseudonymizer::new(&salt).unwrap();
let result = p.pseudonymize(&input);
let value = result.value.clone();
prop_assert_ne!(
value, input,
"Pseudonym must not equal the original input",
);
let value2 = result.value;
prop_assert_eq!(
value2.len(), 64,
"HMAC-SHA256 output should always be 64 hex characters",
);
}
#[test]
fn prop_different_salts_different_output(input in "[a-zA-Z0-9]{1,50}") {
let p1 = Pseudonymizer::new(b"salt_one").unwrap();
let p2 = Pseudonymizer::new(b"salt_two").unwrap();
let r1 = p1.pseudonymize(&input);
let r2 = p2.pseudonymize(&input);
prop_assert_ne!(
r1, r2,
"Different salts must produce different pseudonyms",
);
}
#[test]
fn prop_classify_no_panic(input in ".*") {
let classifier = PiiClassifier::new();
let _ = classifier.classify(&input);
}
#[test]
fn prop_classify_emails(
local in "[a-z]{1,10}",
domain in "[a-z]{1,10}\\.[a-z]{2,4}",
) {
let email = format!("{local}@{domain}");
let classifier = PiiClassifier::new();
let result = classifier.classify(&email);
prop_assert_eq!(
result,
PiiClassification::Email,
"Email pattern should be classified as Email",
);
}
}