Files
stack/tests/rex/comments/test_combine.py
kert b2ad400764 feat(comments): DOCX/text extract + combined.md writer (refs #253)
- extract_attachment now dispatches PDF/DOCX/TXT/HTML; DOCX via
  python-docx, text-like via plain read with cheap HTML strip.
- combine.py writes one combined.md per comment dir with YAML
  frontmatter (per-attachment status + chars) and per-section body.
- extract_comment is idempotent (existing combined.md is a no-op
  unless force=True).
- parse_combined() splits frontmatter ↔ body for downstream consumers.

Walker + DuckDB view land in the next batch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 15:42:32 -04:00

90 lines
2.9 KiB
Python

"""Per-comment combine — write combined.md with YAML frontmatter."""
from __future__ import annotations
from pathlib import Path
import fitz
from rex.comments import extract_comment
from rex.comments.combine import parse_combined
def _make_pdf(path: Path, text: str) -> None:
doc = fitz.open()
doc.new_page().insert_text((50, 72), text)
doc.save(str(path))
doc.close()
def _setup_comment_dir(tmp_path: Path, cid: str = "CMS-2024-0001-0042") -> Path:
"""Layout matches .state/comments/{docket}/{cid}/."""
docket = "-".join(cid.split("-")[:3])
d = tmp_path / docket / cid
d.mkdir(parents=True)
_make_pdf(
d / "attachment_1.pdf",
"Position: oppose the proposed rule. This is a substantive comment.",
)
return d
def test_extract_comment_writes_combined_md(tmp_path: Path):
d = _setup_comment_dir(tmp_path)
out = extract_comment(d, inline_body="Inline body text from items.abstract.")
assert out == d / "combined.md"
assert out.is_file()
def test_combined_md_has_frontmatter_and_body(tmp_path: Path):
d = _setup_comment_dir(tmp_path)
extract_comment(d, inline_body="Inline body.")
text = (d / "combined.md").read_text()
fm, body = parse_combined(text)
assert fm["comment_id"] == "CMS-2024-0001-0042"
assert fm["docket_id"] == "CMS-2024-0001"
assert fm["chars"] > 0
assert len(fm["attachments"]) == 1
assert fm["attachments"][0]["file"] == "attachment_1.pdf"
assert fm["attachments"][0]["status"] == "ok"
assert "## Inline comment" in body
assert "Inline body." in body
assert "## attachment_1.pdf" in body
assert "Position: oppose" in body
def test_extract_comment_is_idempotent(tmp_path: Path):
d = _setup_comment_dir(tmp_path)
first = extract_comment(d, inline_body="x")
mtime1 = first.stat().st_mtime
second = extract_comment(d, inline_body="x")
assert second == first
assert second.stat().st_mtime == mtime1 # no rewrite on second call
def test_extract_comment_force_rewrites(tmp_path: Path):
d = _setup_comment_dir(tmp_path)
extract_comment(d, inline_body="first")
extract_comment(d, inline_body="second", force=True)
body = (d / "combined.md").read_text()
assert "second" in body
assert "first" not in body
def test_extract_comment_no_attachments(tmp_path: Path):
d = tmp_path / "CMS-2024-0001" / "CMS-2024-0001-0099"
d.mkdir(parents=True)
out = extract_comment(d, inline_body="Inline only.")
fm, body = parse_combined(out.read_text())
assert fm["attachments"] == []
assert "Inline only." in body
def test_extract_comment_handles_failed_attachment(tmp_path: Path):
d = tmp_path / "CMS-2024-0001" / "CMS-2024-0001-0100"
d.mkdir(parents=True)
(d / "attachment_1.pdf").write_bytes(b"not a real pdf")
out = extract_comment(d, inline_body="x")
fm, _body = parse_combined(out.read_text())
assert fm["attachments"][0]["status"] == "failed"