Files
pdf/gateway/tests/convert/test_unit_writers.py
T

95 lines
3.2 KiB
Python

"""Unit tests for DOCX/XLSX writers and validators."""
from __future__ import annotations
import io
import zipfile
import pytest
from docx import Document
from openpyxl import load_workbook
from app.services.convert.pdf_bridge import PdfDocumentText, PdfPageText, _heuristic_tables
from app.services.convert.validate import ValidationError, validate_input
from app.services.convert.writers.docx_writer import _is_heading, build_docx_from_pdf_text
from app.services.convert.writers.xlsx_writer import build_xlsx_from_pdf_text
def test_heading_heuristic():
assert _is_heading("CHAPTER 1 INTRODUCTION")
assert _is_heading("1. Overview")
assert not _is_heading("This is a long sentence that should not be treated as a heading at all.")
def test_table_heuristic_pipe():
tables = _heuristic_tables(["Name | Qty", "A | 1", "B | 2"])
assert len(tables) == 1
assert tables[0][0] == ["Name", "Qty"]
assert len(tables[0]) == 3
def test_docx_writer_paragraphs_and_table():
doc_text = PdfDocumentText(
page_count=1,
pages=[
PdfPageText(
index=0,
width=612,
height=792,
paragraphs=["TITLE PAGE", "Body paragraph one."],
tables=[[["H1", "H2"], ["a", "b"]]],
raw_text="TITLE PAGE\nBody paragraph one.",
)
],
)
# ``build_docx_from_pdf_text`` is deprecated in favour of
# ``formatters.docx_formatter``. The legacy entry point still has callers,
# so it is still tested — but the deprecation notice is part of the
# contract, not noise: asserting it here means silently dropping the
# warning (or the function) fails the suite instead of passing quietly.
with pytest.warns(DeprecationWarning, match="docx_writer.build_docx_from_pdf_text"):
data = build_docx_from_pdf_text(doc_text)
with zipfile.ZipFile(io.BytesIO(data)) as zf:
assert "[Content_Types].xml" in zf.namelist()
doc = Document(io.BytesIO(data))
texts = [p.text for p in doc.paragraphs if p.text.strip()]
assert any("Body paragraph one." in t for t in texts)
assert len(doc.tables) >= 1
def test_xlsx_writer_cells():
doc_text = PdfDocumentText(
page_count=1,
pages=[
PdfPageText(
index=0,
width=612,
height=792,
paragraphs=[],
tables=[[["Name", "Qty"], ["Apple", "10"]]],
raw_text="",
)
],
)
with pytest.warns(DeprecationWarning, match="xlsx_writer.build_xlsx_from_pdf_text"):
data, warnings = build_xlsx_from_pdf_text(doc_text)
assert not any("No table" in w for w in warnings)
wb = load_workbook(io.BytesIO(data))
ws = wb.active
assert ws.cell(1, 1).value == "Name"
assert ws.cell(2, 1).value == "Apple"
def test_validate_rejects_empty_and_docm():
try:
validate_input(b"", "a.pdf", "pdf")
assert False, "expected ValidationError"
except ValidationError as exc:
assert "Empty" in str(exc)
try:
validate_input(b"PK", "macro.docm", "docx")
assert False, "expected ValidationError"
except ValidationError as exc:
assert exc.status_code == 415