Skip to content

Commit

Permalink
update api tests using models
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr-Blank committed Oct 10, 2023
1 parent 8cfcfff commit 80e34b9
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 116 deletions.
109 changes: 20 additions & 89 deletions tests/test_api_with_mock.py
Original file line number Diff line number Diff line change
@@ -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")
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand All @@ -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

Expand All @@ -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:
Expand Down Expand Up @@ -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)
59 changes: 32 additions & 27 deletions tests/test_api_with_vcr.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from datetime import datetime
import pytest
import vcr

Expand All @@ -10,6 +11,13 @@
ServerError,
)

from lrclib.models import (
CryptographicChallenge,
Lyrics,
LyricsMinimal,
SearchResult,
)


@pytest.fixture(scope="module")
def api() -> LrcLibAPI:
Expand All @@ -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(
Expand Down Expand Up @@ -118,4 +123,4 @@ def test_not_found(api: LrcLibAPI) -> None:
"this album does not exist",
233,
cached=False,
)
)

0 comments on commit 80e34b9

Please sign in to comment.