Spaces:
Sleeping
Sleeping
solidprivacy-nl commited on
Commit ·
bb9e758
1
Parent(s): b8b956b
Add placeholder validation tests
Browse files
tests/test_placeholder_validation.py
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from inspect import signature
|
| 2 |
+
|
| 3 |
+
from placeholder_validation import (
|
| 4 |
+
classify_placeholder,
|
| 5 |
+
compute_integrity_token,
|
| 6 |
+
is_legacy_placeholder,
|
| 7 |
+
validate_robust_placeholder,
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def _robust(entity="PERSON", counter="0001"):
|
| 12 |
+
integrity = compute_integrity_token(entity, counter)
|
| 13 |
+
return f"[[SP_{entity}_{counter}_{integrity}]]"
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def test_valid_robust_placeholder_is_parsed():
|
| 17 |
+
placeholder = _robust("PERSON", "0001")
|
| 18 |
+
result = validate_robust_placeholder(placeholder)
|
| 19 |
+
assert result.is_valid is True
|
| 20 |
+
assert result.kind == "robust"
|
| 21 |
+
assert result.entity_type == "PERSON"
|
| 22 |
+
assert result.counter == "0001"
|
| 23 |
+
assert result.integrity == compute_integrity_token("PERSON", "0001")
|
| 24 |
+
assert result.issues == ()
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
def test_invalid_prefix_is_rejected():
|
| 28 |
+
result = classify_placeholder("[[XX_PERSON_0001_ABCD]]")
|
| 29 |
+
assert result.is_valid is False
|
| 30 |
+
assert result.kind == "malformed_robust"
|
| 31 |
+
assert "invalid_prefix" in result.issues
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_invalid_entity_is_rejected():
|
| 35 |
+
result = validate_robust_placeholder("[[SP_person_0001_ABCD]]")
|
| 36 |
+
assert result.is_valid is False
|
| 37 |
+
assert result.kind == "malformed_robust"
|
| 38 |
+
assert "invalid_entity" in result.issues
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def test_invalid_counter_is_rejected():
|
| 42 |
+
result = validate_robust_placeholder("[[SP_PERSON_001_ABCD]]")
|
| 43 |
+
assert result.is_valid is False
|
| 44 |
+
assert "invalid_counter" in result.issues
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
def test_zero_counter_is_rejected():
|
| 48 |
+
result = validate_robust_placeholder("[[SP_PERSON_0000_ABCD]]")
|
| 49 |
+
assert result.is_valid is False
|
| 50 |
+
assert "invalid_counter" in result.issues
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
def test_invalid_integrity_token_shape_is_rejected():
|
| 54 |
+
result = validate_robust_placeholder("[[SP_PERSON_0001_ZZZZ]]")
|
| 55 |
+
assert result.is_valid is False
|
| 56 |
+
assert "invalid_integrity" in result.issues
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_integrity_mismatch_is_rejected():
|
| 60 |
+
expected = compute_integrity_token("PERSON", "0001")
|
| 61 |
+
wrong = "FFFF" if expected != "FFFF" else "0000"
|
| 62 |
+
result = validate_robust_placeholder(f"[[SP_PERSON_0001_{wrong}]]")
|
| 63 |
+
assert result.is_valid is False
|
| 64 |
+
assert result.expected_integrity == expected
|
| 65 |
+
assert "integrity_mismatch" in result.issues
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def test_legacy_placeholder_is_detected_separately():
|
| 69 |
+
result = classify_placeholder("[PERSOON_1]")
|
| 70 |
+
assert is_legacy_placeholder("[PERSOON_1]") is True
|
| 71 |
+
assert result.kind == "legacy"
|
| 72 |
+
assert result.is_valid is True
|
| 73 |
+
assert result.entity_type is None
|
| 74 |
+
assert result.integrity is None
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
def test_placeholder_like_malformed_string_is_classified():
|
| 78 |
+
result = classify_placeholder("{{SP:PERSON:0001:A7F3}}")
|
| 79 |
+
assert result.kind == "unknown_placeholder_like"
|
| 80 |
+
assert result.is_valid is False
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def test_truncated_robust_placeholder_is_rejected():
|
| 84 |
+
result = classify_placeholder("[[SP_PERSON_0001_ABCD]")
|
| 85 |
+
assert result.kind == "malformed_robust"
|
| 86 |
+
assert result.is_valid is False
|
| 87 |
+
assert "missing_closing_double_bracket" in result.issues
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def test_ai_mutated_robust_placeholder_is_rejected():
|
| 91 |
+
result = classify_placeholder("[[SP PERSON 0001 ABCD]]")
|
| 92 |
+
assert result.kind == "malformed_robust"
|
| 93 |
+
assert result.is_valid is False
|
| 94 |
+
assert "invalid_prefix" in result.issues
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
def test_integrity_does_not_use_original_sensitive_values():
|
| 98 |
+
parameters = signature(compute_integrity_token).parameters
|
| 99 |
+
assert "original_value" not in parameters
|
| 100 |
+
assert "sensitive_value" not in parameters
|
| 101 |
+
token_a = compute_integrity_token("PERSON", "0001")
|
| 102 |
+
token_b = compute_integrity_token("PERSON", "0001")
|
| 103 |
+
assert token_a == token_b
|
| 104 |
+
assert "SYNTHETIC" not in token_a
|
| 105 |
+
assert "PERSON" not in token_a
|