Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions tests/comic/comic_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from unittest.mock import MagicMock

import pytest

from perdoo.cli.process import generate_naming
from perdoo.comic.archives import CBTArchive, CBZArchive
from perdoo.comic.comic import Comic
from perdoo.comic.metadata import ComicInfo, MetronInfo
from perdoo.settings import Naming


@pytest.fixture
def cbz_comic(cbz_archive: CBZArchive) -> Comic:
return Comic(filepath=cbz_archive.filepath)


@pytest.fixture
def cbt_comic(cbt_archive: CBTArchive) -> Comic:
return Comic(filepath=cbt_archive.filepath)


def test_convert_to_cbz(cbt_comic: Comic) -> None:
cbt_comic.convert_to(extension="cbz")
assert isinstance(cbt_comic.archive, CBZArchive)
assert cbt_comic.filepath.suffix == ".cbz"


def test_convert_to_cbt(cbz_comic: Comic) -> None:
cbz_comic.convert_to(extension="cbt")
assert isinstance(cbz_comic.archive, CBTArchive)
assert cbz_comic.filepath.suffix == ".cbt"


def test_clean_archive(cbz_comic: Comic) -> None:
cbz_comic.archive.list_filenames = MagicMock(
return_value=["001.jpg", "info.txt", "ComicInfo.xml", "cover.png"]
)
cbz_comic.archive.delete_file = MagicMock()
with cbz_comic.open_session() as session:
for extra in cbz_comic.list_extras():
session.delete(filename=extra.name)
cbz_comic.archive.delete_file.assert_called_once_with(filename="info.txt")


def test_write_comicinfo(cbz_comic: Comic, comic_info: ComicInfo) -> None:
with cbz_comic.open_session() as session:
_, info = cbz_comic.read_metadata(session=session)
assert info is None
session.write(filename=ComicInfo.FILENAME, data=comic_info.to_bytes())
_, info = cbz_comic.read_metadata(session=session)
assert info == comic_info


def test_write_metroninfo(cbz_comic: Comic, metron_info: MetronInfo) -> None:
with cbz_comic.open_session() as session:
info, _ = cbz_comic.read_metadata(session=session)
assert info is None
session.write(filename=MetronInfo.FILENAME, data=metron_info.to_bytes())
info, _ = cbz_comic.read_metadata(session=session)
assert info == metron_info


def test_write_metadata_override(cbz_comic: Comic, metron_info: MetronInfo) -> None:
metadata_copy = metron_info.model_copy(deep=True)
metadata_copy.series.volume = 2

with cbz_comic.open_session() as session:
info, _ = cbz_comic.read_metadata(session=session)
assert info is None
session.write(filename=MetronInfo.FILENAME, data=metron_info.to_bytes())
info, _ = cbz_comic.read_metadata(session=session)
assert info == metron_info
session.write(filename=MetronInfo.FILENAME, data=metadata_copy.to_bytes())
info, _ = cbz_comic.read_metadata(session=session)
assert info == metadata_copy


def test_rename(cbz_comic: Comic, metron_info: MetronInfo) -> None:
naming = generate_naming(settings=Naming(), metron_info=metron_info, comic_info=None)
cbz_comic.move_to(naming=naming, output_folder=cbz_comic.filepath.parent)
assert cbz_comic.filepath.name == "Test-Series-v1_#.cbz"
File renamed without changes.
Empty file.
38 changes: 38 additions & 0 deletions tests/comic/metadata/base_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from pathlib import Path

from perdoo.comic.metadata import ComicInfo
from perdoo.comic.metadata._base import sanitize
from perdoo.settings import Naming


def test_sanitize_basic() -> None:
assert sanitize(value="Example Title!", seperator="-") == "Example-Title!"
assert sanitize(value="Example/Title: 123", seperator="-") == "ExampleTitle-123"
assert sanitize(value=" already spaced ", seperator="_") == "already_spaced"


def test_sanitize_none_and_empty() -> None:
assert sanitize(value=None, seperator="-") is None
assert sanitize(value="", seperator="-") == ""


def test_evaluate_pattern() -> None:
obj = ComicInfo(series="Series", volume=1, number=2, format="Single Issue", publisher="Pub")
settings = Naming(seperator="-", default="{series-name}-{unknown}-{number:03}")
name = obj.get_filename(settings=settings)

assert name == "Series-unknown-002"


def test_metadata_to_file(tmp_path: Path) -> None:
obj = ComicInfo(series="Example", number=1, format="Single Issue")
out = tmp_path / obj.FILENAME
obj.to_file(file=out)

assert out.exists()

loaded = ComicInfo.from_bytes(content=out.read_bytes())

assert loaded.series == "Example"
assert loaded.number == "1"
assert loaded.format == "Single Issue"
96 changes: 96 additions & 0 deletions tests/comic/metadata/comic_info_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from datetime import date

from perdoo.comic.metadata import ComicInfo
from perdoo.comic.metadata.comic_info import Page, PageType
from perdoo.settings import Naming


def test_cover_date_property(comic_info: ComicInfo) -> None:
assert comic_info.cover_date is None

comic_info.cover_date = date(2020, 2, 29)
assert comic_info.year == 2020
assert comic_info.month == 2
assert comic_info.day == 29
assert comic_info.cover_date == date(2020, 2, 29)

comic_info.year = None
assert comic_info.year is None
assert comic_info.month == 2
assert comic_info.day == 29
assert comic_info.cover_date is None


def test_page_ordering_and_hashing() -> None:
p1 = Page(image=2, type=PageType.STORY)
p2 = Page(image=1, type=PageType.FRONT_COVER)
p3 = Page(image=2, type=PageType.OTHER)

assert sorted([p1, p2]) == [p2, p1]
assert p1 == p3
assert len({p1, p2, p3}) == 2


def test_credits_property(comic_info: ComicInfo) -> None:
comic_info.credits = {
"Alice": ["Writer"],
"Bob": ["Inker", "Colorist"],
"Charles": ["Writer", "Inker"],
}

assert comic_info.writer == "Alice,Charles"
assert comic_info.inker == "Bob,Charles"
assert comic_info.colorist == "Bob"


def test_list_fields_mapping(comic_info: ComicInfo) -> None:
comic_info.genre_list = ["Sci-Fi", "Noir"]
comic_info.character_list = ["Alice", "Bob"]
comic_info.team_list = ["Team X"]
comic_info.location_list = ["Gotham"]
comic_info.story_arc_list = ["Arc 1", "Arc 2"]

assert comic_info.genre == "Sci-Fi,Noir"
assert comic_info.characters == "Alice,Bob"
assert comic_info.teams == "Team X"
assert comic_info.locations == "Gotham"
assert comic_info.story_arc == "Arc 1,Arc 2"


def test_get_filename_padding_and_sanitization() -> None:
obj = ComicInfo(
publisher="Example Publisher",
series="Example Series",
volume=1,
number=2,
format="Single Issue",
title="Hello: World / ???",
)
settings = Naming(
seperator="-",
default="{publisher-name}/{series-name}-v{volume}/{series-name}-v{volume}_#{number:02}-{title}",
)
name = obj.get_filename(settings=settings)

assert "#02" in name
assert "Hello-World" in name


def test_xml_bytes_preserves_pages() -> None:
obj = ComicInfo(
series="Series",
number=1,
format="Single Issue",
pages=[
Page(image=1, type=PageType.FRONT_COVER, image_size=123),
Page(image=2, type=PageType.STORY, image_size=456),
],
)
loaded = ComicInfo.from_bytes(content=obj.to_bytes())

assert loaded.series == obj.series
assert len(loaded.pages) == len(obj.pages)
assert loaded.pages[0].image == obj.pages[0].image
assert loaded.pages[0].type == obj.pages[0].type
assert loaded.pages[1].image == obj.pages[1].image
assert loaded.pages[1].type == obj.pages[1].type
86 changes: 86 additions & 0 deletions tests/comic/metadata/metron_info_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from datetime import date, datetime

import pytest

from perdoo.comic.metadata import MetronInfo
from perdoo.comic.metadata.metron_info import (
GTIN,
Credit,
Format,
Id,
InformationSource,
Publisher,
Resource,
Role,
)
from perdoo.settings import Naming


def test_information_source_load_valid() -> None:
assert InformationSource.load(value="Metron") is InformationSource.METRON
assert InformationSource.load(value="Comic Vine") is InformationSource.COMIC_VINE
with pytest.raises(ValueError, match=r"isn't a valid InformationSource"):
InformationSource.load(value="Not Real")


def test_role_load_unknown_fallback() -> None:
assert Role.load(value="Writer") is Role.WRITER
assert Role.load(value="Not Real") is Role.OTHER


def test_ensure_timezone_adds_local_tz(metron_info: MetronInfo) -> None:
naive = datetime(2020, 1, 1, 12, 0, 0) # tzinfo=None
metron_info.last_modified = naive

assert metron_info.last_modified is not None
assert metron_info.last_modified.tzinfo is not None


def test_get_filename_padding_and_sanitization(metron_info: MetronInfo) -> None:
metron_info.number = 2
metron_info.cover_date = date(2021, 7, 4)
metron_info.ids = [
Id(primary=False, source=InformationSource.METRON, value="abc"),
Id(primary=True, source=InformationSource.COMIC_VINE, value="cv-123"),
]
settings = Naming(
seperator="-",
default="{publisher-name}/{series-name}-v{volume}/{series-name}-v{volume}_#{number:03}_{cover-year}_{id}",
)
name = metron_info.get_filename(settings=settings)

assert "#002" in name
assert "2021" in name
assert "cv-123" in name


def test_pattern_map(metron_info: MetronInfo) -> None:
metron_info.publisher = Publisher(name="Pub", imprint=Resource(value="Imprint Name"))
metron_info.gtin = GTIN(isbn="9781234567890", upc="012345678905")
settings = Naming(seperator="-", default="{publisher-name}/{imprint}/{isbn}/{upc}")
name = metron_info.get_filename(settings=settings)

assert "Pub" in name
assert "Imprint-Name" in name
assert "9781234567890" in name
assert "012345678905" in name


def test_xml_bytes_preserved(metron_info: MetronInfo) -> None:
metron_info.credits = [
Credit(
creator=Resource(value="Alice"),
roles=[Resource(value=Role.WRITER), Resource(value=Role.INKER)],
)
]
metron_info.series.format = Format.SINGLE_ISSUE
metron_info.number = 2
loaded = MetronInfo.from_bytes(content=metron_info.to_bytes())

assert loaded.series.name == metron_info.series.name
assert loaded.series.format == metron_info.series.format
assert loaded.number == metron_info.number
assert loaded.credits[0].creator.value == metron_info.credits[0].creator.value
assert {r.value for r in loaded.credits[0].roles} == {
r.value for r in metron_info.credits[0].roles
}
14 changes: 14 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest

from perdoo.comic.metadata import ComicInfo, MetronInfo
from perdoo.comic.metadata.metron_info import Series


@pytest.fixture
def metron_info() -> MetronInfo:
return MetronInfo(series=Series(name="Test Series"))


@pytest.fixture
def comic_info() -> ComicInfo:
return ComicInfo()
Loading