Files
stack/tests/rex/comments/test_extract_other.py
kert 7281012c76
Some checks failed
CI / lint (push) Successful in 32s
Deploy / notebooks (push) Has been skipped
Deploy / zotero (push) Has been skipped
Deploy / api (push) Has been skipped
Deploy / mc (push) Has been skipped
Infra CI / notebooks (push) Failing after 14s
Package Supply Chain / pkg-supply-chain (push) Failing after 34s
Deploy / report (push) Successful in 28s
Deploy / docs (push) Has been skipped
Infra CI / zotero (push) Successful in 12s
Infra CI / docs (push) Successful in 1m16s
Infra CI / api (push) Successful in 23s
Infra CI / mc (push) Successful in 12s
CI / test (push) Has been cancelled
fix(comments): address code-review BLOCKER + 4 IMPORTANT issues
From the end-of-impl review:

1. BLOCKER: SQLite cross-thread error in stack comments extract --bib.
   _bib_lookup_factory was sharing the bib.connect() connection across
   walker worker threads — sqlite3 defaults to check_same_thread=True
   so every worker would have raised ProgrammingError. Tests didn't
   catch it because all CLI tests pass --no-bib. Fix: open a fresh
   read-only connection with check_same_thread=False directly via
   conf.path("db.bib"); SQLite handles concurrent reads safely.

2. view._iter_index_rows now catches yaml.YAMLError too, so one
   malformed combined.md doesn't crash `stack comments stats`.

3. Image attachments (.jpg/.png/.tif/.tiff/.gif/.bmp) now classify as
   ocr_needed instead of being silently dropped as unsupported. This
   gives the phase-2 OCR command a clean candidate set to query.
   Real CMS comments include scanned-letter images.

4. view.register() defaults to rebuild=True so downstream consumers
   (#254/#255) always see fresh data. Pass rebuild=False to skip.

5. extract_comment writes via tmp file + os.replace() so concurrent
   walkers / restarts never see a half-written combined.md.

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

46 lines
1.4 KiB
Python

"""Plain-text fallback + unsupported extensions."""
from __future__ import annotations
from pathlib import Path
from rex.comments import extract_attachment
def test_extract_txt(tmp_path: Path):
p = tmp_path / "note.txt"
p.write_text("This is a plain text comment longer than fifty characters total.")
result = extract_attachment(p)
assert result.status == "ok"
assert "plain text comment" in result.text
def test_extract_html_strips_tags(tmp_path: Path):
p = tmp_path / "page.html"
p.write_text(
"<html><body><p>This is a comment letter</p>"
"<p>with two paragraphs of substance.</p></body></html>"
)
result = extract_attachment(p)
assert result.status == "ok"
assert "This is a comment letter" in result.text
assert "<p>" not in result.text
def test_extract_unknown_extension(tmp_path: Path):
p = tmp_path / "weird.xyz"
p.write_bytes(b"some bytes")
result = extract_attachment(p)
assert result.status == "unsupported"
assert result.chars == 0
def test_extract_image_marked_ocr_needed(tmp_path: Path):
"""Image attachments (scanned letters) route to phase-2 OCR queue."""
for ext in (".jpg", ".jpeg", ".png", ".tif", ".tiff", ".gif", ".bmp"):
p = tmp_path / f"scan{ext}"
p.write_bytes(b"fake image bytes")
result = extract_attachment(p)
assert result.status == "ocr_needed", f"{ext}: {result.status}"
assert result.chars == 0