Spaces:
Running
Running
solidprivacy-nl commited on
Commit ·
2feff9a
1
Parent(s): 470b7dd
Add Scrub Key import tests
Browse files- tests/test_scrub_key_import.py +116 -0
tests/test_scrub_key_import.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
from scrub_key import build_scrub_key, scrub_key_to_json
|
| 4 |
+
from scrub_key_import import (
|
| 5 |
+
IMPORT_PRIVACY_WARNING,
|
| 6 |
+
build_scrub_key_import_result,
|
| 7 |
+
normalise_scrub_key_items,
|
| 8 |
+
validate_scrub_key_import_text,
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
VALID_SYNTHETIC_ROWS = [
|
| 13 |
+
{
|
| 14 |
+
"original_value": "BETROKKENE-TEST-IMPORT-A",
|
| 15 |
+
"placeholder": "[PERSOON_1]",
|
| 16 |
+
"entity_type": "PERSON",
|
| 17 |
+
"type_label": "Naam",
|
| 18 |
+
"source": "detected",
|
| 19 |
+
"review_status": "auto_detected",
|
| 20 |
+
"include": True,
|
| 21 |
+
"timestamp": "2026-06-07T11:00:00Z",
|
| 22 |
+
},
|
| 23 |
+
{
|
| 24 |
+
"original_value": "ZAAK-TEST-IMPORT-2026-001",
|
| 25 |
+
"placeholder": "[ZAAKNUMMER_1]",
|
| 26 |
+
"entity_type": "LEGAL_REFERENCE",
|
| 27 |
+
"type_label": "Zaaknummer",
|
| 28 |
+
"source": "manual",
|
| 29 |
+
"review_status": "manual",
|
| 30 |
+
"include": True,
|
| 31 |
+
"timestamp": "2026-06-07T11:05:00Z",
|
| 32 |
+
},
|
| 33 |
+
]
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
def _valid_scrub_key_json():
|
| 37 |
+
scrub_key = build_scrub_key(VALID_SYNTHETIC_ROWS, document_label="Import testdossier")
|
| 38 |
+
return scrub_key_to_json(scrub_key)
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
def test_import_result_accepts_valid_scrub_key_json_and_normalises_rows():
|
| 42 |
+
result = build_scrub_key_import_result(_valid_scrub_key_json())
|
| 43 |
+
|
| 44 |
+
assert result["ok"] is True
|
| 45 |
+
assert result["errors"] == []
|
| 46 |
+
assert result["item_count"] == 2
|
| 47 |
+
assert result["reversible"] is True
|
| 48 |
+
assert result["privacy_model"] == "pseudonymization_not_full_anonymization"
|
| 49 |
+
assert result["document_label"] == "Import testdossier"
|
| 50 |
+
|
| 51 |
+
first_row = result["mapping_rows"][0]
|
| 52 |
+
assert first_row["find"] == "BETROKKENE-TEST-IMPORT-A"
|
| 53 |
+
assert first_row["replace_with"] == "[PERSOON_1]"
|
| 54 |
+
assert first_row["original_value"] == "BETROKKENE-TEST-IMPORT-A"
|
| 55 |
+
assert first_row["placeholder"] == "[PERSOON_1]"
|
| 56 |
+
assert first_row["include"] is True
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_import_result_contains_local_key_privacy_warning():
|
| 60 |
+
result = build_scrub_key_import_result(_valid_scrub_key_json())
|
| 61 |
+
|
| 62 |
+
assert IMPORT_PRIVACY_WARNING in result["warnings"]
|
| 63 |
+
assert "lokaal herleidbaar" in result["warnings"][0]
|
| 64 |
+
assert "AI-diensten" in result["warnings"][0]
|
| 65 |
+
|
| 66 |
+
|
| 67 |
+
def test_validate_import_text_returns_safe_error_for_empty_text():
|
| 68 |
+
errors = validate_scrub_key_import_text(" ")
|
| 69 |
+
|
| 70 |
+
assert errors == ["Scrub Key JSON ontbreekt of is leeg."]
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
def test_validate_import_text_returns_safe_error_for_invalid_json():
|
| 74 |
+
errors = validate_scrub_key_import_text("{niet-json")
|
| 75 |
+
|
| 76 |
+
assert errors == ["Scrub Key JSON is geen geldige JSON."]
|
| 77 |
+
|
| 78 |
+
|
| 79 |
+
def test_validate_import_text_returns_error_for_invalid_top_level_format():
|
| 80 |
+
errors = validate_scrub_key_import_text("[]")
|
| 81 |
+
|
| 82 |
+
assert errors
|
| 83 |
+
assert errors[0].startswith("Scrub Key JSON heeft een ongeldig hoofdformaat:")
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
def test_import_result_reports_structural_validation_errors_without_mapping_rows():
|
| 87 |
+
scrub_key = json.loads(_valid_scrub_key_json())
|
| 88 |
+
scrub_key["items"][0]["timestamp"] = ""
|
| 89 |
+
|
| 90 |
+
result = build_scrub_key_import_result(json.dumps(scrub_key))
|
| 91 |
+
|
| 92 |
+
assert result["ok"] is False
|
| 93 |
+
assert result["mapping_rows"] == []
|
| 94 |
+
assert result["item_count"] == 0
|
| 95 |
+
assert any("timestamp" in error for error in result["errors"])
|
| 96 |
+
assert IMPORT_PRIVACY_WARNING in result["warnings"]
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def test_normalise_scrub_key_items_does_not_mutate_input_key():
|
| 100 |
+
scrub_key = build_scrub_key(VALID_SYNTHETIC_ROWS, document_label="Import testdossier")
|
| 101 |
+
original_first_item = dict(scrub_key["items"][0])
|
| 102 |
+
|
| 103 |
+
rows = normalise_scrub_key_items(scrub_key)
|
| 104 |
+
|
| 105 |
+
assert rows[0]["find"] == original_first_item["original_value"]
|
| 106 |
+
assert scrub_key["items"][0] == original_first_item
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
def test_import_examples_use_synthetic_dutch_legal_values_only():
|
| 110 |
+
result = build_scrub_key_import_result(_valid_scrub_key_json())
|
| 111 |
+
imported_text = json.dumps(result, ensure_ascii=False)
|
| 112 |
+
|
| 113 |
+
assert "BETROKKENE-TEST-IMPORT-A" in imported_text
|
| 114 |
+
assert "ZAAK-TEST-IMPORT-2026-001" in imported_text
|
| 115 |
+
assert "Jan Jansen" not in imported_text
|
| 116 |
+
assert "Piet de Vries" not in imported_text
|