393 lines
12 KiB
Python
393 lines
12 KiB
Python
from datetime import date
|
||
|
||
import pytest
|
||
from httpx import URL
|
||
|
||
from omdb.result import (
|
||
ExtendedResult,
|
||
MovieExtendedResult,
|
||
MovieSearchResult,
|
||
Rating,
|
||
SearchResult,
|
||
SeriesExtendedResult,
|
||
SeriesSearchResult,
|
||
_parse_optional_date,
|
||
_parse_optional_int,
|
||
_parse_optional_minutes,
|
||
_parse_optional_string,
|
||
_parse_optional_url,
|
||
_parse_optional_year_range,
|
||
_parse_rating,
|
||
_parse_string_set,
|
||
)
|
||
|
||
mock_movie_search_result = {
|
||
"Title": "Movie Title",
|
||
"Year": "2000",
|
||
"imdbID": "tt0000000",
|
||
"Type": "movie",
|
||
"Poster": "https://example.com/poster.jpg",
|
||
}
|
||
|
||
mock_series_search_result = {
|
||
"Title": "Series Title",
|
||
"Year": "2000–2010",
|
||
"imdbID": "tt0000000",
|
||
"Type": "series",
|
||
"Poster": "https://example.com/poster.jpg",
|
||
}
|
||
|
||
mock_movie_extended_result = {
|
||
"Type": "movie",
|
||
"Title": "Movie Title",
|
||
"Year": "2000",
|
||
"Rated": "R",
|
||
"Released": "01 Jan 2000",
|
||
"Genre": "Action, Adventure, Comedy",
|
||
"Plot": "Example movie",
|
||
"Language": "English, Esperanto",
|
||
"Country": "United States, Molossia",
|
||
"Poster": "https://example.com/poster.jpg",
|
||
"Ratings": [
|
||
{"Source": "Internet Movie Database", "Value": "10.0/10"},
|
||
],
|
||
"imdbID": "tt0000000",
|
||
"Runtime": "123 min",
|
||
"Director": "Alan Smithee",
|
||
"Writer": "Alan Smithee",
|
||
"Actors": "Jack Nicholson, Robert De Niro, Anthony Hopkins",
|
||
}
|
||
|
||
mock_series_extended_result = {
|
||
"Type": "series",
|
||
"Title": "Series Title",
|
||
"Year": "2000",
|
||
"Rated": "TV-MA",
|
||
"Released": "01 Jan 2000",
|
||
"Genre": "Action, Adventure, Comedy",
|
||
"Plot": "Example series",
|
||
"Language": "English, Esperanto",
|
||
"Country": "United States, Molossia",
|
||
"Poster": "https://example.com/poster.jpg",
|
||
"Ratings": [
|
||
{"Source": "Internet Movie Database", "Value": "10.0/10"},
|
||
],
|
||
"imdbID": "tt0000000",
|
||
"totalSeasons": 10,
|
||
}
|
||
|
||
|
||
def test_search_result_parse():
|
||
"""Tests the `SearchResult.parse` class method."""
|
||
|
||
movie_result = SearchResult.parse(mock_movie_search_result)
|
||
assert movie_result == MovieSearchResult.parse(mock_movie_search_result)
|
||
|
||
series_result = SearchResult.parse(mock_series_search_result)
|
||
assert series_result == SeriesSearchResult.parse(mock_series_search_result)
|
||
|
||
with pytest.raises(
|
||
NotImplementedError,
|
||
match='Result type "unknown" is not supported.',
|
||
):
|
||
SearchResult.parse({"Type": "unknown"})
|
||
|
||
|
||
def test_movie_search_result_parse():
|
||
"""Tests the `MovieSearchResult.parse` class method."""
|
||
|
||
result = MovieSearchResult.parse(mock_movie_search_result)
|
||
assert result == MovieSearchResult(
|
||
title="Movie Title",
|
||
imdb_id="tt0000000",
|
||
poster=URL("https://example.com/poster.jpg"),
|
||
year=2000,
|
||
)
|
||
|
||
|
||
def test_series_search_result_parse():
|
||
"""Tests the `SeriesSearchResult.parse` class method."""
|
||
|
||
result = SeriesSearchResult.parse(mock_series_search_result)
|
||
assert result == SeriesSearchResult(
|
||
title="Series Title",
|
||
imdb_id="tt0000000",
|
||
poster=URL("https://example.com/poster.jpg"),
|
||
year_start=2000,
|
||
year_end=2010,
|
||
)
|
||
|
||
|
||
def test_rating_parse():
|
||
"""Tests the `Rating.parse` class method."""
|
||
|
||
rating = Rating.parse({"Source": "Internet Movie Database", "Value": "50.0/100"})
|
||
assert rating == Rating("imdb", 50.0, 100)
|
||
|
||
with pytest.raises(
|
||
NotImplementedError,
|
||
match='Rating source "Unknown" is not supported.',
|
||
):
|
||
Rating.parse({"Source": "Unknown", "Value": "50%"})
|
||
|
||
|
||
def test_rating_nfo_element():
|
||
"""Tests the `Rating.nfo_element` method."""
|
||
|
||
rating = Rating("imdb", 50.0, 100)
|
||
element = rating.nfo_element()
|
||
assert element.tag == "rating"
|
||
assert element.attrib == {"name": "imdb", "default": "true", "max": "100"}
|
||
assert element[0].tag == "value"
|
||
assert element[0].text == "50.0"
|
||
|
||
rating = Rating("metacritic", 5.0, 10)
|
||
element = rating.nfo_element()
|
||
assert element.tag == "rating"
|
||
assert element.attrib == {"name": "metacritic", "default": "false", "max": "10"}
|
||
assert element[0].tag == "value"
|
||
assert element[0].text == "5.0"
|
||
|
||
|
||
def test_extended_result_parse():
|
||
"""Tests the `ExtendedResult.parse` class method."""
|
||
|
||
movie_result = ExtendedResult.parse(mock_movie_extended_result)
|
||
assert movie_result == MovieExtendedResult.parse(mock_movie_extended_result)
|
||
|
||
series_result = ExtendedResult.parse(mock_series_extended_result)
|
||
assert series_result == SeriesExtendedResult.parse(mock_series_extended_result)
|
||
|
||
with pytest.raises(
|
||
NotImplementedError,
|
||
match='Result type "unknown" is not supported.',
|
||
):
|
||
ExtendedResult.parse({"Type": "unknown"})
|
||
|
||
|
||
def test_extended_result_nfo_subelements():
|
||
"""Tests the `ExtendedResult._nfo_subelements` method."""
|
||
|
||
result = SeriesExtendedResult(
|
||
title="Series title",
|
||
imdb_id="tt0000000",
|
||
mpaa_rating="TV-MA",
|
||
release_date=date(2000, 1, 1),
|
||
genres={"Action", "Adventure", "Comedy"},
|
||
plot="Example series",
|
||
language={"English", "Esperanto"},
|
||
countries={"United States", "Molossia"},
|
||
poster=URL("https://example.com/poster.jpg"),
|
||
ratings=[Rating("imdb", 10.0, 10)],
|
||
total_seasons=0,
|
||
)
|
||
elements = result._nfo_subelements()
|
||
|
||
title_elements = [element for element in elements if element.tag == "title"]
|
||
assert len(title_elements) == 1
|
||
assert title_elements[0].text == "Series title"
|
||
|
||
uniqueid_elements = [element for element in elements if element.tag == "uniqueid"]
|
||
assert len(uniqueid_elements) == 1
|
||
assert uniqueid_elements[0].attrib == {"type": "imdb", "default": "true"}
|
||
assert uniqueid_elements[0].text == "tt0000000"
|
||
|
||
mpaa_elements = [element for element in elements if element.tag == "mpaa"]
|
||
assert len(mpaa_elements) == 1
|
||
assert mpaa_elements[0].text == "TV-MA"
|
||
|
||
premiered_elements = [element for element in elements if element.tag == "premiered"]
|
||
assert len(premiered_elements) == 1
|
||
assert premiered_elements[0].text == "2000-01-01"
|
||
|
||
genre_elements = [element for element in elements if element.tag == "genre"]
|
||
assert len(genre_elements) == 3
|
||
assert any(genre_element.text == "Action" for genre_element in genre_elements)
|
||
|
||
plot_elements = [element for element in elements if element.tag == "plot"]
|
||
assert len(plot_elements) == 1
|
||
assert plot_elements[0].text == "Example series"
|
||
|
||
country_elements = [element for element in elements if element.tag == "country"]
|
||
assert len(country_elements) == 2
|
||
assert any(
|
||
country_element.text == "United States" for country_element in country_elements
|
||
)
|
||
|
||
ratings_elements = [element for element in elements if element.tag == "ratings"]
|
||
assert len(ratings_elements) == 1
|
||
assert len(ratings_elements[0]) == 1
|
||
assert ratings_elements[0][0].tag == "rating"
|
||
assert ratings_elements[0][0].attrib == {
|
||
"name": "imdb",
|
||
"max": "10",
|
||
"default": "true",
|
||
}
|
||
assert ratings_elements[0][0][0].tag == "value"
|
||
assert ratings_elements[0][0][0].text == "10.0"
|
||
|
||
|
||
def test_movie_extended_result_parse():
|
||
"""Tests the `MovieExtendedResult.parse` class method."""
|
||
|
||
result = MovieExtendedResult.parse(mock_movie_extended_result)
|
||
assert result == MovieExtendedResult(
|
||
title="Movie Title",
|
||
imdb_id="tt0000000",
|
||
mpaa_rating="R",
|
||
release_date=date(2000, 1, 1),
|
||
genres={"Action", "Adventure", "Comedy"},
|
||
plot="Example movie",
|
||
language={"English", "Esperanto"},
|
||
countries={"United States", "Molossia"},
|
||
poster=URL("https://example.com/poster.jpg"),
|
||
ratings=[Rating("imdb", 10.0, 10)],
|
||
runtime=123,
|
||
directors={"Alan Smithee"},
|
||
writers={"Alan Smithee"},
|
||
actors={"Jack Nicholson", "Robert De Niro", "Anthony Hopkins"},
|
||
)
|
||
|
||
|
||
def test_movie_extended_result_nfo_element():
|
||
"""Tests the `MovieExtendedResult.nfo_element` method."""
|
||
|
||
result = MovieExtendedResult.parse(mock_movie_extended_result)
|
||
element = result.nfo_element()
|
||
assert element.tag == "movie"
|
||
|
||
for tag in (
|
||
"title",
|
||
"uniqueid",
|
||
"mpaa",
|
||
"premiered",
|
||
"genre",
|
||
"plot",
|
||
"country",
|
||
"ratings",
|
||
):
|
||
assert element.find(tag) is not None
|
||
|
||
runtime_element = element.find("runtime")
|
||
assert runtime_element is not None
|
||
assert runtime_element.text == "123"
|
||
|
||
director_elements = element.findall("director")
|
||
assert len(director_elements) == 1
|
||
assert director_elements[0].text == "Alan Smithee"
|
||
|
||
credits_elements = element.findall("credits")
|
||
assert len(credits_elements) == 1
|
||
assert credits_elements[0].text == "Alan Smithee"
|
||
|
||
actor_elements = element.findall("actor")
|
||
assert len(actor_elements) == 3
|
||
assert any(
|
||
actor_element[0].tag == "name" and actor_element[0].text == "Anthony Hopkins"
|
||
for actor_element in actor_elements
|
||
)
|
||
|
||
|
||
def test_series_extended_result_parse():
|
||
"""Tests the `SeriesExtendedResult.parse` class method."""
|
||
|
||
series_extended_result = SeriesExtendedResult.parse(mock_series_extended_result)
|
||
assert series_extended_result == SeriesExtendedResult(
|
||
title="Series Title",
|
||
imdb_id="tt0000000",
|
||
mpaa_rating="TV-MA",
|
||
release_date=date(2000, 1, 1),
|
||
genres={"Action", "Adventure", "Comedy"},
|
||
plot="Example series",
|
||
language={"English", "Esperanto"},
|
||
countries={"United States", "Molossia"},
|
||
poster=URL("https://example.com/poster.jpg"),
|
||
ratings=[Rating("imdb", 10.0, 10)],
|
||
total_seasons=10,
|
||
)
|
||
|
||
|
||
def test_series_extended_result_nfo():
|
||
"""Tests the `SeriesExtendedResult.nfo_element` method."""
|
||
|
||
result = SeriesExtendedResult.parse(mock_series_extended_result)
|
||
element = result.nfo_element()
|
||
assert element.tag == "tvshow"
|
||
|
||
for tag in (
|
||
"title",
|
||
"uniqueid",
|
||
"mpaa",
|
||
"premiered",
|
||
"genre",
|
||
"plot",
|
||
"country",
|
||
"ratings",
|
||
):
|
||
assert element.find(tag) is not None
|
||
|
||
season_element = element.find("season")
|
||
assert season_element is not None
|
||
assert season_element.text == "10"
|
||
|
||
|
||
def test_parse_optional_string():
|
||
"""Tests the `_parse_optional_string` function."""
|
||
|
||
assert _parse_optional_string("N/A") is None
|
||
assert _parse_optional_string("TV-MA") == "TV-MA"
|
||
|
||
|
||
def test_parse_optional_int():
|
||
"""Tests the `_parse_optional_int` function."""
|
||
|
||
assert _parse_optional_int("N/A") is None
|
||
assert _parse_optional_int("2000") == 2000
|
||
|
||
|
||
def test_parse_optional_url():
|
||
"""Tests the `_parse_optional_url` function."""
|
||
|
||
assert _parse_optional_url("N/A") is None
|
||
assert _parse_optional_url("https://example.com/poster.jpg") == URL(
|
||
"https://example.com/poster.jpg"
|
||
)
|
||
|
||
|
||
def test_parse_optional_date():
|
||
"""Tests the `_parse_optional_date` function."""
|
||
|
||
assert _parse_optional_date("N/A") is None
|
||
assert _parse_optional_date("01 Jan 2000") == date(2000, 1, 1)
|
||
|
||
|
||
def test_parse_optional_minutes():
|
||
"""Tests the `_parse_optional_minutes` function."""
|
||
|
||
assert _parse_optional_minutes("N/A") is None
|
||
assert _parse_optional_minutes("123 min") == 123
|
||
|
||
|
||
def test_parse_optional_year_range():
|
||
"""Tests the `_parse_optional_year_range` function."""
|
||
|
||
assert _parse_optional_year_range("N/A") == (None, None)
|
||
assert _parse_optional_year_range("2000") == (2000, 2000)
|
||
assert _parse_optional_year_range("2000–") == (2000, None)
|
||
assert _parse_optional_year_range("2000–2001") == (2000, 2001)
|
||
|
||
|
||
def test_parse_rating():
|
||
"""Tests the `_parse_rating` function."""
|
||
|
||
assert _parse_rating("50%") == (50.0, 100)
|
||
assert _parse_rating("50/100") == (50.0, 100)
|
||
assert _parse_rating("5.0/10") == (5.0, 10)
|
||
|
||
|
||
def test_parse_string_set():
|
||
"""Tests the `_parse_string_set` function."""
|
||
|
||
assert _parse_string_set("N/A") == set()
|
||
assert _parse_string_set("Foo, Bar, Baz Qux") == {"Foo", "Bar", "Baz Qux"}
|