Files
stack/tests/bib/test_iom_exercise.py
kert dbf71a6594 test: 99.93% coverage — Zotero 9 schema fix + 400+ new tests
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
2026-04-18 10:06:47 -04:00

296 lines
9.5 KiB
Python

"""Exercise bib.iom — covers fetch_chapters regex parsing, download, check_future."""
from __future__ import annotations
from unittest.mock import MagicMock
from bib.iom import (
IOMEntry,
_existing_attachment_hash,
_futurepdf_anchor,
_prune_stale,
_sha256,
check_future_updates,
download_attachments,
fetch_chapters,
fetch_index,
ingest_all,
ingest_entry,
)
_ENTRY = IOMEntry(
pub="100-04",
title="Medicare Claims Processing Manual",
landing_url="https://www.cms.gov/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms018912",
)
class TestFetchChaptersRegex:
def _client(self, html):
client = MagicMock()
resp = MagicMock()
resp.text = html
resp.status_code = 200
client.get.return_value = resp
return client
def test_matches_chapters(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01.pdf">
Chapter 1 - General Billing Requirements
</a>
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c02.pdf">
Chapter 2 - Submission of Claims
</a>
"""
chapters = fetch_chapters(self._client(html), _ENTRY)
assert len(chapters) == 2
assert chapters[0].chapter == "1"
assert "General Billing" in chapters[0].title
def test_skips_supplements(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01.pdf">
Chapter 1 - General
</a>
<a href="/regulations-and-guidance/guidance/manuals/downloads/crosswalk.pdf">
Crosswalk of Changes
</a>
"""
chapters = fetch_chapters(self._client(html), _ENTRY)
assert len(chapters) == 1
def test_whole_pub_fallback(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/pub100_18.pdf">
Pub 100-18 - Medicare Prescription Drug Benefit Manual
</a>
"""
chapters = fetch_chapters(self._client(html), _ENTRY)
assert len(chapters) == 1
assert chapters[0].chapter == ""
def test_dedup_chapters(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01.pdf">
Chapter 1 - General
</a>
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01v2.pdf">
Chapter 1 - General (Updated)
</a>
"""
chapters = fetch_chapters(self._client(html), _ENTRY)
assert len(chapters) == 1
def test_part_chapters(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/ncd103c03p1.pdf">
Chapter 3, Part 1 — Section A
</a>
<a href="/regulations-and-guidance/guidance/manuals/downloads/ncd103c03p2.pdf">
Chapter 3, Part 2 — Section B
</a>
"""
chapters = fetch_chapters(self._client(html), _ENTRY)
assert len(chapters) == 2
assert chapters[0].chapter in ("3P1", "3p1")
class TestFetchIndex:
def test_real_html_pattern(self):
html = """
<a href="/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms018912"
class="title-link">
100-04
</a>
<div><label>Title</label>Medicare Claims Processing Manual</div>
"""
client = MagicMock()
resp = MagicMock()
resp.text = html
resp.status_code = 200
client.get.return_value = resp
entries = fetch_index(client)
assert len(entries) == 1
assert entries[0].pub == "100-04"
class TestPruneStale:
def test_prunes(self):
store = MagicMock()
con = MagicMock()
store._con.return_value = con
con.execute.return_value.fetchall.return_value = [
{"key": "K1", "url": "https://old.pdf"},
{"key": "K2", "url": "https://live.pdf"},
]
n = _prune_stale(store, "100-04", {"https://live.pdf"})
assert n == 1
store.delete.assert_called_once_with("K1")
class TestIngestEntryDeep:
def test_with_chapters(self):
store = MagicMock()
store.upsert.return_value = "KEY1"
store._con.return_value = MagicMock(
execute=MagicMock(
return_value=MagicMock(fetchall=MagicMock(return_value=[]))
)
)
html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01.pdf">
Chapter 1 - General
</a>
"""
client = MagicMock()
resp = MagicMock()
resp.text = html
resp.status_code = 200
client.get.return_value = resp
keys = ingest_entry(store, client, _ENTRY)
assert len(keys) == 1
store.upsert.assert_called_once()
class TestIngestAllFiltered:
def test_with_pub_filter(self):
store = MagicMock()
store.upsert.return_value = "KEY1"
store._con.return_value = MagicMock(
execute=MagicMock(
return_value=MagicMock(fetchall=MagicMock(return_value=[]))
)
)
index_html = """
<a href="/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms018912">
100-04
</a>
<div><label>Title</label>Claims Processing Manual</div>
"""
chapter_html = """
<a href="/regulations-and-guidance/guidance/manuals/downloads/clm104c01.pdf">
Chapter 1 - General
</a>
"""
client = MagicMock()
resp1 = MagicMock(text=index_html, status_code=200)
resp2 = MagicMock(text=chapter_html, status_code=200)
client.get.side_effect = [resp1, resp2]
result = ingest_all(store, client, pubs=["100-04"])
assert isinstance(result, dict)
def test_skips_unmatched_pubs(self):
store = MagicMock()
index_html = """
<a href="/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms018912">
100-04
</a>
<div><label>Title</label>Claims Processing Manual</div>
"""
client = MagicMock()
resp = MagicMock(text=index_html, status_code=200)
client.get.return_value = resp
result = ingest_all(store, client, pubs=["100-99"])
assert result == {}
def test_handles_exception(self):
store = MagicMock()
index_html = """
<a href="/regulations-and-guidance/guidance/manuals/internet-only-manuals-ioms-items/cms018912">
100-04
</a>
<div><label>Title</label>Claims Processing Manual</div>
"""
client = MagicMock()
resp1 = MagicMock(text=index_html, status_code=200)
resp2 = MagicMock()
resp2.raise_for_status.side_effect = Exception("fail")
client.get.side_effect = [resp1, resp2]
result = ingest_all(store, client)
assert result.get("100-04") == 0
class TestExistingAttachmentHash:
def test_no_attachment(self):
store = MagicMock()
con = MagicMock()
store._con.return_value = con
con.execute.return_value.fetchone.return_value = None
assert _existing_attachment_hash(store, "K1") is None
def test_with_file(self, tmp_path):
f = tmp_path / "test.pdf"
f.write_bytes(b"pdf content")
store = MagicMock()
con = MagicMock()
store._con.return_value = con
con.execute.return_value.fetchone.return_value = {"storage_path": str(f)}
result = _existing_attachment_hash(store, "K1")
assert result == _sha256(f)
class TestDownloadAttachments:
def test_downloads_and_attaches(self, tmp_path):
store = MagicMock()
store._db_path = str(tmp_path / "bib.sqlite")
item = MagicMock()
item.url = "https://cms.gov/manuals/downloads/ch1.pdf"
item.key = "K1"
item.title = "Chapter 1"
row = {"extra_json": '{"pub_number": "100-04"}'}
item.to_row.return_value = row
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
result = download_attachments(store, client, tmp_dir=tmp_path / "dl")
assert result.get("100-04", 0) >= 1
class TestFuturepdfAnchor:
def test_creates_new(self):
store = MagicMock()
store.list_items.return_value = []
store.upsert.return_value = "FKEY"
key = _futurepdf_anchor(store)
assert key == "FKEY"
store.upsert.assert_called_once()
def test_returns_existing(self):
store = MagicMock()
item = MagicMock()
item.key = "EXISTING"
store.list_items.return_value = [item]
assert _futurepdf_anchor(store) == "EXISTING"
class TestCheckFutureUpdates:
def test_changed(self, tmp_path):
store = MagicMock()
store._db_path = str(tmp_path / "bib.sqlite")
store.list_items.return_value = []
store.upsert.return_value = "FKEY"
store._con.return_value.execute.return_value.fetchone.return_value = None
client = MagicMock()
resp = MagicMock()
resp.content = b"new pdf content"
resp.status_code = 200
client.get.return_value = resp
changed, digest = check_future_updates(store, client, tmp_dir=tmp_path / "dl")
assert changed is True
assert len(digest) == 64