import pytest from pathlib import Path from datetime import date from chitai.services.metadata_extractor import EpubExtractor, Extractor, PdfExtractor @pytest.mark.asyncio() class TestEpubExtractor: async def test_extraction_by_path(self): path = Path("tests/data_files/Moby Dick; Or, The Whale - Herman Melville.epub") metadata = await EpubExtractor.extract_metadata(path) assert metadata["title"] == "Moby Dick; Or, The Whale" assert metadata["authors"] == ["Herman Melville"] assert metadata["published_date"] == date(year=2001, month=7, day=1) EPUB = Path("tests/data_files/Metamorphosis - Franz Kafka.epub") PDF = Path("tests/data_files/Calculus Made Easy - Silvanus Thompson.pdf") @pytest.mark.asyncio() class TestIdentifierMerging: """A book's formats each contribute identifiers; none of them replaces the rest.""" async def test_every_format_contributes(self, monkeypatch: pytest.MonkeyPatch) -> None: """ Identifiers are a collection, not a single value. Merging the whole dict meant the last format to report won outright: an EPUB declaring an ASIN, a Google volume id and a Calibre id kept none of them once a PDF contributed one ISBN. """ async def epub(_file): return { "title": "How Linux Works", "identifiers": {"isbn-13": "9781718500419", "asin": "1718500408"}, } async def pdf(_file): return {"identifiers": {"isbn-13": "9781718500402", "isbn-10": "1593270356"}} monkeypatch.setattr(EpubExtractor, "extract_metadata", epub) monkeypatch.setattr(PdfExtractor, "extract_metadata", pdf) metadata = await Extractor.extract_metadata( [Path("How Linux Works.epub"), Path("How Linux Works.pdf")] ) assert metadata["identifiers"] == { # Declared by the publisher's toolchain, so it outranks the PDF's, which # was scraped off a copyright page that also prints the print edition's. "isbn-13": "9781718500419", "asin": "1718500408", "isbn-10": "1593270356", } async def test_a_second_format_that_finds_nothing_erases_nothing(self) -> None: """The PDF fixture carries no ISBN, so it must leave the EPUB's alone.""" metadata = await Extractor.extract_metadata([EPUB, PDF]) assert metadata["identifiers"] == {"id": "http://www.gutenberg.org/5200"} async def test_one_format_on_its_own_is_unaffected(self) -> None: metadata = await Extractor.extract_metadata([EPUB]) assert metadata["identifiers"] == {"id": "http://www.gutenberg.org/5200"} async def test_no_identifiers_anywhere_leaves_the_field_absent(self) -> None: """An empty dict would count as extracted metadata and overwrite nothing.""" metadata = await Extractor.extract_metadata([PDF]) assert "identifiers" not in metadata