90 lines
3 KiB
Python
90 lines
3 KiB
Python
"""Unit-тесты consumer-PII scrubber для GlitchTip (#396)."""
|
|
import os
|
|
|
|
os.environ.setdefault("DATABASE_URL", "postgresql+psycopg://test:test@localhost:5432/test")
|
|
|
|
from app.observability.sentry_scrub import scrub_pii_event
|
|
|
|
|
|
def test_redacts_pii_in_request_data() -> None:
|
|
event = {
|
|
"request": {
|
|
"data": {
|
|
"client_name": "Иван Иванов",
|
|
"client_phone": "+79991234567",
|
|
"client_email": "ivan@example.com",
|
|
"address": "Екатеринбург, ул. Ленина 1",
|
|
}
|
|
}
|
|
}
|
|
out = scrub_pii_event(event, {})
|
|
data = out["request"]["data"]
|
|
assert data["client_name"] == "[REDACTED]"
|
|
assert data["client_phone"] == "[REDACTED]"
|
|
assert data["client_email"] == "[REDACTED]"
|
|
# non-PII поле не трогаем
|
|
assert data["address"] == "Екатеринбург, ул. Ленина 1"
|
|
|
|
|
|
def test_redacts_pii_in_extra() -> None:
|
|
event = {
|
|
"extra": {
|
|
"phone": "+79990000000",
|
|
"email": "x@y.ru",
|
|
"name": "Пётр",
|
|
"estimate_id": 42,
|
|
}
|
|
}
|
|
out = scrub_pii_event(event, {})
|
|
extra = out["extra"]
|
|
assert extra["phone"] == "[REDACTED]"
|
|
assert extra["email"] == "[REDACTED]"
|
|
assert extra["name"] == "[REDACTED]"
|
|
assert extra["estimate_id"] == 42
|
|
|
|
|
|
def test_redact_is_case_insensitive() -> None:
|
|
event = {"extra": {"Client_Name": "Анна", "CLIENT_PHONE": "+7900"}}
|
|
out = scrub_pii_event(event, {})
|
|
assert out["extra"]["Client_Name"] == "[REDACTED]"
|
|
assert out["extra"]["CLIENT_PHONE"] == "[REDACTED]"
|
|
|
|
|
|
def test_redacts_nested_pii_in_contexts() -> None:
|
|
event = {"contexts": {"trace": {"op": "http"}, "consumer": {"client_email": "z@z.ru"}}}
|
|
out = scrub_pii_event(event, {})
|
|
assert out["contexts"]["consumer"]["client_email"] == "[REDACTED]"
|
|
# вложенный non-PII контекст не трогаем
|
|
assert out["contexts"]["trace"]["op"] == "http"
|
|
|
|
|
|
def test_leaves_non_pii_untouched() -> None:
|
|
event = {
|
|
"request": {"data": {"region": "66", "area_sqm": 50}},
|
|
"extra": {"job": "geocode"},
|
|
"level": "error",
|
|
}
|
|
out = scrub_pii_event(event, {})
|
|
assert out["request"]["data"] == {"region": "66", "area_sqm": 50}
|
|
assert out["extra"] == {"job": "geocode"}
|
|
assert out["level"] == "error"
|
|
|
|
|
|
def test_handles_missing_sections() -> None:
|
|
out = scrub_pii_event({}, {})
|
|
assert out == {}
|
|
|
|
|
|
def test_handles_none_and_non_dict_sections() -> None:
|
|
event = {"request": None, "extra": None, "contexts": "not-a-dict"}
|
|
# не должно бросать исключений
|
|
out = scrub_pii_event(event, {})
|
|
assert out is event
|
|
|
|
|
|
def test_returns_event_not_none() -> None:
|
|
"""before_send должен вернуть event (не None) — иначе SDK дропнет отчёт."""
|
|
event = {"request": {"data": {"client_name": "X"}}}
|
|
out = scrub_pii_event(event, {})
|
|
assert out is not None
|
|
assert out is event
|