Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test/rewrite test suite #138

Merged
merged 47 commits into from
Mar 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
4dcd418
test: add new types to library response.
2e0byo Sep 2, 2023
d57edd8
test: xfail broken.
2e0byo Sep 2, 2023
3a780d3
chore: dump markers for old python versions.
2e0byo Sep 2, 2023
1dd8314
refactor(tests/library): separate fixtures.
2e0byo Sep 2, 2023
816cd8c
chore: drop references to 'new_api' now v6 is history.
2e0byo Sep 2, 2023
78b4d81
refactor: we should return set, not list.
2e0byo Sep 2, 2023
f48aaf8
chore: marks for test quality.
2e0byo Sep 3, 2023
7ccf298
refactor: make tests an executable spec, not a regression suite.
2e0byo Sep 3, 2023
19e93e1
refactor: neater selection logic using if.
2e0byo Mar 1, 2024
08d74a2
fix: correct missing album handling and refactor tests.
2e0byo Sep 3, 2023
d47470a
chore: be kind to old pythons.
2e0byo Sep 3, 2023
57ec6da
refactor: use logger.exception (logs traceback) over logger.error.
2e0byo Sep 3, 2023
667db32
fix: handle missing types correctly.
2e0byo Sep 3, 2023
27c9a1f
refactor: break out setting attributes on mocks.
2e0byo Jan 13, 2024
05ab3b8
chore: xfail test for now.
2e0byo Jan 13, 2024
1a62c58
refactor: cleanup.
2e0byo Jan 13, 2024
c97d073
test: track uri resolves to album images.
2e0byo Jan 13, 2024
d1e95d7
test: get distinct.
2e0byo Jan 13, 2024
014db27
test: search.
2e0byo Jan 13, 2024
6dab8a8
test: new tests for lookup.
2e0byo Jan 13, 2024
73c5461
test: rewrite search key tests.
2e0byo Jan 27, 2024
77d1fd2
test(login hack): refactor repeated asserts.
2e0byo Feb 3, 2024
d9860d5
test: refactor into class.
2e0byo Feb 3, 2024
dcc8d63
refactor(factories): add more attrs.
2e0byo Feb 3, 2024
b4592bc
test: full models mappers.
2e0byo Feb 3, 2024
fc7df2e
test: rename context tests.
2e0byo Feb 3, 2024
24e9148
test: finish test_extension.
2e0byo Feb 3, 2024
7d53a09
test: rewrite login hack tests.
2e0byo Feb 3, 2024
3a9505a
test: lru cache.
2e0byo Feb 3, 2024
6e8436e
chore: rename test.
2e0byo Feb 3, 2024
c78a3c0
chore: rename test module.
2e0byo Feb 3, 2024
e5addc6
test: watermarks.
2e0byo Feb 3, 2024
c325520
refactor: uri schemes shouldn't be mutable.
2e0byo Feb 3, 2024
afd697b
chore: fixup backend tests.
2e0byo Feb 3, 2024
cb3d3b0
chore: rename test.
2e0byo Feb 3, 2024
6f381e2
refactor: rename variable.
2e0byo Feb 3, 2024
d11d89f
tests: make config autouse.
2e0byo Feb 3, 2024
408a061
test: search cache.
2e0byo Feb 3, 2024
fd7a9c8
test: explain reason for failure.
2e0byo Feb 3, 2024
feb3e3b
fix: set new mock property.
2e0byo Feb 3, 2024
cbe4dc0
chore: keep compatible with 3.9.
2e0byo Feb 3, 2024
d8880a3
deps: add tidalapi from git (for now).
2e0byo Mar 1, 2024
a7dcfc5
chore: mixes is now my mixes.
2e0byo Mar 1, 2024
b003890
test: add new root entries.
2e0byo Mar 1, 2024
1eaf1f8
test: add new config items.
2e0byo Mar 1, 2024
5caeca6
test: add new keys.
2e0byo Mar 1, 2024
dee7c26
test: fixup login test.
2e0byo Mar 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mopidy_tidal/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def __init__(self, config, audio):
# Session parameters
self._active_session: Optional[Session] = None
self._logged_in: bool = False
self.uri_schemes: [str] = ["tidal"]
self.uri_schemes: tuple[str] = ("tidal",)
self._login_future: Optional[Future] = None
self._login_url: Optional[str] = None
self.data_dir: Path = Path(Extension.get_data_dir(self._config))
Expand Down
134 changes: 70 additions & 64 deletions mopidy_tidal/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import logging
from concurrent.futures import ThreadPoolExecutor
from contextlib import suppress
from typing import TYPE_CHECKING, List, Optional, Tuple, Union

from mopidy import backend, models
Expand Down Expand Up @@ -162,38 +163,38 @@ def get_distinct(self, field, query=None) -> set[str]:

if not query: # library root
if field in {"artist", "albumartist"}:
return [
return {
apply_watermark(a.name) for a in session.user.favorites.artists()
]
}
elif field == "album":
return [
return {
apply_watermark(a.name) for a in session.user.favorites.albums()
]
}
elif field in {"track", "track_name"}:
return [
return {
apply_watermark(t.name) for t in session.user.favorites.tracks()
]
}
else:
if field == "artist":
return [
return {
apply_watermark(a.name) for a in session.user.favorites.artists()
]
}
elif field in {"album", "albumartist"}:
artists, _, _ = tidal_search(session, query=query, exact=True)
if len(artists) > 0:
artist = artists[0]
artist_id = artist.uri.split(":")[2]
return [
return {
apply_watermark(a.name)
for a in self._get_artist_albums(session, artist_id)
]
}
elif field in {"track", "track_name"}:
return [
return {
apply_watermark(t.name) for t in session.user.favorites.tracks()
]
}
pass

return []
return set()

@login_hack
def browse(self, uri) -> list[Ref]:
Expand Down Expand Up @@ -245,59 +246,64 @@ def browse(self, uri) -> list[Ref]:
elif uri == "tidal:genres":
return ref_models_mappers.create_genres(session.genre.get_genres())

# details
parts = uri.split(":")
nr_of_parts = len(parts)

if nr_of_parts == 3 and parts[1] == "album":
return ref_models_mappers.create_tracks(
self._get_album_tracks(session, parts[2])
)

if nr_of_parts == 3 and parts[1] == "artist":
top_10_tracks = ref_models_mappers.create_tracks(
self._get_artist_top_tracks(session, parts[2])[:10]
)

albums = ref_models_mappers.create_albums(
self._get_artist_albums(session, parts[2])
)

return albums + top_10_tracks

if nr_of_parts == 3 and parts[1] == "playlist":
return ref_models_mappers.create_tracks(
self._get_playlist_tracks(session, parts[2])
)

if nr_of_parts == 3 and parts[1] == "mood":
return ref_models_mappers.create_playlists(
self._get_mood_items(session, parts[2])
)

if nr_of_parts == 3 and parts[1] == "genre":
return ref_models_mappers.create_playlists(
self._get_genre_items(session, parts[2])
)

if nr_of_parts == 3 and parts[1] == "mix":
return ref_models_mappers.create_tracks(
self._get_mix_tracks(session, parts[2])
)

if nr_of_parts == 3 and parts[1] == "page":
# User page (eg. page:for_you, page:home etc)
return ref_models_mappers.create_mixed_directory(session.page.get(parts[2]))

if nr_of_parts == 4 and parts[2] == "category":
# Category nested on a page (eg. page(For You).category[0..n])
category = session.page.get("pages/{}".format(parts[1])).categories[
int(parts[3])
]
# Category nested on a page (eg. page(For You).category[0..n])
# These have 3-part uris
with suppress(ValueError):
_, page_id, type, category_id = uri.split(":")
category = session.page.get(f"pages/{page_id}").categories[int(category_id)]
return ref_models_mappers.create_mixed_directory(category.items)

logger.info("Unknown uri for browse request: %s", uri)
return []
# details with 2-part uris
try:
_, type, id = uri.split(":")

if type == "album":
return ref_models_mappers.create_tracks(
self._get_album_tracks(session, id)
)

elif type == "artist":
top_10_tracks = ref_models_mappers.create_tracks(
self._get_artist_top_tracks(session, id)[:10]
)

albums = ref_models_mappers.create_albums(
self._get_artist_albums(session, id)
)

return albums + top_10_tracks

elif type == "playlist":
return ref_models_mappers.create_tracks(
self._get_playlist_tracks(session, id)
)

elif type == "mood":
return ref_models_mappers.create_playlists(
self._get_mood_items(session, id)
)

elif type == "genre":
return ref_models_mappers.create_playlists(
self._get_genre_items(session, id)
)

elif type == "mix":
return ref_models_mappers.create_tracks(
self._get_mix_tracks(session, id)
)

elif type == "page":
return ref_models_mappers.create_mixed_directory(session.page.get(id))
else:
return []

except ValueError:
logger.exception("Unable to parse uri '%s' for browse.", uri)
return []
except HTTPError:
logger.exception("Unable to retrieve object from uri '%s'", uri)
return []

@login_hack
def search(self, query=None, uris=None, exact=False) -> Optional[SearchResult]:
Expand Down
6 changes: 3 additions & 3 deletions mopidy_tidal/lru_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ def _check_limit(self):


class SearchCache(LruCache):
def __init__(self, func):
def __init__(self, search_function):
super().__init__(persist=False)
self._func = func
self._search_function = search_function

def __call__(self, *args, **kwargs):
key = str(SearchKey(**kwargs))
Expand All @@ -165,7 +165,7 @@ def __call__(self, *args, **kwargs):
"Search cache miss" if cached_result is None else "Search cache hit"
)
if cached_result is None:
cached_result = self._func(*args, **kwargs)
cached_result = self._search_function(*args, **kwargs)
self[key] = cached_result

return cached_result
Expand Down
73 changes: 58 additions & 15 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ classifiers = [
[tool.poetry.dependencies]
python = "^3.9"
Mopidy = "^3.0"
tidalapi = "^0.7.3"
tidalapi = {git = "https://github.com/tamland/python-tidal"}

[tool.poetry.group.dev.dependencies]
pytest = "^7.3.1"
Expand Down Expand Up @@ -50,10 +50,9 @@ tidal = "mopidy_tidal:Extension"

[tool.pytest.ini_options]
markers = [
"gt_3_7: Mark a test as requiring python > 3.7.",
"gt_3_8: Mark a test as requiring python > 3.8.",
"gt_3_9: Mark a test as requiring python > 3.9.",
"gt_3_10: Mark a test as requiring python > 3.10.",
"poor_test: Mark a test in need of improvement",
"insufficiently_decoupled: Mark a test as insufficiently decoupled from implementation",
]
filterwarnings = [
"error::DeprecationWarning:mopidy[.*]",
Expand Down
Loading
Loading