Files
epub2pdf/tests/test_parse_opf.py

75 lines
2.7 KiB
Python

"""Unit tests for EPUB structure parsing (no rendering involved)."""
import pytest
import app
from tests.helpers import build_epub_tree
def test_missing_container_xml_raises(tmp_path):
(tmp_path / "META-INF").mkdir()
with pytest.raises(ValueError, match="missing META-INF/container.xml"):
app.parse_opf(tmp_path)
def test_container_xml_without_rootfile_raises(tmp_path):
(tmp_path / "META-INF").mkdir()
(tmp_path / "META-INF" / "container.xml").write_text(
'<?xml version="1.0"?><container version="1.0"><rootfiles/></container>',
encoding="utf-8",
)
with pytest.raises(ValueError, match="no rootfile"):
app.parse_opf(tmp_path)
def test_parse_opf_returns_meta_spine_and_pdir_ltr(tmp_path):
build_epub_tree(tmp_path)
meta, opf_dir, spine, pdir = app.parse_opf(tmp_path)
assert meta["title"] == "Tree Book"
assert meta["creator"] == "Tree Author"
assert meta["language"] == "en"
assert str(opf_dir).endswith("OEBPS")
assert [i["href"] for i in spine] == ["chapter1.xhtml", "chapter2.xhtml"] # img filtered out
assert pdir == "ltr" # unset defaults to ltr
def test_parse_opf_rtl_page_progression(tmp_path):
build_epub_tree(tmp_path, pdir="rtl")
_, _, _, pdir = app.parse_opf(tmp_path)
assert pdir == "rtl"
def test_nonlinear_spine_items_are_skipped(tmp_path):
items = [
("front", "front.xhtml", "application/xhtml+xml", ""),
("ch1", "chapter1.xhtml", "application/xhtml+xml", ""),
]
build_epub_tree(tmp_path, items=items, spine_ids=["ch1"])
# Add a non-linear itemref for 'front' via raw OPF edit
opf_path = tmp_path / "OEBPS" / "book.opf"
text = opf_path.read_text(encoding="utf-8")
text = text.replace(
'<spine><itemref idref="ch1"/></spine>',
'<spine><itemref idref="front" linear="no"/>'
'<itemref idref="ch1"/></spine>',
)
opf_path.write_text(text, encoding="utf-8")
_, _, spine, _ = app.parse_opf(tmp_path)
assert [i["href"] for i in spine] == ["chapter1.xhtml"]
def test_empty_spine_falls_back_to_non_nav_html(tmp_path):
items = [
("nav", "nav.xhtml", "application/xhtml+xml", "nav"),
("ch1", "chapter1.xhtml", "application/xhtml+xml", ""),
("img1", "img.png", "image/png", ""),
]
build_epub_tree(tmp_path, items=items, spine_ids=[]) # spine refs: none
_, _, spine, _ = app.parse_opf(tmp_path)
assert [i["href"] for i in spine] == ["chapter1.xhtml"] # nav + image excluded
def test_no_readable_content_raises(tmp_path):
items = [("img1", "img.png", "image/png", "")]
build_epub_tree(tmp_path, items=items, spine_ids=["img1"])
with pytest.raises(ValueError, match="No readable content"):
app.parse_opf(tmp_path)