Add tests for theme mixin (#897)

* Add lockTheme and unlockTheme methods

* Change setTheme to raise NotImplementedError

* Add tests for theme mixins
This commit is contained in:
JonnyWong16 2022-02-26 21:05:43 -08:00 committed by GitHub
parent caf3910057
commit a568819e1e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 241 additions and 152 deletions

View file

@ -244,12 +244,18 @@ class ThemeMixin(ThemeUrlMixin):
self._server.query(key, method=self._server._session.post, data=data)
def setTheme(self, theme):
""" Set the theme for a Plex object.
raise NotImplementedError(
'Themes cannot be set through the API. '
'Re-upload the theme using "uploadTheme" to set it.'
)
Parameters:
theme (:class:`~plexapi.media.Theme`): The theme object to select.
"""
theme.select()
def lockTheme(self):
""" Lock the theme for a Plex object. """
self._edit(**{'theme.locked': 1})
def unlockTheme(self):
""" Unlock the theme for a Plex object. """
self._edit(**{'theme.locked': 0})
class RatingMixin(object):

View file

@ -32,6 +32,7 @@ def test_audio_Artist_attr(artist):
assert isinstance(artist.similar, list)
if artist.summary:
assert "Alias" in artist.summary
assert artist.theme is None
if artist.thumb:
assert utils.is_thumb(artist.thumb)
assert artist.title == "Broke For Free"
@ -95,6 +96,10 @@ def test_audio_Artist_mixins_images(artist):
test_mixins.attr_posterUrl(artist)
def test_audio_Artist_mixins_themes(artist):
test_mixins.edit_theme(artist)
def test_audio_Artist_mixins_rating(artist):
test_mixins.edit_rating(artist)
@ -143,6 +148,7 @@ def test_audio_Album_attrs(album):
assert utils.is_datetime(album.originallyAvailableAt)
assert utils.is_metadata(album.parentKey)
assert utils.is_int(album.parentRatingKey)
assert album.parentTheme is None or utils.is_metadata(album.parentTheme)
if album.parentThumb:
assert utils.is_thumb(album.parentThumb)
assert album.parentTitle == "Broke For Free"
@ -206,6 +212,10 @@ def test_audio_Album_mixins_images(album):
test_mixins.attr_posterUrl(album)
def test_audio_Album_mixins_themes(album):
test_mixins.attr_themeUrl(album)
def test_audio_Album_mixins_rating(album):
test_mixins.edit_rating(album)
@ -246,6 +256,7 @@ def test_audio_Track_attrs(album):
assert utils.is_art(track.grandparentArt)
assert utils.is_metadata(track.grandparentKey)
assert utils.is_int(track.grandparentRatingKey)
assert track.grandparentTheme is None or utils.is_metadata(track.grandparentTheme)
if track.grandparentThumb:
assert utils.is_thumb(track.grandparentThumb)
assert track.grandparentTitle == "Broke For Free"
@ -363,6 +374,10 @@ def test_audio_Track_mixins_images(track):
test_mixins.attr_posterUrl(track)
def test_audio_Track_mixins_themes(track):
test_mixins.attr_themeUrl(track)
def test_audio_Track_mixins_rating(track):
test_mixins.edit_rating(track)

View file

@ -33,6 +33,7 @@ def test_Collection_attrs(collection):
assert collection.smart is False
assert collection.subtype == "movie"
assert collection.summary == ""
assert collection.theme is None
assert collection.thumb.startswith("/library/collections/%s/composite" % collection.ratingKey)
assert collection.thumbBlurHash is None
assert collection.title == "Test Collection"
@ -282,6 +283,10 @@ def test_Collection_mixins_images(collection):
test_mixins.attr_posterUrl(collection)
def test_Collection_mixins_themes(collection):
test_mixins.edit_theme(collection)
def test_Collection_mixins_rating(collection):
test_mixins.edit_rating(collection)

View file

@ -7,6 +7,7 @@ from . import conftest as utils
TEST_MIXIN_TAG = "Test Tag"
CUTE_CAT_SHA1 = "9f7003fc401761d8e0b0364d428b2dab2f789dbb"
AUDIO_STUB_SHA1 = "1abc20d5fdc904201bf8988ca6ef30f96bb73617"
def _test_mixins_tag(obj, attr, tag_method):
@ -180,6 +181,48 @@ def attr_posterUrl(obj):
_test_mixins_imageUrl(obj, "thumb")
def _test_mixins_edit_theme(obj):
_fields = lambda: [f.name for f in obj.fields]
# Test upload theme from file
obj.uploadTheme(filepath=utils.STUB_MP3_PATH)
themes = obj.themes()
file_theme = [
t for t in themes
if t.ratingKey.startswith("upload://") and t.ratingKey.endswith(AUDIO_STUB_SHA1)
]
assert file_theme
obj.reload()
assert "theme" in _fields()
# Unlock the theme
obj.unlockTheme()
obj.reload()
assert "theme" not in _fields()
# Lock the theme
obj.lockTheme()
obj.reload()
assert "theme" in _fields()
with pytest.raises(NotImplementedError):
obj.setTheme(themes[0])
def edit_theme(obj):
_test_mixins_edit_theme(obj)
def _test_mixins_themeUrl(obj):
url = obj.themeUrl
if url:
assert url.startswith(utils.SERVER_BASEURL)
assert "/library/metadata/" in url
assert "theme" in url
else:
assert url is None
def attr_themeUrl(obj):
_test_mixins_themeUrl(obj)
def _test_mixins_editAdvanced(obj):
for pref in obj.preferences():
currentPref = obj.preference(pref.id)

View file

@ -40,153 +40,6 @@ def test_video_Movie_merge(movie, patched_http_call):
movie.merge(1337)
def test_video_Movie_mixins_edit_advanced_settings(movie):
test_mixins.edit_advanced_settings(movie)
@pytest.mark.xfail(reason="Changing images fails randomly")
def test_video_Movie_mixins_images(movie):
test_mixins.lock_art(movie)
test_mixins.lock_poster(movie)
test_mixins.edit_art(movie)
test_mixins.edit_poster(movie)
def test_video_Movie_mixins_rating(movie):
test_mixins.edit_rating(movie)
def test_video_Movie_mixins_tags(movie):
test_mixins.edit_collection(movie)
test_mixins.edit_country(movie)
test_mixins.edit_director(movie)
test_mixins.edit_genre(movie)
test_mixins.edit_label(movie)
test_mixins.edit_producer(movie)
test_mixins.edit_writer(movie)
def test_video_Movie_media_tags(movie):
movie.reload()
test_media.tag_collection(movie)
test_media.tag_country(movie)
test_media.tag_director(movie)
test_media.tag_genre(movie)
test_media.tag_label(movie)
test_media.tag_producer(movie)
test_media.tag_role(movie)
test_media.tag_similar(movie)
test_media.tag_writer(movie)
def test_video_Movie_media_tags_Exception(movie):
with pytest.raises(BadRequest):
movie.genres[0].items()
def test_video_Movie_media_tags_collection(movie, collection):
movie.reload()
collection_tag = next(c for c in movie.collections if c.tag == "Test Collection")
assert collection == collection_tag.collection()
def test_video_Movie_getStreamURL(movie, account):
key = movie.ratingKey
assert movie.getStreamURL() == (
"{0}/video/:/transcode/universal/start.m3u8?"
"X-Plex-Platform=Chrome&copyts=1&mediaIndex=0&"
"offset=0&path=%2Flibrary%2Fmetadata%2F{1}&X-Plex-Token={2}").format(
utils.SERVER_BASEURL, key, account.authenticationToken
) # noqa
assert movie.getStreamURL(
videoResolution="800x600"
) == ("{0}/video/:/transcode/universal/start.m3u8?"
"X-Plex-Platform=Chrome&copyts=1&mediaIndex=0&"
"offset=0&path=%2Flibrary%2Fmetadata%2F{1}&videoResolution=800x600&X-Plex-Token={2}").format(
utils.SERVER_BASEURL, key, account.authenticationToken
) # noqa
def test_video_Movie_isFullObject_and_reload(plex):
movie = plex.library.section("Movies").get("Sita Sings the Blues")
assert movie.isFullObject() is False
movie.reload(checkFiles=False)
assert movie.isFullObject() is False
movie.reload()
assert movie.isFullObject() is True
movie_via_search = plex.library.search(movie.title)[0]
assert movie_via_search.isFullObject() is False
movie_via_search.reload()
assert movie_via_search.isFullObject() is True
movie_via_section_search = plex.library.section("Movies").search(movie.title)[0]
assert movie_via_section_search.isFullObject() is False
movie_via_section_search.reload()
assert movie_via_section_search.isFullObject() is True
# If the verify that the object has been reloaded. xml from search only returns 3 actors.
assert len(movie_via_section_search.roles) >= 3
def test_video_Movie_isPartialObject(movie):
assert movie.isPartialObject()
def test_video_Movie_media_delete(movie, patched_http_call):
for media in movie.media:
media.delete()
def test_video_Movie_iterParts(movie):
assert len(list(movie.iterParts())) >= 1
def test_video_Movie_download(monkeydownload, tmpdir, movie):
filepaths = movie.download(savepath=str(tmpdir))
assert len(filepaths) == 1
with_resolution = movie.download(
savepath=str(tmpdir), keep_original_filename=True, videoResolution="500x300"
)
assert len(with_resolution) == 1
filename = os.path.basename(movie.media[0].parts[0].file)
assert filename in with_resolution[0]
def test_video_Movie_subtitlestreams(movie):
assert not movie.subtitleStreams()
def test_video_Episode_subtitlestreams(episode):
assert not episode.subtitleStreams()
def test_video_Movie_upload_select_remove_subtitle(movie, subtitle):
filepath = os.path.realpath(subtitle.name)
movie.uploadSubtitles(filepath)
movie.reload()
subtitles = [sub.title for sub in movie.subtitleStreams()]
subname = subtitle.name.rsplit(".", 1)[0]
assert subname in subtitles
subtitleSelection = movie.subtitleStreams()[0]
parts = list(movie.iterParts())
parts[0].setDefaultSubtitleStream(subtitleSelection)
movie.reload()
subtitleSelection = movie.subtitleStreams()[0]
assert subtitleSelection.selected
movie.removeSubtitles(streamTitle=subname)
movie.reload()
subtitles = [sub.title for sub in movie.subtitleStreams()]
assert subname not in subtitles
try:
os.remove(filepath)
except:
pass
def test_video_Movie_attrs(movies):
movie = movies.get("Sita Sings the Blues")
assert len(movie.locations) == 1
@ -238,6 +91,7 @@ def test_video_Movie_attrs(movies):
assert movie.studio == "Nina Paley"
assert utils.is_string(movie.summary, gte=100)
assert movie.tagline == "The Greatest Break-Up Story Ever Told"
assert movie.theme is None
if movie.thumb:
assert utils.is_thumb(movie.thumb)
assert movie.title == "Sita Sings the Blues"
@ -436,6 +290,114 @@ def test_video_Movie_attrs(movies):
assert stream2.type == 2
def test_video_Movie_media_tags_Exception(movie):
with pytest.raises(BadRequest):
movie.genres[0].items()
def test_video_Movie_media_tags_collection(movie, collection):
movie.reload()
collection_tag = next(c for c in movie.collections if c.tag == "Test Collection")
assert collection == collection_tag.collection()
def test_video_Movie_getStreamURL(movie, account):
key = movie.ratingKey
assert movie.getStreamURL() == (
"{0}/video/:/transcode/universal/start.m3u8?"
"X-Plex-Platform=Chrome&copyts=1&mediaIndex=0&"
"offset=0&path=%2Flibrary%2Fmetadata%2F{1}&X-Plex-Token={2}").format(
utils.SERVER_BASEURL, key, account.authenticationToken
) # noqa
assert movie.getStreamURL(
videoResolution="800x600"
) == ("{0}/video/:/transcode/universal/start.m3u8?"
"X-Plex-Platform=Chrome&copyts=1&mediaIndex=0&"
"offset=0&path=%2Flibrary%2Fmetadata%2F{1}&videoResolution=800x600&X-Plex-Token={2}").format(
utils.SERVER_BASEURL, key, account.authenticationToken
) # noqa
def test_video_Movie_isFullObject_and_reload(plex):
movie = plex.library.section("Movies").get("Sita Sings the Blues")
assert movie.isFullObject() is False
movie.reload(checkFiles=False)
assert movie.isFullObject() is False
movie.reload()
assert movie.isFullObject() is True
movie_via_search = plex.library.search(movie.title)[0]
assert movie_via_search.isFullObject() is False
movie_via_search.reload()
assert movie_via_search.isFullObject() is True
movie_via_section_search = plex.library.section("Movies").search(movie.title)[0]
assert movie_via_section_search.isFullObject() is False
movie_via_section_search.reload()
assert movie_via_section_search.isFullObject() is True
# If the verify that the object has been reloaded. xml from search only returns 3 actors.
assert len(movie_via_section_search.roles) >= 3
def test_video_Movie_isPartialObject(movie):
assert movie.isPartialObject()
def test_video_Movie_media_delete(movie, patched_http_call):
for media in movie.media:
media.delete()
def test_video_Movie_iterParts(movie):
assert len(list(movie.iterParts())) >= 1
def test_video_Movie_download(monkeydownload, tmpdir, movie):
filepaths = movie.download(savepath=str(tmpdir))
assert len(filepaths) == 1
with_resolution = movie.download(
savepath=str(tmpdir), keep_original_filename=True, videoResolution="500x300"
)
assert len(with_resolution) == 1
filename = os.path.basename(movie.media[0].parts[0].file)
assert filename in with_resolution[0]
def test_video_Movie_subtitlestreams(movie):
assert not movie.subtitleStreams()
def test_video_Episode_subtitlestreams(episode):
assert not episode.subtitleStreams()
def test_video_Movie_upload_select_remove_subtitle(movie, subtitle):
filepath = os.path.realpath(subtitle.name)
movie.uploadSubtitles(filepath)
movie.reload()
subtitles = [sub.title for sub in movie.subtitleStreams()]
subname = subtitle.name.rsplit(".", 1)[0]
assert subname in subtitles
subtitleSelection = movie.subtitleStreams()[0]
parts = list(movie.iterParts())
parts[0].setDefaultSubtitleStream(subtitleSelection)
movie.reload()
subtitleSelection = movie.subtitleStreams()[0]
assert subtitleSelection.selected
movie.removeSubtitles(streamTitle=subname)
movie.reload()
subtitles = [sub.title for sub in movie.subtitleStreams()]
assert subname not in subtitles
try:
os.remove(filepath)
except:
pass
def test_video_Movie_history(movie):
movie.markWatched()
history = movie.history()
@ -611,6 +573,50 @@ def test_video_Movie_extras(movies):
assert extra.type == 'clip'
assert extra.section() == movies
def test_video_Movie_mixins_edit_advanced_settings(movie):
test_mixins.edit_advanced_settings(movie)
@pytest.mark.xfail(reason="Changing images fails randomly")
def test_video_Movie_mixins_images(movie):
test_mixins.lock_art(movie)
test_mixins.lock_poster(movie)
test_mixins.edit_art(movie)
test_mixins.edit_poster(movie)
def test_video_Movie_mixins_themes(movie):
test_mixins.edit_theme(movie)
def test_video_Movie_mixins_rating(movie):
test_mixins.edit_rating(movie)
def test_video_Movie_mixins_tags(movie):
test_mixins.edit_collection(movie)
test_mixins.edit_country(movie)
test_mixins.edit_director(movie)
test_mixins.edit_genre(movie)
test_mixins.edit_label(movie)
test_mixins.edit_producer(movie)
test_mixins.edit_writer(movie)
def test_video_Movie_media_tags(movie):
movie.reload()
test_media.tag_collection(movie)
test_media.tag_country(movie)
test_media.tag_director(movie)
test_media.tag_genre(movie)
test_media.tag_label(movie)
test_media.tag_producer(movie)
test_media.tag_role(movie)
test_media.tag_similar(movie)
test_media.tag_writer(movie)
def test_video_Movie_PlexWebURL(plex, movie):
url = movie.getWebURL()
assert url.startswith('https://app.plex.tv/desktop')
@ -799,6 +805,10 @@ def test_video_Show_mixins_images(show):
test_mixins.attr_posterUrl(show)
def test_video_Show_mixins_themes(show):
test_mixins.edit_theme(show)
def test_video_Show_mixins_rating(show):
test_mixins.edit_rating(show)
@ -860,6 +870,7 @@ def test_video_Season_attrs(show):
assert utils.is_metadata(season.parentKey)
assert utils.is_int(season.parentRatingKey)
assert season.parentStudio == "Revolution Sun Studios"
assert utils.is_metadata(season.parentTheme)
if season.parentThumb:
assert utils.is_thumb(season.parentThumb)
assert season.parentTitle == "Game of Thrones"
@ -930,6 +941,11 @@ def test_video_Season_mixins_images(show):
test_mixins.attr_posterUrl(season)
def test_video_Season_mixins_themes(show):
season = show.season(season=1)
test_mixins.attr_themeUrl(season)
def test_video_Season_mixins_rating(show):
season = show.season(season=1)
test_mixins.edit_rating(season)
@ -1142,6 +1158,10 @@ def test_video_Episode_mixins_images(episode):
test_mixins.attr_posterUrl(episode)
def test_video_Episode_mixins_themes(episode):
test_mixins.attr_themeUrl(episode)
def test_video_Episode_mixins_rating(episode):
test_mixins.edit_rating(episode)