Files
info-privacy/tests/test_pipeline.py
T
qiurui cbfe4a23dc feat: info-privacy PII detection service with frame analysis support
- Pipeline: analyze(), redact(), analyze_image() methods
- API: /analyze, /redact, /analyze/frame, /analyze/frame/base64 endpoints
- Detectors: regex, NER, face (RKNN NPU)
- Privacy frame route added for KVM-Privacy Hub integration
2026-02-28 17:33:11 +08:00

90 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# tests/test_pipeline.py
import pytest
import docx
from info_privacy.pipeline import PrivacyPipeline
@pytest.fixture
def pipeline():
return PrivacyPipeline()
@pytest.fixture
def sample_docx_path(tmp_path):
doc = docx.Document()
doc.add_paragraph("姓名:张伟 身份证:110101199001011234 电话:13812345678")
p = tmp_path / "test.docx"
doc.save(str(p))
return str(p)
def test_analyze_docx(pipeline, sample_docx_path):
report = pipeline.analyze(sample_docx_path)
assert report.blocked is False
assert len(report.entities) > 0
types = {e.type.value for e in report.entities}
assert "id_card" in types or "phone" in types
def test_analyze_classified_doc(pipeline, tmp_path):
doc = docx.Document()
doc.add_paragraph("【机密】本文件仅供内部使用")
p = tmp_path / "secret.docx"
doc.save(str(p))
report = pipeline.analyze(str(p))
assert report.blocked is True
assert report.classification.value == "classified"
def test_redact_docx_removes_entity(pipeline, sample_docx_path, tmp_path):
out = str(tmp_path / "out.docx")
pipeline.redact(sample_docx_path, redact_types=["id_card"], out_path=out)
doc = docx.Document(out)
all_text = " ".join(p.text for p in doc.paragraphs)
assert "110101199001011234" not in all_text
assert "张伟" in all_text # 未指定遮罩 name,保留
def test_analyze_returns_summary_dict(pipeline, sample_docx_path):
"""DetectionReport.summary 各类型计数应与 entities 列表精确对应。"""
report = pipeline.analyze(sample_docx_path)
for etype, count in report.summary.items():
actual = sum(1 for e in report.entities if e.type.value == etype)
assert actual == count, f"{etype}: summary={count}entities={actual}"
def test_analyze_no_pii_empty_entities(pipeline, tmp_path):
"""无 PII 的文档:entities 为空,分类为 normal,无 warning。"""
doc = docx.Document()
doc.add_paragraph("季度汇报:各项指标均达标。")
p = tmp_path / "clean.docx"
doc.save(str(p))
report = pipeline.analyze(str(p))
assert len(report.entities) == 0
assert report.classification.value == "normal"
assert report.warning is None
def test_analyze_many_entities_triggers_warning(pipeline, tmp_path):
"""5 个以上高风险实体应在 DetectionReport 中生成 warning。"""
doc = docx.Document()
ids = [
"110101199001011234", "110101199001011235", "110101199001011236",
"110101199001011237", "110101199001011238",
]
doc.add_paragraph(" ".join(ids))
p = tmp_path / "many.docx"
doc.save(str(p))
report = pipeline.analyze(str(p))
assert report.warning is not None
def test_redact_multi_type_all_removed(pipeline, tmp_path):
"""同时遮罩 id_card/phone/email 三种类型,各类值均应从文档消失。"""
doc = docx.Document()
doc.add_paragraph("身份证:110101199001011234 电话:13812345678 邮箱:user@corp.com")
p = tmp_path / "multi.docx"
doc.save(str(p))
out = str(tmp_path / "out.docx")
pipeline.redact(str(p), redact_types=["id_card", "phone", "email"], out_path=out)
result = docx.Document(out)
text = " ".join(para.text for para in result.paragraphs)
assert "110101199001011234" not in text
assert "13812345678" not in text
assert "user@corp.com" not in text