from datetime import date from unittest.mock import patch 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, ) def test_search_result_parse(): """Tests the `SearchResult.parse` class method.""" with patch("omdb.result.MovieSearchResult.parse") as mock_parse: SearchResult.parse({"Type": "movie"}) mock_parse.assert_called() with patch("omdb.result.SeriesSearchResult.parse") as mock_parse: SearchResult.parse({"Type": "series"}) mock_parse.assert_called() with pytest.raises(NotImplementedError): SearchResult.parse({"Type": "unknown"}) def test_movie_search_result_parse(): """Tests the `MovieSearchResult.parse` class method.""" result = MovieSearchResult.parse( { "Type": "movie", "imdbID": "tt0000000", "Title": "Title", "Year": "2000", "Poster": "https://example.com/poster.jpg", } ) assert result == MovieSearchResult( imdb_id="tt0000000", title="Title", year=2000, poster=URL("https://example.com/poster.jpg"), ) def test_series_search_result_parse(): """Tests the `SeriesSearchResult.parse` class method.""" result = SeriesSearchResult.parse( { "Type": "series", "imdbID": "tt0000000", "Title": "Title", "Year": "2000–2010", "Poster": "https://example.com/poster.jpg", } ) assert result == SeriesSearchResult( title="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.""" with patch("omdb.result.MovieExtendedResult.parse") as mock_parse: ExtendedResult.parse({"Type": "movie"}) mock_parse.assert_called() with patch("omdb.result.SeriesExtendedResult.parse") as mock_parse: ExtendedResult.parse({"Type": "series"}) mock_parse.assert_called() with pytest.raises(NotImplementedError): 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( { "imdbID": "tt0000000", "Title": "Title", "Year": "2000", "Rated": "R", "Released": "01 Jan 2000", "Genre": "Action, Adventure, Comedy", "Plot": "Plot", "Language": "English, Esperanto", "Country": "United States, Canada", "Poster": "https://example.com/poster.jpg", "Ratings": [{"Source": "Internet Movie Database", "Value": "10.0/10"}], "Runtime": "123 min", "Director": "Alan Smithee", "Writer": "Alan Smithee", "Actors": "Jenna Maroney, Tracy Jordan", } ) assert result == MovieExtendedResult( title="Title", imdb_id="tt0000000", mpaa_rating="R", release_date=date(2000, 1, 1), genres={"Action", "Adventure", "Comedy"}, plot="Plot", language={"English", "Esperanto"}, countries={"United States", "Canada"}, poster=URL("https://example.com/poster.jpg"), ratings=[Rating("imdb", 10.0, 10)], runtime=123, directors={"Alan Smithee"}, writers={"Alan Smithee"}, actors={"Jenna Maroney", "Tracy Jordan"}, ) def test_movie_extended_result_nfo_element(): """Tests the `MovieExtendedResult.nfo_element` method.""" result = MovieExtendedResult( title="Title", imdb_id="tt0000000", mpaa_rating="R", release_date=date(2000, 1, 1), genres={"Action", "Adventure", "Comedy"}, plot="Plot", language={"English", "Esperanto"}, countries={"United States", "Canada"}, poster=URL("https://example.com/poster.jpg"), ratings=[Rating("imdb", 10.0, 10)], runtime=123, directors={"Alan Smithee"}, writers={"Alan Smithee"}, actors={"Jenna Maroney", "Tracy Jordan"}, ) 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) == 2 assert any( actor_element[0].tag == "name" and actor_element[0].text == "Jenna Maroney" for actor_element in actor_elements ) def test_series_extended_result_parse(): """Tests the `SeriesExtendedResult.parse` class method.""" result = SeriesExtendedResult.parse( { "imdbID": "tt0000000", "Title": "Title", "Year": "2000", "Rated": "R", "Released": "01 Jan 2000", "Genre": "Action, Adventure, Comedy", "Plot": "Plot", "Language": "English, Esperanto", "Country": "United States, Canada", "Poster": "https://example.com/poster.jpg", "Ratings": [{"Source": "Internet Movie Database", "Value": "10.0/10"}], "totalSeasons": 10, } ) assert result == SeriesExtendedResult( title="Title", imdb_id="tt0000000", mpaa_rating="R", release_date=date(2000, 1, 1), genres={"Action", "Adventure", "Comedy"}, plot="Plot", language={"English", "Esperanto"}, countries={"United States", "Canada"}, 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( title="Title", imdb_id="tt0000000", mpaa_rating="R", release_date=date(2000, 1, 1), genres={"Action", "Adventure", "Comedy"}, plot="Plot", language={"English", "Esperanto"}, countries={"United States", "Canada"}, poster=URL("https://example.com/poster.jpg"), ratings=[Rating("imdb", 10.0, 10)], total_seasons=10, ) 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"}