Files
omdb/tests/result_test.py
2024-05-04 23:10:12 -07:00

393 lines
12 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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": "20002010",
"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("20002001") == (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"}