Skip to content

Commit ab60056

Browse files
testing tests
1 parent 1971431 commit ab60056

File tree

7 files changed

+169
-68
lines changed

7 files changed

+169
-68
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ cython_debug/
163163
Contents/Info.plist
164164

165165
# Remove plexhints files
166-
plexhints-temp
166+
plexhints/
167+
plexhints-temp/
167168
*cache.sqlite
168169

169170
# Remove python modules

Contents/Code/plex_api_helper.py

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,58 @@ def get_plex_item(rating_key):
598598
return item
599599

600600

601+
def get_user_info(token):
602+
# type: (str) -> Optional[MyPlexAccount]
603+
"""
604+
Get the Plex user info.
605+
606+
Parameters
607+
----------
608+
token : str
609+
The Plex token.
610+
611+
Returns
612+
-------
613+
Optional[MyPlexAccount]
614+
The Plex user info.
615+
616+
Examples
617+
--------
618+
>>> get_user_info(token='...')
619+
...
620+
"""
621+
try:
622+
return MyPlexAccount(token=token)
623+
except Exception as e:
624+
Log.Error('Error getting user info: {}'.format(e))
625+
return None
626+
627+
628+
def is_server_owner(user):
629+
# type: (MyPlexAccount) -> bool
630+
"""
631+
Check if the user is the owner of the Plex server.
632+
633+
Parameters
634+
----------
635+
user : MyPlexAccount
636+
The Plex user info.
637+
638+
Returns
639+
-------
640+
py:class:`bool`
641+
True if the user is the owner of the Plex server, False otherwise.
642+
643+
Examples
644+
--------
645+
>>> is_server_owner(user=...)
646+
...
647+
"""
648+
plex = setup_plexapi()
649+
650+
return plex.account().username in {user.email, user.username}
651+
652+
601653
def process_queue():
602654
# type: () -> None
603655
"""
@@ -766,54 +818,3 @@ def scheduled_update():
766818
for item in all_items:
767819
if item.ratingKey not in q.queue:
768820
q.put(item=item.ratingKey)
769-
770-
771-
def get_user_info(token):
772-
# type: (str) -> Optional[MyPlexAccount]
773-
"""
774-
Get the Plex user info.
775-
776-
Parameters
777-
----------
778-
token : str
779-
The Plex token.
780-
781-
Returns
782-
-------
783-
Optional[MyPlexAccount]
784-
The Plex user info.
785-
786-
Examples
787-
--------
788-
>>> get_user_info(token='...')
789-
...
790-
"""
791-
try:
792-
return MyPlexAccount(token=token)
793-
except Exception:
794-
return None
795-
796-
797-
def is_server_owner(user):
798-
# type: (MyPlexAccount) -> bool
799-
"""
800-
Check if the user is the owner of the Plex server.
801-
802-
Parameters
803-
----------
804-
user : MyPlexAccount
805-
The Plex user info.
806-
807-
Returns
808-
-------
809-
py:class:`bool`
810-
True if the user is the owner of the Plex server, False otherwise.
811-
812-
Examples
813-
--------
814-
>>> is_server_owner(user=...)
815-
...
816-
"""
817-
plex = setup_plexapi()
818-
819-
return plex.account().username in {user.email, user.username}

Contents/Code/webapp.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import logging
99
import os
1010
from threading import Lock, Thread
11+
from typing import Optional
1112
import uuid
1213

1314
# plex debugging
@@ -62,7 +63,7 @@ def render_template(*args, **kwargs):
6263
>>> render_template('home.html', title='Home', items=items)
6364
"""
6465
kwargs['Prefs'] = Prefs
65-
kwargs['is_logged_in'] = is_logged_in
66+
kwargs['is_logged_in'] = is_logged_in()
6667
return flask_render_template(*args, **kwargs)
6768

6869

@@ -574,8 +575,8 @@ def is_logged_in():
574575
return False
575576

576577
token = session["token"]
577-
user = get_user_info(token)
578-
logged_in = user and is_server_owner(user)
578+
user = get_user_info(token=token)
579+
logged_in = user and is_server_owner(user=user)
579580
return logged_in
580581

581582

@@ -600,7 +601,7 @@ def logout():
600601

601602
@app.before_request
602603
def check_login_status():
603-
# type: () -> None
604+
# type: () -> Optional[flask.redirect]
604605
"""
605606
Check if the user is logged in.
606607

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# development environment requirements, these should not be distributed
22
flake8==3.9.2;python_version<"3"
3+
mock==3.0.5;python_version<"3"
34
m2r2==0.3.2;python_version<"3"
45
numpydoc==0.9.2;python_version<"3"
56
plexhints==2023.1211.160853 # type hinting library for plex development

tests/conftest.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@
55
import os
66
import sys
77
import time
8+
from mock import patch
89

910
# lib imports
1011
import plexapi
1112
from plexapi.exceptions import NotFound
1213
from plexapi.server import PlexServer
1314
from plexhints.agent_kit import Agent
15+
from plexhints.prefs_kit import _PreferenceSet
1416
import pytest
1517
import requests
1618

19+
# create a fake directory for plexhints
20+
if not os.path.exists('plexhints'):
21+
os.mkdir('plexhints')
22+
1723
# add Contents directory to the system path
1824
pytest.root_dir = root_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
1925
pytest.contents_dir = contents_dir = os.path.join(root_dir, 'Contents')
@@ -87,6 +93,18 @@ def agent(request):
8793
return Themerr()
8894

8995

96+
# extend the _PreferenceSet class, and give it a setter
97+
class PreferenceSet(_PreferenceSet):
98+
def __setitem__(self, key, value):
99+
self.update_user_values(**{key: value})
100+
101+
102+
@pytest.fixture(scope='function')
103+
def prefs_webapp_patch():
104+
with patch('Code.webapp.Prefs', new_callable=lambda: PreferenceSet('test_webapp_prefs')) as mock_prefs:
105+
yield mock_prefs
106+
107+
90108
@pytest.fixture(scope='function')
91109
def test_client():
92110
"""Create a test client for testing webapp endpoints"""
@@ -102,6 +120,13 @@ def test_client():
102120
yield test_client # this is where the testing happens!
103121

104122

123+
@pytest.fixture(scope='function')
124+
def test_client_login_disabled(test_client, prefs_webapp_patch):
125+
"""Create a test client for testing webapp endpoints with login disabled"""
126+
webapp.Prefs['bool_webapp_require_login'] = False # disable login requirement
127+
yield test_client
128+
129+
105130
# plex server fixtures
106131
@pytest.fixture(scope="session")
107132
def plugin_logs():
@@ -111,7 +136,6 @@ def plugin_logs():
111136
yield plugin_logs
112137

113138

114-
# plex server fixtures
115139
@pytest.fixture(scope="session")
116140
def plugin_log_file():
117141
# the primary plugin log file
@@ -136,6 +160,11 @@ def plex(request, sess):
136160
return PlexServer(SERVER_BASEURL, SERVER_TOKEN, session=sess)
137161

138162

163+
@pytest.fixture(scope="session")
164+
def plex_token():
165+
return SERVER_TOKEN
166+
167+
139168
@pytest.fixture(params=MOVIE_SECTIONS, scope="session")
140169
def movie_section_names(plex, request):
141170
library_section = request.param

tests/functional/test_webapp.py

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,64 +15,115 @@ def remove_themerr_db_cache_file():
1515
_backup_file_name = "{}.bak".format(webapp.database_cache_file)
1616

1717
# rename the file, so it is not found
18-
os.rename(webapp.database_cache_file, _backup_file_name)
18+
if os.path.exists(webapp.database_cache_file):
19+
os.rename(webapp.database_cache_file, _backup_file_name)
1920
yield
2021

2122
# rename the file back
22-
os.rename(_backup_file_name, webapp.database_cache_file)
23+
if os.path.exists(_backup_file_name):
24+
os.rename(_backup_file_name, webapp.database_cache_file)
2325

2426

25-
def test_home(test_client):
27+
def test_home_login_disabled(test_client_login_disabled):
2628
"""
2729
WHEN the '/' page is requested (GET)
2830
THEN check that the response is valid
2931
3032
Repeat for '/home'
3133
"""
3234
try:
33-
response = test_client.get('/')
35+
response = test_client_login_disabled.get('/')
3436
except AttributeError:
3537
pytest.skip("cannot access Plex token/server")
3638
else:
3739
assert response.status_code == 200
3840

39-
response = test_client.get('/home')
41+
response = test_client_login_disabled.get('/home')
4042
assert response.status_code == 200
4143

4244
assert 'id="section_' in response.data.decode('utf-8')
4345

4446

45-
def test_home_without_cache(remove_themerr_db_cache_file, test_client):
47+
def test_home(test_client):
4648
"""
4749
WHEN the '/' page is requested (GET)
48-
THEN check that the response is valid
50+
THEN check that the response is a redirect
51+
52+
Repeat for '/home'
4953
"""
5054
try:
5155
response = test_client.get('/')
5256
except AttributeError:
5357
pytest.skip("cannot access Plex token/server")
58+
else:
59+
assert response.status_code == 302
60+
61+
response = test_client.get('/home')
62+
assert response.status_code == 302
63+
64+
65+
def test_home_without_cache_login_disabled(remove_themerr_db_cache_file, test_client_login_disabled):
66+
"""
67+
WHEN the '/' page is requested (GET)
68+
THEN check that the response is valid
69+
"""
70+
try:
71+
response = test_client_login_disabled.get('/')
72+
except AttributeError:
73+
pytest.skip("cannot access Plex token/server")
5474
else:
5575
assert response.status_code == 200
5676

5777
assert 'Database is being cached' in response.data.decode('utf-8')
5878

5979

60-
def test_image(test_client):
80+
def test_home_without_cache(remove_themerr_db_cache_file, test_client):
81+
"""
82+
WHEN the '/' page is requested (GET)
83+
THEN check that the response is a redirect
84+
"""
85+
try:
86+
response = test_client.get('/')
87+
except AttributeError:
88+
pytest.skip("cannot access Plex token/server")
89+
else:
90+
assert response.status_code == 302
91+
92+
93+
def test_image_login_disabled(test_client_login_disabled):
6194
"""
6295
WHEN the '/favicon.ico' file is requested (GET)
6396
THEN check that the response is valid
6497
THEN check the content type is 'image/vnd.microsoft.icon'
6598
"""
66-
response = test_client.get('favicon.ico')
99+
response = test_client_login_disabled.get('favicon.ico')
67100
assert response.status_code == 200
68101
assert response.content_type == 'image/vnd.microsoft.icon'
69102

70103

71-
def test_status(test_client):
104+
def test_image(test_client):
105+
"""
106+
WHEN the '/favicon.ico' file is requested (GET)
107+
THEN check that the response is a redirect
108+
"""
109+
response = test_client.get('favicon.ico')
110+
assert response.status_code == 302
111+
112+
113+
def test_status_no_login(test_client_login_disabled):
72114
"""
73115
WHEN the '/status' page is requested (GET)
74116
THEN check that the response is valid
75117
"""
76-
response = test_client.get('/status')
118+
response = test_client_login_disabled.get('/status')
77119
assert response.status_code == 200
78120
assert response.content_type == 'application/json'
121+
122+
123+
def test_status(test_client):
124+
"""
125+
WHEN the '/status' page is requested (GET)
126+
THEN check that the response is a redirect
127+
"""
128+
response = test_client.get('/status')
129+
assert response.status_code == 302

tests/unit/test_plex_api_helper.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,20 @@ def test_change_lock_status(section, lock):
2424
change_status = plex_api_helper.change_lock_status(item, field=field, lock=lock)
2525
assert change_status, 'change_lock_status did not return True'
2626
assert item.isLocked(field=field) == lock, 'Failed to change lock status to {}'.format(lock)
27+
28+
29+
def test_get_user_info(plex_token):
30+
assert plex_api_helper.get_user_info(token=plex_token)
31+
32+
33+
def test_get_user_info_invalid_token():
34+
assert not plex_api_helper.get_user_info(token='invalid_token')
35+
36+
37+
def test_is_server_owner(plex_token):
38+
user = plex_api_helper.get_user_info(token=plex_token)
39+
assert plex_api_helper.is_server_owner(user=user)
40+
41+
42+
def test_is_not_server_owner():
43+
assert plex_api_helper.is_server_owner(user={}) is None

0 commit comments

Comments
 (0)