#[cfg(test)]
mod tests {
use crate::{Rule, Span};
use wasm_bindgen_test::*;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test_configure!(run_in_browser);
#[test]
fn test_rule_get_type() {
assert_eq!(Rule::Email.get_type(), "pii.email");
assert_eq!(Rule::Ssn.get_type(), "pii.ssn");
assert_eq!(Rule::CreditCard.get_type(), "pii.credit_card");
assert_eq!(Rule::Phone.get_type(), "pii.phone");
assert_eq!(Rule::SomaliNid.get_type(), "pii.id.somali_nid");
let custom_rule = Rule::Custom {
type_: "pii.custom.test".to_string(),
regex: "abc".to_string(),
};
assert_eq!(custom_rule.get_type(), "pii.custom.test");
}
#[test]
fn test_rule_get_regex() {
let _email_regex = Rule::Email.get_regex();
let _ssn_regex = Rule::Ssn.get_regex();
let _cc_regex = Rule::CreditCard.get_regex();
let _phone_regex = Rule::Phone.get_regex();
let _nid_regex = Rule::SomaliNid.get_regex();
let custom_rule = Rule::Custom {
type_: "pii.custom.test".to_string(),
regex: "abc".to_string(),
};
let _custom_regex = custom_rule.get_regex();
}
#[test]
fn test_find_pii_internal_email() {
let text = "Contact me at test@example.com for more information.";
let rules = vec![Rule::Email];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.email");
assert!(text[spans[0].start..spans[0].end].contains("@example.com"));
}
#[test]
fn test_find_pii_internal_ssn() {
let text = "My SSN is 123-45-6789 and should be kept private.";
let rules = vec![Rule::Ssn];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.ssn");
assert_eq!(&text[spans[0].start..spans[0].end], "123-45-6789");
}
#[test]
fn test_find_pii_internal_multiple() {
let text = "Contact: test@example.com, SSN: 123-45-6789";
let rules = vec![Rule::Email, Rule::Ssn];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 2);
assert_eq!(spans[0].type_, "pii.email");
assert_eq!(spans[1].type_, "pii.ssn");
}
#[wasm_bindgen_test]
fn test_email_detection() {
let text = "Contact me at test@example.com for more information.";
let rules = vec![Rule::Email];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.email");
assert!(text[spans[0].start..spans[0].end].contains("@example.com"));
}
#[wasm_bindgen_test]
fn test_ssn_detection() {
let text = "My SSN is 123-45-6789 and should be kept private.";
let rules = vec![Rule::Ssn];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.ssn");
assert_eq!(&text[spans[0].start..spans[0].end], "123-45-6789");
}
#[wasm_bindgen_test]
fn test_credit_card_detection() {
let text = "Payment with 4111 1111 1111 1111 was successful.";
let rules = vec![Rule::CreditCard];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.credit_card");
assert_eq!(&text[spans[0].start..spans[0].end], "4111 1111 1111 1111");
}
#[wasm_bindgen_test]
fn test_phone_detection() {
let text = "Call me at +1 (555) 123-4567 anytime.";
let rules = vec![Rule::Phone];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.phone");
assert_eq!(&text[spans[0].start..spans[0].end], "+1 (555) 123-4567");
}
#[wasm_bindgen_test]
fn test_somali_nid_detection() {
let text = "My Somali National ID is AB1234567.";
let rules = vec![Rule::SomaliNid];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.id.somali_nid");
assert_eq!(&text[spans[0].start..spans[0].end], "AB1234567");
}
#[wasm_bindgen_test]
fn test_custom_rule() {
let text = "Employee ID: EMP-123456";
let custom_rule = Rule::Custom {
type_: "pii.custom.employee_id".to_string(),
regex: r"EMP-\d{6}".to_string(),
};
let rules = vec![custom_rule];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 1);
assert_eq!(spans[0].type_, "pii.custom.employee_id");
assert_eq!(&text[spans[0].start..spans[0].end], "EMP-123456");
}
#[wasm_bindgen_test]
fn test_multiple_rules() {
let text = "Contact: test@example.com, SSN: 123-45-6789";
let rules = vec![Rule::Email, Rule::Ssn];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 2);
assert_eq!(spans[0].type_, "pii.email");
assert_eq!(spans[1].type_, "pii.ssn");
}
#[wasm_bindgen_test]
fn test_no_matches() {
let text = "This text does not contain any PII.";
let rules = vec![Rule::Email, Rule::Ssn, Rule::CreditCard, Rule::Phone, Rule::SomaliNid];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 0);
}
#[wasm_bindgen_test]
fn test_empty_text() {
let text = "";
let rules = vec![Rule::Email, Rule::Ssn];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 0);
}
#[wasm_bindgen_test]
fn test_invalid_custom_regex() {
let text = "Some text";
let custom_rule = Rule::Custom {
type_: "pii.invalid".to_string(),
regex: r"[invalid regex".to_string(), };
let rules = vec![custom_rule];
let spans = find_pii_internal(text, rules);
assert_eq!(spans.len(), 0);
}
fn find_pii_internal(text: &str, rules: Vec<Rule>) -> Vec<Span> {
let mut spans = Vec::new();
for rule in rules {
let rule_type = rule.get_type();
let regex = rule.get_regex();
for mat in regex.find_iter(text) {
spans.push(Span {
start: mat.start(),
end: mat.end(),
type_: rule_type.clone(),
});
}
}
spans.sort_by_key(|span| span.start);
spans
}
}