Skip to content

Commit

Permalink
Imprint Support (#61)
Browse files Browse the repository at this point in the history
* Add Imprint schema
* Add Imprint methods
* Add tests for Imprint endpoints
* Update tests for refreshed data
* Add `imprint` field to Issue & Series schemas
  • Loading branch information
bpepple authored Aug 12, 2024
1 parent 83c0f54 commit b6a232e
Show file tree
Hide file tree
Showing 14 changed files with 165 additions and 10 deletions.
20 changes: 20 additions & 0 deletions mokkari/schemas/imprint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Imprint module.
This module provides the following classes:
- Imprint
"""

from mokkari.schemas.generic import GenericItem
from mokkari.schemas.publisher import Publisher


class Imprint(Publisher):
"""A data model representing an imprint that extends Publisher.
Attributes:
publisher (GenericItem): The generic item representing the publisher.
"""

publisher: GenericItem
2 changes: 2 additions & 0 deletions mokkari/schemas/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class Issue(CommonIssue):
Attributes:
publisher (GenericItem): The publisher of the issue.
imprint (GenericItem, optional): The imprint of the issue or None.
series (IssueSeries): The series to which the issue belongs.
collection_title (str): The title of the issue collection.
story_titles (list[str]): The titles of the stories in the issue.
Expand All @@ -133,6 +134,7 @@ class Issue(CommonIssue):
"""

publisher: GenericItem
imprint: GenericItem | None = None
series: IssueSeries
collection_title: str = Field(alias="title")
story_titles: list[str] = Field(alias="name")
Expand Down
2 changes: 2 additions & 0 deletions mokkari/schemas/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Series(CommonSeries):
series_type (GenericItem): The type of the series.
status (str): The status of the series.
publisher (GenericItem): The publisher of the series.
imprint (GenericItem, optional): The imprint of the series or None.
year_end (int, optional): The year the series ended.
desc (str): The description of the series.
genres (list[GenericItem], optional): The genres associated with the series.
Expand All @@ -79,6 +80,7 @@ class Series(CommonSeries):
series_type: GenericItem
status: str
publisher: GenericItem
imprint: GenericItem | None = None
year_end: int | None = None
desc: str
genres: list[GenericItem] = []
Expand Down
43 changes: 43 additions & 0 deletions mokkari/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from mokkari.schemas.character import Character
from mokkari.schemas.creator import Creator
from mokkari.schemas.generic import GenericItem
from mokkari.schemas.imprint import Imprint
from mokkari.schemas.issue import BaseIssue, Issue
from mokkari.schemas.publisher import Publisher
from mokkari.schemas.series import BaseSeries, Series
Expand Down Expand Up @@ -547,6 +548,48 @@ def universes_list(
raise exceptions.ApiError(err) from err
return result

def imprint(self: Session, _id: int) -> Imprint:
"""Retrieves an imprint by ID.
Args:
_id: The ID of the imprint to retrieve.
Returns:
Imprint: The retrieved imprint object.
Raises:
ApiError: If there is an error during the API call or validation.
"""
resp = self._call(["imprint", _id])
adaptor = TypeAdapter(Imprint)
try:
result = adaptor.validate_python(resp)
except ValidationError as error:
raise exceptions.ApiError(error) from error
return result

def imprints_list(
self: Session, params: dict[str, str | int] | None = None
) -> list[BaseResource]:
"""Retrieves a list of imprints based on the provided parameters.
Args:
params: A dictionary containing parameters for filtering imprints (optional).
Returns:
list[BaseResource]: A list of BaseResource objects representing the retrieved imprints.
Raises:
ApiError: If there is an error during the API call or validation.
"""
resp = self._get_results(["imprint"], params)
adapter = TypeAdapter(list[BaseResource])
try:
result = adapter.validate_python(resp["results"])
except ValidationError as err:
raise exceptions.ApiError(err) from err
return result

def _get_results(
self: Session,
endpoint: list[str | int],
Expand Down
2 changes: 1 addition & 1 deletion tests/test_arcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_arcs_list(talker: Session) -> None:
assert next(arc_iter).name == "(She) Drunk History"
assert next(arc_iter).name == "1+2 = Fantastic Three"
assert next(arc_iter).name == "1602"
assert len(arcs) == 1813
assert len(arcs) == 1817
assert arcs[5].name == "1602"


Expand Down
4 changes: 2 additions & 2 deletions tests/test_characters.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ def test_character_list(talker: Session) -> None:
assert next(character_iter).name == "'Mazing Man"
assert next(character_iter).name == "3-D Man (Chandler)"
assert next(character_iter).name == "3-D Man (Garrett)"
assert len(chars) == 975
assert len(chars) == 981
assert chars[2].name == "3-D Man (Garrett)"


def test_character_issue_list(talker: Session) -> None:
"""Test for getting an issue list for an arc."""
issues = talker.character_issues_list(1)
assert len(issues) == 412
assert len(issues) == 415
assert issues[0].id == 258
assert issues[0].issue_name == "Fantastic Four (1961) #45"
assert issues[0].cover_date == date(1965, 12, 1)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_creator_list(talker: Session) -> None:
assert next(creator_iter).name == "Abel Laxamana"
assert next(creator_iter).name == "Adam Freeman"
assert next(creator_iter).name == "Adam Schlagman"
assert len(creators) == 377
assert len(creators) == 379
assert creators[3].name == "Adam Schlagman"


Expand Down
71 changes: 71 additions & 0 deletions tests/test_imprints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Test Imprints module.
This module contains tests for Imprint objects.
"""

import json

import pytest
import requests_mock

from mokkari import exceptions
from mokkari.session import Session


def test_known_imprints(talker: Session) -> None:
"""Test for a known publisher."""
vertigo = talker.imprint(1)
assert vertigo.name == "Vertigo Comics"
assert (
vertigo.image.__str__()
== "https://static.metron.cloud/media/imprint/2024/08/12/vertigo.jpg"
)
assert vertigo.founded == 1993
assert vertigo.publisher.name == "DC Comics"
assert (
vertigo.resource_url.__str__() == "https://metron.cloud/imprint/vertigo-comics/"
)


def test_imprint_list(talker: Session) -> None:
"""Test the ImprintList."""
imprints = talker.imprints_list()
imprints_iter = iter(imprints)
assert next(imprints_iter).name == "DC Black Label"
assert next(imprints_iter).name == "Icon Comics"
assert next(imprints_iter).name == "Vertigo Comics"
assert len(imprints) == 3
assert imprints[2].name == "Vertigo Comics"


def test_bad_imprint(talker: Session) -> None:
"""Test for a non-existent imprint."""
with requests_mock.Mocker() as r:
r.get(
"https://metron.cloud/api/imprint/-1/",
text='{"response_code": 404, "detail": "Not found."}',
)
with pytest.raises(exceptions.ApiError):
talker.imprint(-1)


def test_bad_imprint_validate(talker: Session) -> None:
"""Test data with invalid data."""
# Change the 'name' field to an int, when it should be a string.
data = {
"id": 15,
"name": 150,
"founded": 1993,
"desc": "Foo Bar",
"image": "https://static.metron.cloud/media/imprint/2018/12/02/bongo.png",
"modified": "2019-06-23T15:13:23.581612-04:00",
}

with requests_mock.Mocker() as r:
r.get(
"https://metron.cloud/api/imprint/15/",
text=json.dumps(data),
)

with pytest.raises(exceptions.ApiError):
talker.imprint(15)
10 changes: 10 additions & 0 deletions tests/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,19 @@
from mokkari.session import Session


def test_imprint_issue(talker: Session) -> None:
"""Test issue from an imprint."""
sandman = talker.issue(46182)
assert sandman.imprint.id == 1
assert sandman.imprint.name == "Vertigo Comics"


def test_issue_with_rating(talker: Session) -> None:
"""Test issue with a rating."""
ff = talker.issue(51658)
assert ff.publisher.id == 1
assert ff.publisher.name == "Marvel"
assert ff.imprint is None
assert ff.series.name == "Fantastic Four"
assert ff.series.volume == 7
assert ff.rating.id == 3
Expand Down
2 changes: 1 addition & 1 deletion tests/test_publishers.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def test_publisher_list(talker: Session) -> None:
assert next(publisher_iter).name == "12-Gauge Comics"
assert next(publisher_iter).name == "AAA Pop Comics"
assert next(publisher_iter).name == "AWA Studios"
assert len(publishers) == 110
assert len(publishers) == 107
assert publishers[2].name == "AWA Studios"


Expand Down
9 changes: 8 additions & 1 deletion tests/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
from mokkari.session import Session


def test_series_with_imprint(talker: Session) -> None:
"""Test series from an imprint."""
sandman = talker.series(3315)
assert sandman.imprint.id == 1
assert sandman.imprint.name == "Vertigo Comics"


def test_known_series(talker: Session) -> None:
"""Test for a known series."""
death = talker.series(1)
Expand Down Expand Up @@ -66,7 +73,7 @@ def test_series_list(talker: Session) -> None:
assert next(series_iter).id == 7972
assert next(series_iter).id == 2481
assert next(series_iter).id == 763
assert len(series) == 245
assert len(series) == 247
assert series[3].id == 2481
assert series[3].volume == 1
assert series[3].issue_count == 715
Expand Down
4 changes: 2 additions & 2 deletions tests/test_series_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ def test_series_type_list(talker: Session) -> None:
series_types = talker.series_type_list()
st_iter = iter(series_types)
assert next(st_iter).name == "Annual"
assert next(st_iter).name == "Digital Chapters"
assert series_types[3].name == "Hard Cover"
assert next(st_iter).name == "Digital Chapter"
assert series_types[3].name == "Hardcover"
assert len(series_types) == 9
4 changes: 2 additions & 2 deletions tests/test_teams.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ def test_team_list(talker: Session) -> None:
assert next(team_iter).name == "A-Force"
assert next(team_iter).name == "A-Next"
assert next(team_iter).name == "A.I.M."
assert len(teams) == 1534
assert len(teams) == 1545
assert teams[4].name == "A.I.M."


def test_team_issue_list(talker: Session) -> None:
"""Test for getting an issue list for an arc."""
issues = talker.team_issues_list(1)
assert len(issues) == 618
assert len(issues) == 621
assert issues[0].id == 258
assert issues[0].issue_name == "Fantastic Four (1961) #45"
assert issues[0].cover_date == date(1965, 12, 1)
Expand Down
Binary file modified tests/testing_mock.sqlite
Binary file not shown.

0 comments on commit b6a232e

Please sign in to comment.