2017-01-09 04:40:39 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2017-10-25 19:53:52 +00:00
|
|
|
import pytest
|
2017-10-28 20:58:47 +00:00
|
|
|
from plexapi.exceptions import BadRequest, NotFound
|
2020-04-29 21:23:22 +00:00
|
|
|
|
2017-10-26 23:09:17 +00:00
|
|
|
from . import conftest as utils
|
2017-01-09 04:40:39 +00:00
|
|
|
|
2017-04-15 00:47:59 +00:00
|
|
|
|
|
|
|
def test_myplex_accounts(account, plex):
|
2020-04-29 21:23:22 +00:00
|
|
|
assert account, "Must specify username, password & resource to run this test."
|
|
|
|
print("MyPlexAccount:")
|
|
|
|
print("username: %s" % account.username)
|
|
|
|
print("email: %s" % account.email)
|
|
|
|
print("home: %s" % account.home)
|
|
|
|
print("queueEmail: %s" % account.queueEmail)
|
|
|
|
assert account.username, "Account has no username"
|
|
|
|
assert account.authenticationToken, "Account has no authenticationToken"
|
|
|
|
assert account.email, "Account has no email"
|
|
|
|
assert account.home is not None, "Account has no home"
|
|
|
|
assert account.queueEmail, "Account has no queueEmail"
|
2017-04-15 00:47:59 +00:00
|
|
|
account = plex.account()
|
2020-04-29 21:23:22 +00:00
|
|
|
print("Local PlexServer.account():")
|
|
|
|
print("username: %s" % account.username)
|
|
|
|
# print('authToken: %s' % account.authToken)
|
|
|
|
print("signInState: %s" % account.signInState)
|
|
|
|
assert account.username, "Account has no username"
|
|
|
|
assert account.authToken, "Account has no authToken"
|
|
|
|
assert account.signInState, "Account has no signInState"
|
2017-01-09 04:40:39 +00:00
|
|
|
|
|
|
|
|
2017-04-15 00:47:59 +00:00
|
|
|
def test_myplex_resources(account):
|
2020-04-29 21:23:22 +00:00
|
|
|
assert account, "Must specify username, password & resource to run this test."
|
2017-01-09 04:40:39 +00:00
|
|
|
resources = account.resources()
|
|
|
|
for resource in resources:
|
2020-04-29 21:23:22 +00:00
|
|
|
name = resource.name or "Unknown"
|
2017-01-09 04:40:39 +00:00
|
|
|
connections = [c.uri for c in resource.connections]
|
2020-04-29 21:23:22 +00:00
|
|
|
connections = ", ".join(connections) if connections else "None"
|
|
|
|
print("%s (%s): %s" % (name, resource.product, connections))
|
|
|
|
assert resources, "No resources found for account: %s" % account.name
|
2017-01-09 04:40:39 +00:00
|
|
|
|
2017-02-02 04:10:12 +00:00
|
|
|
|
2017-04-24 02:59:22 +00:00
|
|
|
def test_myplex_connect_to_resource(plex, account):
|
|
|
|
servername = plex.friendlyName
|
2017-04-15 00:47:59 +00:00
|
|
|
for resource in account.resources():
|
2017-04-24 02:59:22 +00:00
|
|
|
if resource.name == servername:
|
2017-02-02 04:10:12 +00:00
|
|
|
break
|
2017-04-24 02:59:22 +00:00
|
|
|
assert resource.connect(timeout=10)
|
2017-02-02 04:10:12 +00:00
|
|
|
|
|
|
|
|
2017-04-15 00:47:59 +00:00
|
|
|
def test_myplex_devices(account):
|
2017-01-09 04:40:39 +00:00
|
|
|
devices = account.devices()
|
|
|
|
for device in devices:
|
2020-04-29 21:23:22 +00:00
|
|
|
name = device.name or "Unknown"
|
|
|
|
connections = ", ".join(device.connections) if device.connections else "None"
|
|
|
|
print("%s (%s): %s" % (name, device.product, connections))
|
|
|
|
assert devices, "No devices found for account: %s" % account.name
|
2017-01-09 04:40:39 +00:00
|
|
|
|
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
def test_myplex_device(account, plex):
|
|
|
|
assert account.device(plex.friendlyName)
|
2017-10-25 19:53:52 +00:00
|
|
|
|
|
|
|
|
2017-04-15 00:47:59 +00:00
|
|
|
def _test_myplex_connect_to_device(account):
|
2017-01-09 04:40:39 +00:00
|
|
|
devices = account.devices()
|
|
|
|
for device in devices:
|
2020-04-29 21:23:22 +00:00
|
|
|
if device.name == "some client name" and len(device.connections):
|
2017-01-09 04:40:39 +00:00
|
|
|
break
|
|
|
|
client = device.connect()
|
2020-04-29 21:23:22 +00:00
|
|
|
assert client, "Unable to connect to device"
|
2017-02-02 04:10:12 +00:00
|
|
|
|
|
|
|
|
2017-04-15 00:47:59 +00:00
|
|
|
def test_myplex_users(account):
|
2017-02-02 04:10:12 +00:00
|
|
|
users = account.users()
|
2018-09-14 18:03:23 +00:00
|
|
|
if not len(users):
|
2020-04-29 21:23:22 +00:00
|
|
|
return pytest.skip("You have to add a shared account into your MyPlex")
|
|
|
|
print("Found %s users." % len(users))
|
2017-04-15 00:47:59 +00:00
|
|
|
user = account.user(users[0].title)
|
2020-04-29 21:23:22 +00:00
|
|
|
print("Found user: %s" % user)
|
|
|
|
assert user, "Could not find user %s" % users[0].title
|
2017-10-25 19:53:52 +00:00
|
|
|
|
2020-04-29 21:23:22 +00:00
|
|
|
assert (
|
|
|
|
len(users[0].servers[0].sections()) > 0
|
|
|
|
), "Couldn't info about the shared libraries"
|
2017-10-25 20:07:06 +00:00
|
|
|
|
2017-10-25 19:53:52 +00:00
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
def test_myplex_resource(account, plex):
|
|
|
|
assert account.resource(plex.friendlyName)
|
2017-10-25 19:53:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_myplex_webhooks(account):
|
2018-09-14 18:03:23 +00:00
|
|
|
if account.subscriptionActive:
|
|
|
|
assert isinstance(account.webhooks(), list)
|
|
|
|
else:
|
|
|
|
with pytest.raises(BadRequest):
|
|
|
|
account.webhooks()
|
2017-10-25 19:53:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_myplex_addwebhooks(account):
|
2018-09-14 18:03:23 +00:00
|
|
|
if account.subscriptionActive:
|
2020-04-29 21:23:22 +00:00
|
|
|
assert "http://example.com" in account.addWebhook("http://example.com")
|
2018-09-14 18:03:23 +00:00
|
|
|
else:
|
|
|
|
with pytest.raises(BadRequest):
|
2020-04-29 21:23:22 +00:00
|
|
|
account.addWebhook("http://example.com")
|
2017-10-25 19:53:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_myplex_deletewebhooks(account):
|
2018-09-14 18:03:23 +00:00
|
|
|
if account.subscriptionActive:
|
2020-04-29 21:23:22 +00:00
|
|
|
assert "http://example.com" not in account.deleteWebhook("http://example.com")
|
2018-09-14 18:03:23 +00:00
|
|
|
else:
|
|
|
|
with pytest.raises(BadRequest):
|
2020-04-29 21:23:22 +00:00
|
|
|
account.deleteWebhook("http://example.com")
|
2017-10-25 19:53:52 +00:00
|
|
|
|
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
def test_myplex_optout(account_once):
|
2017-10-25 19:53:52 +00:00
|
|
|
def enabled():
|
2020-04-29 21:23:22 +00:00
|
|
|
ele = account_once.query("https://plex.tv/api/v2/user/privacy")
|
|
|
|
lib = ele.attrib.get("optOutLibraryStats")
|
|
|
|
play = ele.attrib.get("optOutPlayback")
|
2017-10-25 19:53:52 +00:00
|
|
|
return bool(int(lib)), bool(int(play))
|
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
account_once.optOut(library=True, playback=True)
|
|
|
|
utils.wait_until(lambda: enabled() == (True, True))
|
|
|
|
account_once.optOut(library=False, playback=False)
|
|
|
|
utils.wait_until(lambda: enabled() == (False, False))
|
2017-10-25 19:53:52 +00:00
|
|
|
|
2017-10-26 23:09:17 +00:00
|
|
|
|
2020-10-07 15:24:20 +00:00
|
|
|
@pytest.mark.skip(reason="account.onlineMediaSources() is empty "
|
|
|
|
"in the CI test run against an unclaimed server.")
|
2020-08-30 06:20:30 +00:00
|
|
|
def test_myplex_onlineMediaSources_optOut(account):
|
|
|
|
mediaOptOut = account.onlineMediaSources()[0]
|
|
|
|
optOutValue = mediaOptOut.value
|
|
|
|
with pytest.raises(NotFound):
|
|
|
|
assert mediaOptOut.updateOptOut('what')
|
|
|
|
with pytest.raises(BadRequest):
|
|
|
|
assert mediaOptOut.updateOptOut(optOutValue)
|
|
|
|
choices = mediaOptOut.CHOICES
|
|
|
|
choices.remove(optOutValue)
|
|
|
|
mediaOptOut.updateOptOut(choices[0])
|
|
|
|
assert account.onlineMediaSources()[0].value == choices[0]
|
2020-09-01 01:41:43 +00:00
|
|
|
choices.append(optOutValue)
|
|
|
|
account.onlineMediaSources()[0].updateOptOut(optOutValue)
|
2020-08-30 06:20:30 +00:00
|
|
|
|
|
|
|
|
2017-10-26 23:09:17 +00:00
|
|
|
def test_myplex_inviteFriend_remove(account, plex, mocker):
|
2020-04-29 21:23:22 +00:00
|
|
|
inv_user = "hellowlol"
|
|
|
|
vid_filter = {"contentRating": ["G"], "label": ["foo"]}
|
2017-10-26 23:09:17 +00:00
|
|
|
secs = plex.library.sections()
|
|
|
|
|
|
|
|
ids = account._getSectionIds(plex.machineIdentifier, secs)
|
2020-12-30 22:58:01 +00:00
|
|
|
mocker.patch.object(account, "_getSectionIds", return_value=ids)
|
|
|
|
with utils.callable_http_patch():
|
|
|
|
account.inviteFriend(
|
|
|
|
inv_user,
|
|
|
|
plex,
|
|
|
|
secs,
|
|
|
|
allowSync=True,
|
|
|
|
allowCameraUpload=True,
|
|
|
|
allowChannels=False,
|
|
|
|
filterMovies=vid_filter,
|
|
|
|
filterTelevision=vid_filter,
|
|
|
|
filterMusic={"label": ["foo"]},
|
|
|
|
)
|
2017-10-26 23:09:17 +00:00
|
|
|
|
|
|
|
assert inv_user not in [u.title for u in account.users()]
|
|
|
|
|
2017-10-28 20:58:47 +00:00
|
|
|
with pytest.raises(NotFound):
|
|
|
|
with utils.callable_http_patch():
|
|
|
|
account.removeFriend(inv_user)
|
|
|
|
|
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
def test_myplex_updateFriend(account, plex, mocker, shared_username):
|
2020-04-29 21:23:22 +00:00
|
|
|
vid_filter = {"contentRating": ["G"], "label": ["foo"]}
|
2017-10-28 20:58:47 +00:00
|
|
|
secs = plex.library.sections()
|
2018-09-14 18:03:23 +00:00
|
|
|
user = account.user(shared_username)
|
2017-10-28 20:58:47 +00:00
|
|
|
|
|
|
|
ids = account._getSectionIds(plex.machineIdentifier, secs)
|
2020-12-30 22:58:01 +00:00
|
|
|
mocker.patch.object(account, "_getSectionIds", return_value=ids)
|
|
|
|
mocker.patch.object(account, "user", return_value=user)
|
|
|
|
with utils.callable_http_patch():
|
|
|
|
|
|
|
|
account.updateFriend(
|
|
|
|
shared_username,
|
|
|
|
plex,
|
|
|
|
secs,
|
|
|
|
allowSync=True,
|
|
|
|
removeSections=True,
|
|
|
|
allowCameraUpload=True,
|
|
|
|
allowChannels=False,
|
|
|
|
filterMovies=vid_filter,
|
|
|
|
filterTelevision=vid_filter,
|
|
|
|
filterMusic={"label": ["foo"]},
|
|
|
|
)
|
2018-09-14 18:03:23 +00:00
|
|
|
|
2017-10-28 20:58:47 +00:00
|
|
|
|
2019-09-15 01:03:18 +00:00
|
|
|
def test_myplex_createExistingUser(account, plex, shared_username):
|
|
|
|
user = account.user(shared_username)
|
2020-04-29 21:23:22 +00:00
|
|
|
url = "https://plex.tv/api/invites/requested/{}?friend=0&server=0&home=1".format(
|
|
|
|
user.id
|
|
|
|
)
|
2019-09-15 01:03:18 +00:00
|
|
|
|
|
|
|
account.createExistingUser(user, plex)
|
|
|
|
assert shared_username in [u.username for u in account.users() if u.home is True]
|
|
|
|
# Remove Home invite
|
|
|
|
account.query(url, account._session.delete)
|
|
|
|
# Confirm user was removed from home and has returned to friend
|
2020-04-29 21:23:22 +00:00
|
|
|
assert shared_username not in [
|
|
|
|
u.username for u in plex.myPlexAccount().users() if u.home is True
|
|
|
|
]
|
|
|
|
assert shared_username in [
|
|
|
|
u.username for u in plex.myPlexAccount().users() if u.home is False
|
|
|
|
]
|
2019-09-15 01:03:18 +00:00
|
|
|
|
|
|
|
|
2019-10-03 01:08:27 +00:00
|
|
|
@pytest.mark.skip(reason="broken test?")
|
2019-09-15 01:03:18 +00:00
|
|
|
def test_myplex_createHomeUser_remove(account, plex):
|
2020-04-29 21:23:22 +00:00
|
|
|
homeuser = "New Home User"
|
2019-09-15 01:03:18 +00:00
|
|
|
account.createHomeUser(homeuser, plex)
|
|
|
|
assert homeuser in [u.title for u in plex.myPlexAccount().users() if u.home is True]
|
|
|
|
account.removeHomeUser(homeuser)
|
2020-04-29 21:23:22 +00:00
|
|
|
assert homeuser not in [
|
|
|
|
u.title for u in plex.myPlexAccount().users() if u.home is True
|
|
|
|
]
|
2019-09-15 01:03:18 +00:00
|
|
|
|
|
|
|
|
2018-09-14 18:03:23 +00:00
|
|
|
def test_myplex_plexpass_attributes(account_plexpass):
|
|
|
|
assert account_plexpass.subscriptionActive
|
2020-04-29 21:23:22 +00:00
|
|
|
assert account_plexpass.subscriptionStatus == "Active"
|
2018-09-14 18:03:23 +00:00
|
|
|
assert account_plexpass.subscriptionPlan
|
2020-04-29 21:23:22 +00:00
|
|
|
assert "sync" in account_plexpass.subscriptionFeatures
|
|
|
|
assert "premium_music_metadata" in account_plexpass.subscriptionFeatures
|
|
|
|
assert "plexpass" in account_plexpass.roles
|
2020-12-16 04:41:04 +00:00
|
|
|
assert utils.ENTITLEMENTS <= set(account_plexpass.entitlements)
|
2018-09-14 18:52:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_myplex_claimToken(account):
|
2020-04-29 21:23:22 +00:00
|
|
|
assert account.claimToken().startswith("claim-")
|