Files
stack/tests/cli/test_comments.py

130 lines
3.9 KiB
Python

"""CLI: stack comments {extract, extract-ocr, stats}."""
from __future__ import annotations
from pathlib import Path
import fitz
from typer.testing import CliRunner
from cli.comments import app
runner = CliRunner()
def _seed(root: Path) -> Path:
cdir = root / "CMS-2024-0001" / "CMS-2024-0001-0001"
cdir.mkdir(parents=True)
doc = fitz.open()
doc.new_page().insert_text((50, 72), "Long body content " * 10)
doc.save(str(cdir / "attachment_1.pdf"))
doc.close()
return cdir
def test_extract_writes_combined(tmp_path: Path):
cdir = _seed(tmp_path)
result = runner.invoke(
app,
[
"extract",
"--root",
str(tmp_path),
"--no-bib", # skip bib.sqlite lookup in tests
"--workers",
"1",
],
)
assert result.exit_code == 0, result.output
assert (cdir / "combined.md").is_file()
assert "written" in result.output.lower()
def test_extract_ocr_empty_queue(tmp_path: Path):
# Implemented in #663 — an empty root reports a zero queue and exits
# cleanly without loading the OCR engine or the bib lookup.
result = runner.invoke(app, ["extract-ocr", "--root", str(tmp_path)])
assert result.exit_code == 0
assert "ocr queue: 0" in result.output
def test_stats_after_extract(tmp_path: Path):
_seed(tmp_path)
runner.invoke(
app,
["extract", "--root", str(tmp_path), "--no-bib", "--workers", "1"],
)
result = runner.invoke(app, ["stats", "--root", str(tmp_path)])
assert result.exit_code == 0, result.output
assert "1" in result.output # at least one comment counted
def test_extract_attaches_combined_md_as_note(tmp_path: Path, monkeypatch):
"""Extract writes combined.md and per-attachment sibling MDs to disk.
Only one Zotero-bound artifact: a single bib note titled 'Comment text'
whose content is the rendered-HTML of combined.md. No file attachments."""
from bib import connect
from bib.item import Source
bib_db = tmp_path / "bib.sqlite"
monkeypatch.setattr("conf.path", lambda _: bib_db)
cdir = _seed(tmp_path)
comment_id = cdir.name # CMS-2024-0001-0001
store = connect(str(bib_db))
item = Source(
title=f"Comment {comment_id}",
url=f"https://www.regulations.gov/comment/{comment_id}",
)
item_key = store.upsert(item)
store.close()
result = runner.invoke(app, ["extract", "--root", str(tmp_path), "--workers", "1"])
assert result.exit_code == 0, result.output
# Disk siblings still written (kept for non-Zotero corpus consumers)
assert (cdir / "combined.md").is_file()
assert (cdir / "attachment_1.pdf.md").is_file()
def md_attachments():
store = connect(str(bib_db))
rows = list(
store._con().execute(
"SELECT a.filename FROM attachments a "
"JOIN items i ON a.item_id=i.id "
"WHERE i.key=? AND a.filename LIKE '%.md'",
(item_key,),
)
)
store.close()
return rows
def notes():
store = connect(str(bib_db))
rows = list(
store._con().execute(
"SELECT n.title, n.content FROM notes n "
"JOIN items i ON n.item_id=i.id WHERE i.key=?",
(item_key,),
)
)
store.close()
return rows
# No file attachments — old behavior is gone.
assert md_attachments() == []
# Exactly one note, rendered HTML.
rows = notes()
assert len(rows) == 1
title, content = rows[0]
assert title == "Comment text"
assert "<h1>" in content or "<h2>" in content
assert "Long body content" in content # the seeded PDF text shows up
# Idempotent on re-run
runner.invoke(app, ["extract", "--root", str(tmp_path), "--workers", "1"])
assert len(notes()) == 1
assert md_attachments() == []