Fix Zotero table models for Zotero 9:
- Remove stale Annotations/Highlights/Transaction* models
- Add ItemAnnotations, RetractedItems, DeletedCollections,
DeletedSearches, DbDebug1
- Fix ItemAttachments, Libraries, Users column mismatches
New test files covering all major modules:
- cli/{bib,prisma,rec,zot,mail,run} deep exercising tests
- mail/{droplet,postmark,resend,cloudflare} lifecycle tests
- bib/{iom,oig,pincite,sync,regulations_gov,email_ingest,format,store}
- prisma/{vpn,fetch,export,llm,screen,eligibility,extract,project,ingest,flow}
- aco/lake/{unity,quality,deploy} + api/aco coverage gaps
- zot/{ops,db,extract,duck} + rec/{report,engine,base,pricers}
- pfs/{pipe,rules,eq,files}
Add pytest-xdist for parallel test execution.
Tracks #353
178 lines
5.1 KiB
Python
178 lines
5.1 KiB
Python
"""Exercise bib.oig — extract_docs regex, classify, download_attachments."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from bib.oig import (
|
|
OIGDoc,
|
|
_build_item,
|
|
_classify_sector,
|
|
_classify_type,
|
|
_existing_attachment_hash,
|
|
_extract_docs,
|
|
_sha256,
|
|
download_attachments,
|
|
fetch_alerts,
|
|
fetch_cpgs,
|
|
ingest_all,
|
|
)
|
|
|
|
|
|
class TestClassifyTypeDeep:
|
|
def test_sfa_by_href(self):
|
|
assert _classify_type("Some Alert", "/special-fraud-alerts/page") == "sfa"
|
|
|
|
def test_sab_by_href(self):
|
|
assert _classify_type("Some Bulletin", "/special-advisory-bulletins/x") == "sab"
|
|
|
|
def test_cpg_by_href(self):
|
|
assert _classify_type("Some Guidance", "/compliance-guidance/x") == "cpg"
|
|
|
|
def test_other(self):
|
|
assert _classify_type("Random", "/random") == "other"
|
|
|
|
|
|
class TestClassifySectorDeep:
|
|
def test_nursing_home(self):
|
|
assert _classify_sector("Nursing Home Compliance") != ""
|
|
|
|
def test_physician(self):
|
|
assert _classify_sector("Individual and Small Group Physician Practices") != ""
|
|
|
|
def test_no_match(self):
|
|
assert _classify_sector("Unrelated Document") == ""
|
|
|
|
|
|
class TestExtractDocsDeep:
|
|
def test_real_pattern(self):
|
|
html = """
|
|
<a href="/documents/compliance-guidance/cpg-hospitals.pdf">
|
|
Compliance Program Guidance for Hospitals
|
|
</a>
|
|
<a href="/documents/special-fraud-alerts/sfa-2024.pdf">
|
|
Special Fraud Alert: Kickbacks
|
|
</a>
|
|
"""
|
|
docs = _extract_docs(html)
|
|
assert len(docs) == 2
|
|
assert docs[0][1] == "Compliance Program Guidance for Hospitals"
|
|
|
|
def test_dedup(self):
|
|
html = """
|
|
<a href="/documents/doc1.pdf">Doc One</a>
|
|
<a href="/documents/doc1.pdf">Doc One Again</a>
|
|
"""
|
|
docs = _extract_docs(html)
|
|
assert len(docs) == 1
|
|
|
|
def test_skip_hints(self):
|
|
html = """
|
|
<a href="/documents/doc1.pdf">Download</a>
|
|
<a href="/documents/doc2.pdf">Real Title</a>
|
|
"""
|
|
docs = _extract_docs(html)
|
|
assert len(docs) == 1
|
|
assert docs[0][1] == "Real Title"
|
|
|
|
|
|
class TestFetchCpgsDeep:
|
|
def test_parses_docs(self):
|
|
client = MagicMock()
|
|
resp = MagicMock()
|
|
resp.text = """
|
|
<a href="/documents/compliance-guidance/cpg-hospitals.pdf">
|
|
CPG for Hospitals
|
|
</a>
|
|
"""
|
|
resp.status_code = 200
|
|
client.get.return_value = resp
|
|
docs = fetch_cpgs(client)
|
|
assert len(docs) == 1
|
|
assert docs[0].guidance_type == "cpg"
|
|
assert docs[0].sector == "hospitals"
|
|
|
|
|
|
class TestFetchAlertsDeep:
|
|
def test_parses_docs(self):
|
|
client = MagicMock()
|
|
resp = MagicMock()
|
|
resp.text = """
|
|
<a href="/documents/special-fraud-alerts/sfa-2024.pdf">
|
|
Special Fraud Alert: Laboratory Kickbacks
|
|
</a>
|
|
"""
|
|
resp.status_code = 200
|
|
client.get.return_value = resp
|
|
docs = fetch_alerts(client)
|
|
assert len(docs) == 1
|
|
assert docs[0].guidance_type == "sfa"
|
|
|
|
|
|
class TestBuildItemDeep:
|
|
def test_all_types(self):
|
|
for gtype in ("cpg", "sfa", "sab", "ea", "open_letter", "other"):
|
|
doc = OIGDoc(
|
|
title=f"Test {gtype}",
|
|
url=f"https://oig.hhs.gov/{gtype}",
|
|
guidance_type=gtype,
|
|
sector="hospitals" if gtype == "cpg" else "",
|
|
)
|
|
item = _build_item(doc)
|
|
assert "agency:oig" in item.tags
|
|
assert f"guidance:{gtype}" in item.tags
|
|
|
|
|
|
class TestIngestAllFiltered:
|
|
def test_cpg_only(self):
|
|
store = MagicMock()
|
|
store.upsert.return_value = "K1"
|
|
client = MagicMock()
|
|
resp = MagicMock()
|
|
resp.text = """
|
|
<a href="/documents/compliance-guidance/cpg1.pdf">CPG Doc</a>
|
|
"""
|
|
resp.status_code = 200
|
|
client.get.return_value = resp
|
|
|
|
result = ingest_all(store, client, kinds=["cpg"])
|
|
assert result["cpg"] >= 1
|
|
assert result["alerts"] == 0
|
|
|
|
|
|
class TestSha256:
|
|
def test_deterministic(self, tmp_path):
|
|
f = tmp_path / "test.bin"
|
|
f.write_bytes(b"hello")
|
|
h = _sha256(f)
|
|
assert len(h) == 64
|
|
assert _sha256(f) == h
|
|
|
|
|
|
class TestExistingAttachmentHash:
|
|
def test_none(self):
|
|
store = MagicMock()
|
|
store._con.return_value.execute.return_value.fetchone.return_value = None
|
|
assert _existing_attachment_hash(store, "K1") is None
|
|
|
|
|
|
class TestDownloadAttachments:
|
|
def test_downloads(self):
|
|
store = MagicMock()
|
|
store._db_path = "/tmp/test.sqlite"
|
|
item = MagicMock()
|
|
item.url = "https://oig.hhs.gov/doc.pdf"
|
|
item.key = "K1"
|
|
item.title = "Test Doc"
|
|
store.list_items.return_value = [item]
|
|
store._con.return_value.execute.return_value.fetchone.return_value = None
|
|
|
|
client = MagicMock()
|
|
resp = MagicMock()
|
|
resp.content = b"pdf bytes"
|
|
resp.status_code = 200
|
|
client.get.return_value = resp
|
|
|
|
n = download_attachments(store, client)
|
|
assert n >= 1
|