From 80e34b9fbb5eba2739a54499666c8429512004be Mon Sep 17 00:00:00 2001 From: Dr-Blank <64108942+Dr-Blank@users.noreply.github.com> Date: Tue, 10 Oct 2023 02:35:04 -0400 Subject: [PATCH] update api tests using models --- tests/test_api_with_mock.py | 109 +++++++----------------------------- tests/test_api_with_vcr.py | 59 ++++++++++--------- 2 files changed, 52 insertions(+), 116 deletions(-) diff --git a/tests/test_api_with_mock.py b/tests/test_api_with_mock.py index f3718e9..463f2cf 100644 --- a/tests/test_api_with_mock.py +++ b/tests/test_api_with_mock.py @@ -1,14 +1,23 @@ from unittest.mock import Mock +import warnings import pytest +from requests import HTTPError, Response from lrclib.api import BASE_URL, ENDPOINTS, LrcLibAPI from lrclib.exceptions import ( APIError, + IncorrectPublishTokenError, NotFoundError, RateLimitError, ServerError, ) +from lrclib.models import ( + Lyrics, + LyricsMinimal, + SearchResult, + CryptographicChallenge, +) @pytest.fixture(scope="module") @@ -67,8 +76,8 @@ def test_get_lyrics( }, ) - # Check that the result is the expected dictionary - assert result == sample_response + # Check that the result is the expected + assert result == Lyrics.from_dict(sample_response) def test_get_cached_lyrics(api: LrcLibAPI) -> None: @@ -102,8 +111,7 @@ def test_get_cached_lyrics(api: LrcLibAPI) -> None: }, ) - # Check that the result is the expected dictionary - assert result == {"lyrics": "test lyrics"} + assert result == Lyrics.from_dict({"lyrics": "test lyrics"}) def test_get_lyrics_by_id(api: LrcLibAPI) -> None: @@ -124,16 +132,14 @@ def test_get_lyrics_by_id(api: LrcLibAPI) -> None: "GET", BASE_URL + ENDPOINTS["get_by_id"].format(id=123) ) - # Check that the result is the expected dictionary - assert result == {"lyrics": "test lyrics"} + assert result == Lyrics.from_dict({"lyrics": "test lyrics"}) def test_search_lyrics(api: LrcLibAPI) -> None: # Mock the requests.Session object session_mock = Mock() - session_mock.request.return_value.json.return_value = [ - {"lyrics": "test lyrics"} - ] + test_lyrics = {"lyrics": "test lyrics"} + session_mock.request.return_value.json.return_value = [test_lyrics] # Set the session object of the LrcLibAPI instance to the mock object api.session = session_mock @@ -146,18 +152,19 @@ def test_search_lyrics(api: LrcLibAPI) -> None: "GET", BASE_URL + ENDPOINTS["search"], params={"q": "test_query"} ) - # Check that the result is the expected list - assert result == [{"lyrics": "test lyrics"}] + assert result == SearchResult([LyricsMinimal.from_dict(test_lyrics)]) def test_request_challenge(api: LrcLibAPI) -> None: # Mock the requests.Session object session_mock = Mock() - session_mock.request.return_value.json.return_value = { + sample_return = { "prefix": "test_prefix", "target": "test_target", } + session_mock.request.return_value.json.return_value = sample_return + # Set the session object of the LrcLibAPI instance to the mock object api.session = session_mock @@ -169,8 +176,7 @@ def test_request_challenge(api: LrcLibAPI) -> None: "POST", BASE_URL + ENDPOINTS["request_challenge"] ) - # Check that the result is the expected dictionary - assert result == {"prefix": "test_prefix", "target": "test_target"} + assert result == CryptographicChallenge.from_dict(sample_return) def test_publish_lyrics(api: LrcLibAPI) -> None: @@ -216,78 +222,3 @@ def test_publish_lyrics(api: LrcLibAPI) -> None: # Check that the result is the expected dictionary assert result == {"status": "success"} - - -def test_not_found_error(api: LrcLibAPI) -> None: - # Mock the requests.Session object - session_mock = Mock() - session_mock.request.side_effect = NotFoundError(Mock(status_code=404)) - - # Set the session object of the LrcLibAPI instance to the mock object - api.session = session_mock - - # Call the get_lyrics method and check that it raises a NotFoundError - with pytest.raises(NotFoundError): - api.get_lyrics( - "test_track_name", "test_artist_name", "test_album_name", 180 - ) - - -def test_rate_limit_error(api: LrcLibAPI) -> None: - # Mock the requests.Session object - session_mock = Mock() - session_mock.request.side_effect = RateLimitError(Mock(status_code=429)) - - # Set the session object of the LrcLibAPI instance to the mock object - api.session = session_mock - - # Call the search_lyrics method and check that it raises a RateLimitError - with pytest.raises(RateLimitError): - api.search_lyrics(query="test_query") - - -def test_server_error(api: LrcLibAPI) -> None: - # Mock the requests.Session object - session_mock = Mock() - session_mock.request.side_effect = ServerError(Mock(status_code=500)) - - # Set the session object of the LrcLibAPI instance to the mock object - api.session = session_mock - - # Call the get_lyrics_by_id method and check that it raises a ServerError - with pytest.raises(ServerError): - api.get_lyrics_by_id(123) - - -# def test_incorrect_publish_token_error(api: LrcLibAPI) -> None: -# # Mock the requests.Session object -# session_mock = Mock() -# session_mock.request.side_effect = APIError(Mock(status_code=400)) - -# # Set the session object of the LrcLibAPI instance to the mock object -# api.session = session_mock - -# # Call the publish_lyrics method and check that it raises an IncorrectPublishTokenError -# with pytest.raises(IncorrectPublishTokenError): -# api.publish_lyrics( -# "test_track_name", -# "test_artist_name", -# "test_album_name", -# 180, -# plain_lyrics="test_plain_lyrics", -# synced_lyrics="test_synced_lyrics", -# publish_token="incorrect_publish_token" -# ) - - -def test_api_error(api: LrcLibAPI) -> None: - # Mock the requests.Session object - session_mock = Mock() - session_mock.request.side_effect = APIError(Mock(status_code=401)) - - # Set the session object of the LrcLibAPI instance to the mock object - api.session = session_mock - - # Call the request_challenge method and check that it raises an APIError - with pytest.raises(APIError): - api.get_lyrics_by_id(123) diff --git a/tests/test_api_with_vcr.py b/tests/test_api_with_vcr.py index c599694..3214e1a 100644 --- a/tests/test_api_with_vcr.py +++ b/tests/test_api_with_vcr.py @@ -1,3 +1,4 @@ +from datetime import datetime import pytest import vcr @@ -10,6 +11,13 @@ ServerError, ) +from lrclib.models import ( + CryptographicChallenge, + Lyrics, + LyricsMinimal, + SearchResult, +) + @pytest.fixture(scope="module") def api() -> LrcLibAPI: @@ -36,45 +44,42 @@ def api() -> LrcLibAPI: "spotifyId": "5Y94QNZmNoHid18Y7c5Al9", "releaseDate": "2023-08-10T00:00:00Z", "plainLyrics": ( - "I feel your breath upon my neck\n...The clock won't stop and this" - " is what we get\n" + "I feel your breath upon my neck\nA soft caress as cold as death\n" ), "syncedLyrics": ( - "[00:17.12] I feel your breath upon my neck\n...[03:20.31] The" - " clock won't stop and this is what we get\n[03:25.72] " + "[00:17.12] I feel your breath upon my neck\n[00:20.41] A soft caress" + " as cold as death\n" ), } -expected_search_keys = [ - "id", - "trackName", - "artistName", - "albumName", - "duration", - "instrumental", - "plainLyrics", - "syncedLyrics", -] - -def is_valid_search_result(result: list) -> bool: +def is_valid_search_result(result: SearchResult) -> bool: return ( - isinstance(result, list) + isinstance(result, SearchResult) and len(result) > 0 - and all(isinstance(item, dict) for item in result) - and all(key in result[0] for key in expected_search_keys) - and all(result[0][key] is not None for key in expected_search_keys) + and all(isinstance(item, LyricsMinimal) for item in result) ) - -def is_valid_get_result(result: dict) -> bool: +def is_valid_get_result(result: Lyrics) -> bool: return ( - isinstance(result, dict) - and all(key in result for key in expected_content) - and all(result[key] is not None for key in expected_content) + isinstance(result, Lyrics) + and result.name == expected_content["name"] + and result.track_name == expected_content["trackName"] + and result.artist_name == expected_content["artistName"] + and result.album_name == expected_content["albumName"] + and result.duration == expected_content["duration"] + and result.instrumental == expected_content["instrumental"] + and result.plain_lyrics.startswith(expected_content["plainLyrics"]) + and result.synced_lyrics.startswith(expected_content["syncedLyrics"]) + and result.lang == expected_content["lang"] + and result.isrc == expected_content["isrc"] + and result.spotify_id == expected_content["spotifyId"] + and isinstance(result.release_date, datetime) + and result.release_date == datetime.fromisoformat( + expected_content["releaseDate"] + ) ) - @my_vcr.use_cassette() def test_get_lyrics(api: LrcLibAPI) -> None: result = api.get_lyrics( @@ -118,4 +123,4 @@ def test_not_found(api: LrcLibAPI) -> None: "this album does not exist", 233, cached=False, - ) \ No newline at end of file + )