Scriptorium / tests /test_epub.py
mattkevan's picture
First in space
af4851b
Raw
History Blame Contribute Delete
2.54 kB
from pathlib import Path
import pytest
from ebooklib import epub
from backend.epub import EpubConfig, parse_epub
def _write_sample_epub(target: Path, chapter_count: int = 2) -> Path:
book = epub.EpubBook()
book.set_identifier("sample-id")
book.set_title("Sample Book")
book.set_language("en")
book.add_author("Example Author")
chapters = []
for idx in range(chapter_count):
chapter = epub.EpubHtml(
title=f"Chapter {idx + 1}",
file_name=f"chap_{idx + 1}.xhtml",
lang="en",
)
chapter.content = (
f"<h1>Chapter {idx + 1}</h1>"
f"<p>This is chapter {idx + 1}. It has enough words to estimate audio.</p>"
)
book.add_item(chapter)
chapters.append(chapter)
book.toc = tuple(chapters)
book.spine = ["nav", *chapters]
book.add_item(epub.EpubNcx())
book.add_item(epub.EpubNav())
epub.write_epub(str(target), book)
return target
def test_parse_epub_extracts_metadata_and_chapters(tmp_path: Path) -> None:
epub_path = _write_sample_epub(tmp_path / "sample.epub", chapter_count=3)
payload = parse_epub(epub_path, config=EpubConfig(max_file_bytes=2_000_000))
assert payload["title"] == "Sample Book"
assert payload["author"] == "Example Author"
assert len(payload["chapters"]) == 3
assert payload["chapters"][0]["title"] == "Chapter 1"
assert payload["chapters"][0]["included"] is True
assert payload["chapters"][0]["text"]
def test_parse_epub_rejects_oversized_upload(tmp_path: Path) -> None:
epub_path = _write_sample_epub(tmp_path / "sample.epub", chapter_count=1)
with pytest.raises(ValueError, match="too large"):
parse_epub(epub_path, config=EpubConfig(max_file_bytes=32))
def test_parse_epub_rejects_malformed_file(tmp_path: Path) -> None:
bad_path = tmp_path / "bad.epub"
bad_path.write_text("not really an epub", encoding="utf-8")
with pytest.raises(ValueError, match="Invalid EPUB"):
parse_epub(bad_path, config=EpubConfig(max_file_bytes=2_000_000))
def test_parse_epub_accepts_valid_epub_without_epub_suffix(tmp_path: Path) -> None:
epub_path = _write_sample_epub(tmp_path / "sample.epub", chapter_count=1)
no_suffix_path = tmp_path / "upload-cache-file"
no_suffix_path.write_bytes(epub_path.read_bytes())
payload = parse_epub(no_suffix_path, config=EpubConfig(max_file_bytes=2_000_000))
assert payload["title"] == "Sample Book"
assert len(payload["chapters"]) == 1