75 lines
2.7 KiB
Python
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) |