216 lines
7.3 KiB
Python
216 lines
7.3 KiB
Python
"""Tests for bib.cfrlink — bidirectional CFR cite ↔ eCFR URL (P41)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from bib import cfrlink
|
|
|
|
SEC_URL = "https://www.ecfr.gov/current/title-42/section-425.400"
|
|
FRAG_URL = SEC_URL + "#p-425.400(c)(1)(iv)"
|
|
PART_URL = "https://www.ecfr.gov/current/title-42/part-425"
|
|
CANON_URL = (
|
|
"https://www.ecfr.gov/current/title-42/chapter-IV/subchapter-B/"
|
|
"part-425/subpart-E/section-425.400"
|
|
)
|
|
|
|
|
|
# ── parse_cite ──────────────────────────────────────────────────────
|
|
|
|
|
|
class TestParseCite:
|
|
def test_full_paragraph_cite(self) -> None:
|
|
c = cfrlink.parse_cite("42 CFR 425.400(c)(1)(iv)")
|
|
assert (c.title, c.part, c.section, c.paras) == (
|
|
42,
|
|
"425",
|
|
"425.400",
|
|
("c", "1", "iv"),
|
|
)
|
|
|
|
def test_bluebook_dots_and_section_sign(self) -> None:
|
|
c = cfrlink.parse_cite("42 C.F.R. § 425.400")
|
|
assert (c.title, c.section, c.paras) == (42, "425.400", ())
|
|
assert cfrlink.parse_cite("42 CFR § 414.1425").section == "414.1425"
|
|
|
|
def test_case_and_spacing_variants(self) -> None:
|
|
assert cfrlink.parse_cite("42 cfr 414.1450(b)(1)").paras == ("b", "1")
|
|
assert cfrlink.parse_cite(" 42 CFR 425.400 ").section == "425.400"
|
|
|
|
def test_part_level(self) -> None:
|
|
c = cfrlink.parse_cite("42 CFR Part 425")
|
|
assert (c.title, c.part, c.section, c.paras) == (42, "425", "", ())
|
|
assert cfrlink.parse_cite("42 CFR part 425 subpart E").part == "425"
|
|
|
|
def test_title_required(self) -> None:
|
|
with pytest.raises(ValueError, match="title"):
|
|
cfrlink.parse_cite("§ 425.400(c)")
|
|
with pytest.raises(ValueError, match="[Nn]ot a CFR"):
|
|
cfrlink.parse_cite("91 FR 44218")
|
|
|
|
|
|
# ── url ─────────────────────────────────────────────────────────────
|
|
|
|
|
|
class TestUrl:
|
|
def test_section_url(self) -> None:
|
|
assert cfrlink.url(cfrlink.parse_cite("42 CFR 425.400")) == SEC_URL
|
|
|
|
def test_paragraph_fragment(self) -> None:
|
|
assert cfrlink.url(cfrlink.parse_cite("42 CFR 425.400(c)(1)(iv)")) == FRAG_URL
|
|
|
|
def test_part_url(self) -> None:
|
|
assert cfrlink.url(cfrlink.parse_cite("42 CFR Part 425")) == PART_URL
|
|
|
|
def test_date_pin(self) -> None:
|
|
c = cfrlink.parse_cite("42 CFR 425.400")
|
|
pinned = cfrlink.CfrCite(
|
|
title=c.title,
|
|
part=c.part,
|
|
section=c.section,
|
|
paras=c.paras,
|
|
date="2026-01-01",
|
|
)
|
|
assert (
|
|
cfrlink.url(pinned)
|
|
== "https://www.ecfr.gov/on/2026-01-01/title-42/section-425.400"
|
|
)
|
|
|
|
|
|
# ── cite_of ─────────────────────────────────────────────────────────
|
|
|
|
|
|
class TestCiteOf:
|
|
def test_short_url(self) -> None:
|
|
assert cfrlink.cite_of(SEC_URL) == "42 CFR 425.400"
|
|
|
|
def test_fragment_url(self) -> None:
|
|
assert cfrlink.cite_of(FRAG_URL) == "42 CFR 425.400(c)(1)(iv)"
|
|
|
|
def test_canonical_hierarchy_url(self) -> None:
|
|
assert cfrlink.cite_of(CANON_URL) == "42 CFR 425.400"
|
|
assert cfrlink.cite_of(CANON_URL + "#p-425.400(c)") == "42 CFR 425.400(c)"
|
|
|
|
def test_part_url(self) -> None:
|
|
assert cfrlink.cite_of(PART_URL) == "42 CFR Part 425"
|
|
|
|
def test_dated_url(self) -> None:
|
|
assert (
|
|
cfrlink.cite_of(
|
|
"https://www.ecfr.gov/on/2026-01-01/title-42/section-425.400"
|
|
)
|
|
== "42 CFR 425.400"
|
|
)
|
|
|
|
def test_non_ecfr_url_raises(self) -> None:
|
|
with pytest.raises(ValueError, match="eCFR"):
|
|
cfrlink.cite_of("https://www.federalregister.gov/documents/x")
|
|
|
|
|
|
# ── round-trip laws ─────────────────────────────────────────────────
|
|
|
|
|
|
class TestRoundTrip:
|
|
@pytest.mark.parametrize(
|
|
"ref",
|
|
[
|
|
"42 CFR 425.400(c)(1)(iv)",
|
|
"42 C.F.R. § 414.1450(b)(1)",
|
|
"42 CFR § 414.1425",
|
|
"42 CFR Part 425",
|
|
"45 cfr 155.20",
|
|
],
|
|
)
|
|
def test_cite_url_cite_is_canonical(self, ref: str) -> None:
|
|
c = cfrlink.parse_cite(ref)
|
|
assert cfrlink.cite_of(cfrlink.url(c)) == cfrlink.canonical(c)
|
|
|
|
@pytest.mark.parametrize("u", [SEC_URL, FRAG_URL, PART_URL])
|
|
def test_url_cite_url_is_short_form(self, u: str) -> None:
|
|
assert cfrlink.url(cfrlink.parse_cite(cfrlink.cite_of(u))) == u
|
|
|
|
|
|
# ── item_for / place (#640) ─────────────────────────────────────────
|
|
|
|
|
|
def _reg_store():
|
|
from bib.item import Regulation
|
|
from bib.store import Store
|
|
|
|
s = Store(":memory:")
|
|
part_key = s.create(
|
|
Regulation(
|
|
title="42 CFR Part 425",
|
|
url="https://www.ecfr.gov/current/title-42/part-425",
|
|
)
|
|
)
|
|
sec_key = s.create(
|
|
Regulation(
|
|
title="42 CFR Part 425 § 425.400",
|
|
url="https://www.ecfr.gov/current/title-42/part-425/section-425.400",
|
|
)
|
|
)
|
|
s.create(
|
|
Regulation(
|
|
title="42 CFR Part 414",
|
|
url="https://www.ecfr.gov/current/title-42/part-414",
|
|
)
|
|
)
|
|
return s, part_key, sec_key
|
|
|
|
|
|
class TestItemFor:
|
|
def test_exact_section_beats_part(self) -> None:
|
|
s, _part, sec = _reg_store()
|
|
assert cfrlink.item_for(cfrlink.parse_cite("42 CFR 425.400(c)"), s) == sec
|
|
s.close()
|
|
|
|
def test_part_fallback(self) -> None:
|
|
s, part, _sec = _reg_store()
|
|
assert cfrlink.item_for(cfrlink.parse_cite("42 CFR 425.402"), s) == part
|
|
s.close()
|
|
|
|
def test_miss_returns_empty(self) -> None:
|
|
s, _part, _sec = _reg_store()
|
|
assert cfrlink.item_for(cfrlink.parse_cite("45 CFR 155.20"), s) == ""
|
|
s.close()
|
|
|
|
|
|
class TestCfrPlace:
|
|
def test_place_on_section_item(self) -> None:
|
|
s, _part, sec = _reg_store()
|
|
link = cfrlink.place(s, "42 CFR 425.400(c)(1)(iv)", label="attribution ¶")
|
|
assert link.item_key == sec
|
|
con = s._con() # noqa: SLF001
|
|
row = con.execute(
|
|
"SELECT item_key, p_id, page, label, url FROM fr_links"
|
|
).fetchone()
|
|
assert tuple(row) == (
|
|
sec,
|
|
None,
|
|
0,
|
|
"attribution ¶",
|
|
FRAG_URL,
|
|
)
|
|
cfrlink.place(s, "42 CFR 425.400(c)(1)(iv)") # same URL → no dup
|
|
n = con.execute("SELECT count(*) FROM fr_links").fetchone()[0]
|
|
assert n == 1
|
|
s.close()
|
|
|
|
def test_place_without_matching_item_raises(self) -> None:
|
|
s, _part, _sec = _reg_store()
|
|
with pytest.raises(ValueError, match="regulation item"):
|
|
cfrlink.place(s, "45 CFR 155.20")
|
|
s.close()
|
|
|
|
|
|
class TestMdLink:
|
|
def test_store_free_markdown(self) -> None:
|
|
assert (
|
|
cfrlink.md_link("42 CFR 425.400(c)(1)(iv)")
|
|
== f"[42 CFR 425.400(c)(1)(iv)]({FRAG_URL})"
|
|
)
|
|
assert cfrlink.md_link("42 CFR Part 425", text="the MSSP part") == (
|
|
f"[the MSSP part]({PART_URL})"
|
|
)
|