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

Add base handler tests #1090

Merged
merged 3 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 7 additions & 7 deletions jupyter_server/base/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ def log():
class AuthenticatedHandler(web.RequestHandler):
"""A RequestHandler with an authenticated user."""

@property
def base_url(self) -> str:
return self.settings.get("base_url", "/")

@property
def content_security_policy(self):
"""The default Content-Security-Policy header
Expand Down Expand Up @@ -288,10 +292,6 @@ def mathjax_url(self):
def mathjax_config(self):
return self.settings.get("mathjax_config", "TeX-AMS-MML_HTMLorMML-full,Safe")

@property
def base_url(self) -> str:
return self.settings.get("base_url", "/")

@property
def default_url(self):
return self.settings.get("default_url", "")
Expand Down Expand Up @@ -830,12 +830,12 @@ def head(self, path):

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

return web.StaticFileHandler.get(self, path)
return web.StaticFileHandler.get(self, path, **kwargs)

def get_content_type(self):
assert self.absolute_path is not None
Expand Down Expand Up @@ -879,7 +879,7 @@ def validate_absolute_path(self, root, absolute_path):
return abs_path


def json_errors(method):
def json_errors(method): # pragma: no cover
"""Decorate methods with this to return GitHub style JSON errors.
This should be used on any JSON API on any handler method that can raise HTTPErrors.
Expand Down
125 changes: 125 additions & 0 deletions tests/test_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
"""Test Base Handlers"""
import os
import warnings
from unittest.mock import MagicMock

from tornado.httpserver import HTTPRequest
from tornado.httputil import HTTPHeaders

from jupyter_server.auth import AllowAllAuthorizer, IdentityProvider
from jupyter_server.base.handlers import (
APIHandler,
APIVersionHandler,
AuthenticatedFileHandler,
AuthenticatedHandler,
FilesRedirectHandler,
JupyterHandler,
RedirectWithParams,
)
from jupyter_server.serverapp import ServerApp


def test_authenticated_handler(jp_serverapp):
app: ServerApp = jp_serverapp
request = HTTPRequest("OPTIONS")
request.connection = MagicMock()
handler = AuthenticatedHandler(app.web_app, request)
for key in list(handler.settings):
del handler.settings[key]
handler.settings["headers"] = {"Content-Security-Policy": "foo"}

assert handler.content_security_policy == "foo"
assert handler.skip_check_origin()
with warnings.catch_warnings():
warnings.simplefilter("ignore")
assert handler.login_handler == handler.identity_provider.login_handler_class
assert isinstance(handler.authorizer, AllowAllAuthorizer)
assert isinstance(handler.identity_provider, IdentityProvider)


def test_jupyter_handler(jp_serverapp):
app: ServerApp = jp_serverapp
headers = HTTPHeaders({"Origin": "foo"})
request = HTTPRequest("OPTIONS", headers=headers)
request.connection = MagicMock()
handler = JupyterHandler(app.web_app, request)
for key in list(handler.settings):
del handler.settings[key]
handler.settings["mathjax_url"] = "foo"
handler.settings["mathjax_config"] = "bar"
assert handler.mathjax_url == "/foo"
assert handler.mathjax_config == "bar"
handler.settings["terminal_manager"] = "fizz"
assert handler.terminal_manager == "fizz"
handler.settings["allow_origin"] = True
handler.set_cors_headers()
handler.settings["allow_origin"] = False
handler.settings["allow_origin_pat"] = "foo"
handler.settings["allow_credentials"] = True
handler.set_cors_headers()
assert handler.check_referer() is True


def test_api_handler(jp_serverapp):
app: ServerApp = jp_serverapp
headers = HTTPHeaders({"Origin": "foo"})
request = HTTPRequest("OPTIONS", headers=headers)
request.connection = MagicMock()
handler = APIHandler(app.web_app, request)
for key in list(handler.settings):
del handler.settings[key]
handler.options()


async def test_authenticated_file_handler(jp_serverapp, tmpdir):
app: ServerApp = jp_serverapp
headers = HTTPHeaders({"Origin": "foo"})
request = HTTPRequest("HEAD", headers=headers)
request.connection = MagicMock()
test_file = tmpdir / "foo"
with open(test_file, "w") as fid:
fid.write("hello")

handler = AuthenticatedFileHandler(app.web_app, request, path=str(tmpdir))
for key in list(handler.settings):
del handler.settings[key]
handler.check_xsrf_cookie = MagicMock() # type:ignore
handler._jupyter_current_user = "foo" # type:ignore
with warnings.catch_warnings():
warnings.simplefilter("ignore")
await handler.head("foo")
assert handler.get_status() == 200


async def test_api_version_handler(jp_serverapp):
app: ServerApp = jp_serverapp
request = HTTPRequest("GET")
request.connection = MagicMock()
handler = APIVersionHandler(app.web_app, request)
handler._transforms = []
handler.get()
assert handler.get_status() == 200


async def test_files_redirect_handler(jp_serverapp):
app: ServerApp = jp_serverapp
request = HTTPRequest("GET")
request.connection = MagicMock()
test_file = os.path.join(app.contents_manager.root_dir, "foo")
with open(test_file, "w") as fid:
fid.write("hello")
handler = FilesRedirectHandler(app.web_app, request)
handler._transforms = []
await handler.get("foo")
assert handler.get_status() == 302


def test_redirect_with_params(jp_serverapp):
app: ServerApp = jp_serverapp
request = HTTPRequest("GET")
request.connection = MagicMock()
request.query = "foo"
handler = RedirectWithParams(app.web_app, request, url="foo")
handler._transforms = []
handler.get()
assert handler.get_status() == 301