Files
stack/tests/bib/test_item.py
kert 5261032a9b
All checks were successful
ci/woodpecker/push/infra-ci Pipeline was successful
ci/woodpecker/push/deploy Pipeline was successful
ci/woodpecker/push/ci Pipeline was successful
add tests for 100% line coverage across all packages
Cover remaining uncovered lines in bcda (client, store, log, pipe/cclf,
flatten), bib (sync, spider, translate, ingest, item, store, format, ui),
cms (express wrappers, log edge cases), api (base, gitea, rustfs,
woodpecker, zotero), bls (table import), and pfs (pragma on race guard).

37,687 statements, 0 missed — 11,061 tests passing.
2026-02-28 22:03:23 -05:00

665 lines
22 KiB
Python

"""Tests for bib.item — bibliography item models."""
from __future__ import annotations
import json
import warnings
from bib.item import Download, Item, Manual, Regulation, Rule, Source
# ── Item base ────────────────────────────────────────────────────────────────
class TestItem:
def test_create_defaults(self) -> None:
item = Item()
assert item.key == ""
assert item.item_type == ""
assert item.title == ""
assert item.tags == []
assert item.collections == []
def test_create_with_values(self) -> None:
item = Item(
key="ABC12345",
title="Test Item",
url="https://example.com",
tags=["module:pfs"],
)
assert item.key == "ABC12345"
assert item.title == "Test Item"
assert item.tags == ["module:pfs"]
def test_add_tag(self) -> None:
item = Item()
item.add_tag("module:aco")
assert "module:aco" in item.tags
def test_add_tag_no_duplicate(self) -> None:
item = Item(tags=["module:aco"])
item.add_tag("module:aco")
assert item.tags.count("module:aco") == 1
def test_stamp_access(self) -> None:
item = Item()
item.stamp_access()
assert item.access_date
assert "T" in item.access_date
def test_to_row(self) -> None:
item = Item(key="K1", item_type="source", title="Test")
row = item.to_row()
assert row["key"] == "K1"
assert row["item_type"] == "source"
assert row["title"] == "Test"
assert "extra_json" in row
def test_from_row_dispatches_to_rule(self) -> None:
row = {
"key": "K1",
"item_type": "rule",
"title": "PFS Final Rule",
"extra_json": json.dumps(
{
"fr_volume": "90",
"fr_page": "98452",
"document_number": "2025-19787",
"cms_id": "CMS-1832-F",
"rule_type": "final",
"effective_date": "2026-01-01",
}
),
}
item = Item.from_row(row)
assert isinstance(item, Rule)
assert item.fr_volume == "90"
def test_from_row_dispatches_to_manual(self) -> None:
row = {
"key": "K2",
"item_type": "manual",
"title": "Claims Processing",
"extra_json": json.dumps(
{
"manual_name": "Claims Processing Manual",
"pub_number": "100-04",
"chapter": "12",
"transmittal": "",
}
),
}
item = Item.from_row(row)
assert isinstance(item, Manual)
assert item.pub_number == "100-04"
def test_from_row_dispatches_to_regulation(self) -> None:
row = {
"key": "K3",
"item_type": "regulation",
"title": "RVU Methodology",
"extra_json": json.dumps(
{
"cfr_title": "42",
"cfr_part": "414",
"cfr_section": "414.22",
"authority": "42 USC 1395w-4",
"effective_date": "2025-01-01",
}
),
}
item = Item.from_row(row)
assert isinstance(item, Regulation)
assert item.cfr_section == "414.22"
def test_from_row_dispatches_to_download(self) -> None:
row = {
"key": "K4",
"item_type": "download",
"title": "RVU26A",
"extra_json": json.dumps(
{
"page_type": "rvu",
"file_urls": ["https://example.com/rvu.zip"],
"year": 2026,
"quarter": "A",
"website_title": "CMS",
}
),
}
item = Item.from_row(row)
assert isinstance(item, Download)
assert item.year == 2026
def test_from_row_dispatches_to_source(self) -> None:
row = {
"key": "K5",
"item_type": "source",
"title": "Generic Doc",
"extra_json": json.dumps({"doc_type": "guidance"}),
}
item = Item.from_row(row)
assert isinstance(item, Source)
assert item.doc_type == "guidance"
def test_from_row_unknown_type_returns_item(self) -> None:
row = {"key": "K6", "item_type": "unknown", "title": "Unknown"}
item = Item.from_row(row)
assert isinstance(item, Item)
assert not isinstance(item, Rule)
def test_from_row_with_tags_list(self) -> None:
row = {
"key": "K1",
"item_type": "source",
"title": "Test",
"tags": ["module:pfs", "year:2026"],
"extra_json": json.dumps({"doc_type": ""}),
}
item = Item.from_row(row)
assert item.tags == ["module:pfs", "year:2026"]
def test_from_row_with_tags_string(self) -> None:
row = {
"key": "K1",
"item_type": "source",
"title": "Test",
"tags": "module:pfs;year:2026",
"extra_json": json.dumps({"doc_type": ""}),
}
item = Item.from_row(row)
assert "module:pfs" in item.tags
assert "year:2026" in item.tags
# ── Rule ─────────────────────────────────────────────────────────────────────
class TestRule:
def test_default_item_type(self) -> None:
r = Rule(title="Test Rule")
assert r.item_type == "rule"
def test_to_row_includes_extra_json(self) -> None:
r = Rule(
key="R1",
title="PFS Final Rule",
fr_volume="90",
fr_page="98452",
document_number="2025-19787",
cms_id="CMS-1832-F",
rule_type="final",
effective_date="2026-01-01",
)
row = r.to_row()
ej = json.loads(row["extra_json"])
assert ej["fr_volume"] == "90"
assert ej["cms_id"] == "CMS-1832-F"
def test_roundtrip(self) -> None:
r = Rule(
key="R1",
title="Test",
fr_volume="90",
fr_page="1000",
rule_type="final",
)
row = r.to_row()
r2 = Item.from_row(row)
assert isinstance(r2, Rule)
assert r2.fr_volume == "90"
assert r2.fr_page == "1000"
# ── Manual ───────────────────────────────────────────────────────────────────
class TestManual:
def test_default_item_type(self) -> None:
m = Manual()
assert m.item_type == "manual"
def test_default_institution(self) -> None:
m = Manual()
assert "Medicare" in m.institution
def test_to_row_includes_extra_json(self) -> None:
m = Manual(
manual_name="Claims Processing Manual",
pub_number="100-04",
chapter="12",
)
row = m.to_row()
ej = json.loads(row["extra_json"])
assert ej["manual_name"] == "Claims Processing Manual"
assert ej["chapter"] == "12"
def test_roundtrip(self) -> None:
m = Manual(
key="M1",
title="Test",
manual_name="CPM",
pub_number="100-04",
chapter="12",
transmittal="R100",
)
row = m.to_row()
m2 = Item.from_row(row)
assert isinstance(m2, Manual)
assert m2.transmittal == "R100"
# ── Regulation ───────────────────────────────────────────────────────────────
class TestRegulation:
def test_default_item_type(self) -> None:
r = Regulation()
assert r.item_type == "regulation"
def test_roundtrip(self) -> None:
r = Regulation(
key="REG1",
cfr_title="42",
cfr_part="414",
cfr_section="414.22",
authority="42 USC 1395w-4",
effective_date="2025-01-01",
)
row = r.to_row()
r2 = Item.from_row(row)
assert isinstance(r2, Regulation)
assert r2.cfr_title == "42"
assert r2.authority == "42 USC 1395w-4"
# ── Download ─────────────────────────────────────────────────────────────────
class TestDownload:
def test_default_item_type(self) -> None:
d = Download()
assert d.item_type == "download"
def test_file_urls(self) -> None:
d = Download(
file_urls=["https://example.com/a.zip", "https://example.com/b.zip"]
)
assert len(d.file_urls) == 2
def test_roundtrip(self) -> None:
d = Download(
key="D1",
title="RVU26A",
page_type="rvu",
file_urls=["https://example.com/rvu.zip"],
year=2026,
quarter="A",
)
row = d.to_row()
d2 = Item.from_row(row)
assert isinstance(d2, Download)
assert d2.year == 2026
assert d2.file_urls == ["https://example.com/rvu.zip"]
# ── Source ───────────────────────────────────────────────────────────────────
class TestSource:
def test_default_item_type(self) -> None:
s = Source()
assert s.item_type == "source"
def test_roundtrip(self) -> None:
s = Source(key="S1", title="Test", doc_type="guidance")
row = s.to_row()
s2 = Item.from_row(row)
assert isinstance(s2, Source)
assert s2.doc_type == "guidance"
# ── Deprecated _base_dict ───────────────────────────────────────────
class TestBaseDict:
def test_emits_deprecation_warning(self) -> None:
item = Item(
url="https://example.com",
access_date="2025-01-01T00:00:00Z",
abstract="abstract text",
tags=["module:pfs"],
collections=["COL1"],
extra="extra info",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
d = item._base_dict()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert "_base_dict" in str(w[0].message)
assert d["url"] == "https://example.com"
assert d["accessDate"] == "2025-01-01T00:00:00Z"
assert d["abstractNote"] == "abstract text"
assert d["tags"] == [{"tag": "module:pfs", "type": 0}]
assert d["collections"] == ["COL1"]
assert d["extra"] == "extra info"
def test_empty_fields(self) -> None:
item = Item()
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
d = item._base_dict()
assert d == {}
def test_get_classmethod(self) -> None:
assert Item._get({"key": "val"}, "key") == "val"
assert Item._get({"key": ""}, "key") == ""
assert Item._get({"key": None}, "key") == ""
assert Item._get({}, "key") == ""
assert Item._get({}, "key", "default") == "default"
# ── Deprecated to_zotero / from_zotero ─────────────────────────────
class TestRuleDeprecated:
def test_to_zotero(self) -> None:
r = Rule(
title="PFS Rule",
fr_volume="90",
fr_page="98452",
document_number="2025-19787",
cms_id="CMS-1832-F",
rule_type="final",
date_published="2025-11-01",
effective_date="2026-01-01",
url="https://example.com/rule",
abstract="Abstract",
extra="Extra info",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
d = r.to_zotero()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert d["itemType"] == "statute"
assert d["nameOfAct"] == "PFS Rule"
assert d["code"] == "FR"
assert d["codeNumber"] == "90"
assert d["pages"] == "98452"
assert d["url"] == "https://example.com/rule"
assert d["abstractNote"] == "Abstract"
assert d["extra"] == "Extra info"
def test_from_zotero(self) -> None:
data = {
"key": "RULEKEY1",
"nameOfAct": "Test Rule",
"codeNumber": "90",
"pages": "1000",
"session": "CMS-1832-F",
"dateEnacted": "2025-11-01",
"history": "Document: 2025-19787; Type: final; Effective: 2026-01-01",
"url": "https://example.com/rule",
"accessDate": "2026-01-15T00:00:00Z",
"abstractNote": "Abstract",
"extra": "Extra",
"tags": [{"tag": "module:pfs"}],
"collections": ["COL1"],
}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
r = Rule.from_zotero(data)
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert r.key == "RULEKEY1"
assert r.title == "Test Rule"
assert r.fr_volume == "90"
assert r.document_number == "2025-19787"
assert r.rule_type == "final"
assert r.effective_date == "2026-01-01"
assert r.tags == ["module:pfs"]
assert r.collections == ["COL1"]
def test_from_zotero_with_data_wrapper(self) -> None:
data = {
"data": {
"key": "K1",
"nameOfAct": "Rule",
"codeNumber": "90",
"pages": "",
"history": "",
"tags": [],
"collections": [],
}
}
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
r = Rule.from_zotero(data)
assert r.key == "K1"
class TestManualDeprecated:
def test_to_zotero(self) -> None:
m = Manual(
title="Chapter 12",
manual_name="Claims Processing Manual",
pub_number="100-04",
chapter="12",
transmittal="R100",
date_published="2025-01-01",
url="https://example.com/manual",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
d = m.to_zotero()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert d["itemType"] == "report"
assert d["reportType"] == "Internet-Only Manual"
assert d["seriesTitle"] == "Claims Processing Manual"
assert d["seriesNumber"] == "Chapter 12"
assert "Transmittal: R100" in d["extra"]
assert d["url"] == "https://example.com/manual"
def test_to_zotero_no_transmittal(self) -> None:
m = Manual(title="Test")
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
d = m.to_zotero()
assert "url" not in d # no url set
assert "extra" not in d # no transmittal
def test_from_zotero(self) -> None:
data = {
"key": "MKEY",
"title": "Chapter 12",
"seriesTitle": "Claims Processing Manual",
"reportNumber": "100-04",
"seriesNumber": "Chapter 12",
"institution": "CMS",
"date": "2025-01-01",
"url": "https://example.com/manual",
"accessDate": "",
"abstractNote": "",
"extra": "Transmittal: R100\nOther info",
"tags": [{"tag": "module:pfs"}],
"collections": [],
}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
m = Manual.from_zotero(data)
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert m.chapter == "12"
assert m.transmittal == "R100"
assert m.manual_name == "Claims Processing Manual"
assert m.extra == "Other info"
class TestRegulationDeprecated:
def test_to_zotero(self) -> None:
r = Regulation(
title="42 CFR Part 414",
cfr_title="42",
cfr_part="414",
cfr_section="414.22",
authority="42 USC 1395w-4",
effective_date="2025-01-01",
url="https://example.com/reg",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
d = r.to_zotero()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert d["code"] == "C.F.R."
assert d["codeNumber"] == "42"
assert d["section"] == "414.22"
assert d["url"] == "https://example.com/reg"
def test_to_zotero_no_url(self) -> None:
r = Regulation(cfr_title="42", cfr_part="414")
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
d = r.to_zotero()
assert "url" not in d
def test_from_zotero(self) -> None:
data = {
"key": "REGKEY",
"nameOfAct": "42 CFR Part 414",
"codeNumber": "42",
"section": "414.22",
"dateEnacted": "2025-01-01",
"history": "Part 414; Authority: 42 USC 1395w-4",
"url": "https://example.com/reg",
"accessDate": "",
"abstractNote": "",
"extra": "",
"tags": [{"tag": "source:ecfr"}],
"collections": [],
}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
r = Regulation.from_zotero(data)
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert r.cfr_part == "414"
assert r.authority == "42 USC 1395w-4"
assert r.tags == ["source:ecfr"]
class TestDownloadDeprecated:
def test_to_zotero(self) -> None:
d = Download(
title="RVU26A",
website_title="CMS",
date_published="2026-01-01",
file_urls=["https://cms.gov/rvu.zip"],
url="https://example.com/dl",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
zd = d.to_zotero()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert zd["itemType"] == "webpage"
assert zd["websiteTitle"] == "CMS"
assert "Files: https://cms.gov/rvu.zip" in zd["extra"]
assert zd["url"] == "https://example.com/dl"
def test_to_zotero_no_files_no_url(self) -> None:
d = Download(title="Test")
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
zd = d.to_zotero()
assert "url" not in zd
assert "extra" not in zd
def test_from_zotero(self) -> None:
data = {
"key": "DLKEY",
"title": "RVU26A",
"websiteTitle": "CMS",
"date": "2026-01-01",
"url": "https://example.com/dl",
"accessDate": "",
"abstractNote": "",
"extra": "Files: https://cms.gov/a.zip; https://cms.gov/b.zip\nNotes",
"tags": [{"tag": "file:rvu"}],
"collections": [],
}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
d = Download.from_zotero(data)
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert d.file_urls == [
"https://cms.gov/a.zip",
"https://cms.gov/b.zip",
]
assert d.extra == "Notes"
class TestSourceDeprecated:
def test_to_zotero(self) -> None:
s = Source(
title="Doc",
doc_type="guidance",
institution="CMS",
date_published="2025-01-01",
url="https://example.com/src",
)
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
zd = s.to_zotero()
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert zd["itemType"] == "document"
assert zd["type"] == "guidance"
assert zd["publisher"] == "CMS"
assert zd["url"] == "https://example.com/src"
def test_to_zotero_no_url(self) -> None:
s = Source(title="Test")
with warnings.catch_warnings(record=True):
warnings.simplefilter("always")
zd = s.to_zotero()
assert "url" not in zd
def test_from_zotero(self) -> None:
data = {
"key": "SRCKEY",
"title": "Guidance Doc",
"type": "guidance",
"publisher": "CMS Innovation Center",
"date": "2025-06-01",
"url": "https://example.com/src",
"accessDate": "2026-01-01T00:00:00Z",
"abstractNote": "Summary",
"extra": "Notes",
"tags": [{"tag": "source:4i"}],
"collections": ["COL1"],
}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
s = Source.from_zotero(data)
assert len(w) == 1
assert issubclass(w[0].category, DeprecationWarning)
assert s.doc_type == "guidance"
assert s.institution == "CMS Innovation Center"
assert s.tags == ["source:4i"]
assert s.collections == ["COL1"]