"""pytest fixtures:用 reportlab 生成 3 个样例 PDF(中文字体 STSong-Light)。""" import io import pytest from reportlab.lib.pagesizes import A4 from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.cidfonts import UnicodeCIDFont from reportlab.pdfgen import canvas pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light")) def _idcard_fix(prefix17: str) -> str: w = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2] c = "10X98765432" total = sum(int(prefix17[i]) * w[i] for i in range(17)) return prefix17 + c[total % 11] def _luhn_fix(prefix: str) -> str: for last in "0123456789": s = prefix + last total, alt = 0, False for ch in reversed(s): d = int(ch) if alt: d *= 2 if d > 9: d -= 9 total += d alt = not alt if total % 10 == 0: return s raise RuntimeError("no luhn digit") VALID_ID = _idcard_fix("11010119900307759") # 程序化补校验位,保证合法 BANK_CARD = _luhn_fix("622202020011223344") # 19 位,Luhn 合法 PHONE = "13812345678" EMAIL = "zhang.san@example.com" def _make_pdf(pages): """pages: List[str],每页一段文本;空字符串 = 空白页(模拟扫描页)。""" buf = io.BytesIO() c = canvas.Canvas(buf, pagesize=A4) for text in pages: if text: y = 750 for line in text.split("\n"): c.setFont("STSong-Light", 12) c.drawString(72, y, line) y -= 24 c.showPage() c.save() return buf.getvalue() @pytest.fixture(scope="module") def pdf_plain(): """样例1:纯文本页(无 PII)。""" return _make_pdf(["本判决书仅供学习参考。\n案号:(2026)京01民初1号。\n审判员:李四。"]) @pytest.fixture(scope="module") def pdf_pii(): """样例2:含身份证 + 手机号 + 银行卡 + 邮箱。""" return _make_pdf([ f"原告:张三,身份证号 {VALID_ID},联系电话 {PHONE}。\n" f"收款账户:{BANK_CARD},邮箱 {EMAIL}。\n" "以上信息用于测试脱敏。" ]) @pytest.fixture(scope="module") def pdf_scanned(): """样例3:空白扫描页(无文字层)。""" return _make_pdf([""])