Skip to content

Commit a763da3

Browse files
authored
Add base handler tests (#1090)
1 parent bd236f1 commit a763da3

File tree

2 files changed

+132
-7
lines changed

2 files changed

+132
-7
lines changed

jupyter_server/base/handlers.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ def log():
6767
class AuthenticatedHandler(web.RequestHandler):
6868
"""A RequestHandler with an authenticated user."""
6969

70+
@property
71+
def base_url(self) -> str:
72+
return self.settings.get("base_url", "/")
73+
7074
@property
7175
def content_security_policy(self):
7276
"""The default Content-Security-Policy header
@@ -288,10 +292,6 @@ def mathjax_url(self):
288292
def mathjax_config(self):
289293
return self.settings.get("mathjax_config", "TeX-AMS-MML_HTMLorMML-full,Safe")
290294

291-
@property
292-
def base_url(self) -> str:
293-
return self.settings.get("base_url", "/")
294-
295295
@property
296296
def default_url(self):
297297
return self.settings.get("default_url", "")
@@ -830,12 +830,12 @@ def head(self, path):
830830

831831
@web.authenticated
832832
@authorized
833-
def get(self, path):
833+
def get(self, path, **kwargs):
834834
if os.path.splitext(path)[1] == ".ipynb" or self.get_argument("download", None):
835835
name = path.rsplit("/", 1)[-1]
836836
self.set_attachment_header(name)
837837

838-
return web.StaticFileHandler.get(self, path)
838+
return web.StaticFileHandler.get(self, path, **kwargs)
839839

840840
def get_content_type(self):
841841
assert self.absolute_path is not None
@@ -879,7 +879,7 @@ def validate_absolute_path(self, root, absolute_path):
879879
return abs_path
880880

881881

882-
def json_errors(method):
882+
def json_errors(method): # pragma: no cover
883883
"""Decorate methods with this to return GitHub style JSON errors.
884884
885885
This should be used on any JSON API on any handler method that can raise HTTPErrors.

tests/test_handlers.py

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"""Test Base Handlers"""
2+
import os
3+
import warnings
4+
from unittest.mock import MagicMock
5+
6+
from tornado.httpserver import HTTPRequest
7+
from tornado.httputil import HTTPHeaders
8+
9+
from jupyter_server.auth import AllowAllAuthorizer, IdentityProvider
10+
from jupyter_server.base.handlers import (
11+
APIHandler,
12+
APIVersionHandler,
13+
AuthenticatedFileHandler,
14+
AuthenticatedHandler,
15+
FilesRedirectHandler,
16+
JupyterHandler,
17+
RedirectWithParams,
18+
)
19+
from jupyter_server.serverapp import ServerApp
20+
21+
22+
def test_authenticated_handler(jp_serverapp):
23+
app: ServerApp = jp_serverapp
24+
request = HTTPRequest("OPTIONS")
25+
request.connection = MagicMock()
26+
handler = AuthenticatedHandler(app.web_app, request)
27+
for key in list(handler.settings):
28+
del handler.settings[key]
29+
handler.settings["headers"] = {"Content-Security-Policy": "foo"}
30+
31+
assert handler.content_security_policy == "foo"
32+
assert handler.skip_check_origin()
33+
with warnings.catch_warnings():
34+
warnings.simplefilter("ignore")
35+
assert handler.login_handler == handler.identity_provider.login_handler_class
36+
assert isinstance(handler.authorizer, AllowAllAuthorizer)
37+
assert isinstance(handler.identity_provider, IdentityProvider)
38+
39+
40+
def test_jupyter_handler(jp_serverapp):
41+
app: ServerApp = jp_serverapp
42+
headers = HTTPHeaders({"Origin": "foo"})
43+
request = HTTPRequest("OPTIONS", headers=headers)
44+
request.connection = MagicMock()
45+
handler = JupyterHandler(app.web_app, request)
46+
for key in list(handler.settings):
47+
del handler.settings[key]
48+
handler.settings["mathjax_url"] = "foo"
49+
handler.settings["mathjax_config"] = "bar"
50+
assert handler.mathjax_url == "/foo"
51+
assert handler.mathjax_config == "bar"
52+
handler.settings["terminal_manager"] = "fizz"
53+
assert handler.terminal_manager == "fizz"
54+
handler.settings["allow_origin"] = True
55+
handler.set_cors_headers()
56+
handler.settings["allow_origin"] = False
57+
handler.settings["allow_origin_pat"] = "foo"
58+
handler.settings["allow_credentials"] = True
59+
handler.set_cors_headers()
60+
assert handler.check_referer() is True
61+
62+
63+
def test_api_handler(jp_serverapp):
64+
app: ServerApp = jp_serverapp
65+
headers = HTTPHeaders({"Origin": "foo"})
66+
request = HTTPRequest("OPTIONS", headers=headers)
67+
request.connection = MagicMock()
68+
handler = APIHandler(app.web_app, request)
69+
for key in list(handler.settings):
70+
del handler.settings[key]
71+
handler.options()
72+
73+
74+
async def test_authenticated_file_handler(jp_serverapp, tmpdir):
75+
app: ServerApp = jp_serverapp
76+
headers = HTTPHeaders({"Origin": "foo"})
77+
request = HTTPRequest("HEAD", headers=headers)
78+
request.connection = MagicMock()
79+
test_file = tmpdir / "foo"
80+
with open(test_file, "w") as fid:
81+
fid.write("hello")
82+
83+
handler = AuthenticatedFileHandler(app.web_app, request, path=str(tmpdir))
84+
for key in list(handler.settings):
85+
del handler.settings[key]
86+
handler.check_xsrf_cookie = MagicMock() # type:ignore
87+
handler._jupyter_current_user = "foo" # type:ignore
88+
with warnings.catch_warnings():
89+
warnings.simplefilter("ignore")
90+
await handler.head("foo")
91+
assert handler.get_status() == 200
92+
93+
94+
async def test_api_version_handler(jp_serverapp):
95+
app: ServerApp = jp_serverapp
96+
request = HTTPRequest("GET")
97+
request.connection = MagicMock()
98+
handler = APIVersionHandler(app.web_app, request)
99+
handler._transforms = []
100+
handler.get()
101+
assert handler.get_status() == 200
102+
103+
104+
async def test_files_redirect_handler(jp_serverapp):
105+
app: ServerApp = jp_serverapp
106+
request = HTTPRequest("GET")
107+
request.connection = MagicMock()
108+
test_file = os.path.join(app.contents_manager.root_dir, "foo")
109+
with open(test_file, "w") as fid:
110+
fid.write("hello")
111+
handler = FilesRedirectHandler(app.web_app, request)
112+
handler._transforms = []
113+
await handler.get("foo")
114+
assert handler.get_status() == 302
115+
116+
117+
def test_redirect_with_params(jp_serverapp):
118+
app: ServerApp = jp_serverapp
119+
request = HTTPRequest("GET")
120+
request.connection = MagicMock()
121+
request.query = "foo"
122+
handler = RedirectWithParams(app.web_app, request, url="foo")
123+
handler._transforms = []
124+
handler.get()
125+
assert handler.get_status() == 301

0 commit comments

Comments
 (0)