Skip to content

Commit 28577cf

Browse files
authored
Add more coverage (#1069)
1 parent 830c87f commit 28577cf

File tree

7 files changed

+88
-49
lines changed

7 files changed

+88
-49
lines changed

.github/workflows/python-tests.yml

+18-41
Original file line numberDiff line numberDiff line change
@@ -37,34 +37,20 @@ jobs:
3737
sudo apt-get update
3838
sudo apt-get install texlive-plain-generic inkscape texlive-xetex
3939
sudo apt-get install xvfb x11-utils libxkbcommon-x11-0 pandoc
40-
- name: Run the tests
40+
- name: Run the tests on posix
4141
if: ${{ !startsWith(matrix.python-version, 'pypy') && !startsWith(matrix.os, 'windows') }}
42-
run: hatch run cov:test -W default || hatch run test:test -W default --lf
43-
- name: Run the tests on pypy and windows
44-
if: ${{ startsWith(matrix.python-version, 'pypy') || startsWith(matrix.os, 'windows') }}
45-
run: hatch run test:test -W default || hatch run test:test -W default --lf
42+
run: hatch run cov:test --cov-fail-under 75 || hatch run test:test --lf
43+
- name: Run the tests on pypy
44+
if: ${{ startsWith(matrix.python-version, 'pypy') }}
45+
run: hatch run test:test || hatch run test:test --lf
46+
- name: Run the tests on windows
47+
if: ${{ startsWith(matrix.python-version, 'windows') }}
48+
run: hatch run cov:nowarn -s || hatch run cov:nowarn --lf
4649
- name: Coverage
4750
run: |
4851
pip install codecov
4952
codecov
5053
51-
client8:
52-
runs-on: ${{ matrix.os }}
53-
timeout-minutes: 20
54-
strategy:
55-
fail-fast: false
56-
matrix:
57-
os: [ubuntu-latest, windows-latest, macos-latest]
58-
python-version: ["3.10"]
59-
steps:
60-
- name: Checkout
61-
uses: actions/checkout@v3
62-
- name: Base Setup
63-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
64-
- run: |
65-
pip install -U pre jupyter_client
66-
hatch run test:test || hatch run test:test --lf
67-
6854
pre-commit:
6955
name: pre-commit
7056
runs-on: ubuntu-latest
@@ -102,38 +88,30 @@ jobs:
10288
runs-on: ubuntu-latest
10389
steps:
10490
- uses: actions/checkout@v3
105-
- name: Base Setup
106-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
91+
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
10792
with:
10893
python_version: "3.8"
109-
- name: Install miniumum versions
110-
uses: jupyterlab/maintainer-tools/.github/actions/install-minimums@v1
94+
- uses: jupyterlab/maintainer-tools/.github/actions/install-minimums@v1
95+
with:
96+
only_create_file: 1
11197
- name: Run the unit tests
11298
run: |
113-
pytest -vv -W default || pytest -vv -W default --lf
99+
export PIP_CONSTRAINT="./contraints_file.txt"
100+
hatch run test:nowarn || hatch run test:nowarn --lf
114101
115102
test_prereleases:
116103
name: Test Prereleases
117104
runs-on: ubuntu-latest
118105
timeout-minutes: 20
119106
steps:
120-
- name: Checkout
121-
uses: actions/checkout@v3
122-
- name: Base Setup
123-
uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
107+
- uses: actions/checkout@v3
108+
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
124109
with:
125110
python_version: "3.11"
126-
- name: Install the Python dependencies
127-
run: |
128-
pip install --no-deps .
129-
pip install --pre --upgrade ".[test]"
130-
- name: List installed packages
131-
run: |
132-
pip freeze
133-
pip check
134111
- name: Run the tests
135112
run: |
136-
pytest -vv -W default || pytest -vv -W default --lf
113+
export PIP_PRE=1
114+
hatch run test:nowarn || hatch run test:nowarn --lf
137115
138116
make_sdist:
139117
name: Make SDist
@@ -173,7 +151,6 @@ jobs:
173151
- test_docs
174152
- test_minimum_versions
175153
- test_prereleases
176-
- client8
177154
- check_links
178155
- test_sdist
179156
runs-on: ubuntu-latest

jupyter_server/files/handlers.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
"""Serve files directly from the ContentsManager."""
22
# Copyright (c) Jupyter Development Team.
33
# Distributed under the terms of the Modified BSD License.
4-
import json
54
import mimetypes
65
from base64 import decodebytes
76
from typing import List
@@ -15,7 +14,7 @@
1514
AUTH_RESOURCE = "contents"
1615

1716

18-
class FilesHandler(JupyterHandler):
17+
class FilesHandler(JupyterHandler, web.StaticFileHandler):
1918
"""serve files via ContentsManager
2019
2120
Normally used when ContentsManager is not a FileContentsManager.
@@ -85,8 +84,6 @@ async def get(self, path, include_body=True):
8584
if model["format"] == "base64":
8685
b64_bytes = model["content"].encode("ascii")
8786
self.write(decodebytes(b64_bytes))
88-
elif model["format"] == "json":
89-
self.write(json.dumps(model["content"]))
9087
else:
9188
self.write(model["content"])
9289
self.flush()

pyproject.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,8 @@ dependencies = ["coverage", "pytest-cov"]
104104
[tool.hatch.envs.cov.env-vars]
105105
ARGS = "-vv --cov jupyter_server --cov-branch --cov-report term-missing:skip-covered"
106106
[tool.hatch.envs.cov.scripts]
107-
test = "python -m pytest $ARGS --cov-fail-under 75 {args}"
107+
test = "python -m pytest $ARGS {args}"
108+
nwarn = "python -m pytest $ARGS -W default {args}"
108109
integration = "python -m pytest $ARGS --integration_tests=true {args}"
109110

110111
[tool.hatch.version]

tests/extension/test_serverextension.py

+22
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
from jupyter_server.config_manager import BaseJSONConfigManager
1313
from jupyter_server.extension.serverextension import (
14+
DisableServerExtensionApp,
15+
ListServerExtensionsApp,
16+
ServerExtensionApp,
17+
ToggleServerExtensionApp,
1418
_get_config_dir,
1519
toggle_server_extension_python,
1620
)
@@ -112,3 +116,21 @@ def test_load_ordered(jp_serverapp, jp_server_config):
112116
assert jp_serverapp.mockII is True, "Mock II should have been loaded"
113117
assert jp_serverapp.mockI is True, "Mock I should have been loaded"
114118
assert jp_serverapp.mock_shared == "II", "Mock II should be loaded after Mock I"
119+
120+
121+
def test_server_extension_apps(jp_env_config_path, jp_extension_environ):
122+
app = ToggleServerExtensionApp()
123+
app.extra_args = "mock1"
124+
app.start()
125+
126+
app = DisableServerExtensionApp()
127+
app.extra_args = "mock1"
128+
app.start()
129+
130+
app = ListServerExtensionsApp()
131+
app.start()
132+
133+
134+
def test_server_extension_app():
135+
app = ServerExtensionApp()
136+
app.launch_instance(["list"])

tests/extension/test_utils.py

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import logging
2+
import warnings
3+
14
import pytest
25

3-
from jupyter_server.extension.utils import validate_extension
6+
from jupyter_server.extension.utils import get_loader, get_metadata, validate_extension
7+
from tests.extension.mockextensions import mockext_sys
48

59
# Use ServerApps environment because it monkeypatches
610
# jupyter_core.paths and provides a config directory
@@ -17,3 +21,19 @@ def test_validate_extension():
1721
assert validate_extension("tests.extension.mockextensions.mockext_user")
1822
# enabled at Python
1923
assert validate_extension("tests.extension.mockextensions.mockext_py")
24+
25+
26+
def test_get_loader():
27+
get_loader(mockext_sys)
28+
with warnings.catch_warnings():
29+
warnings.simplefilter("ignore")
30+
assert get_loader(object()) is None
31+
32+
33+
def test_get_metadata():
34+
_, ext_points = get_metadata("tests.extension.mockextensions.mockext_sys")
35+
assert len(ext_points)
36+
_, ext_points = get_metadata("tests", logger=logging.getLogger())
37+
point = ext_points[0]
38+
assert point["module"] == "tests"
39+
assert point["name"] == "tests"

tests/test_files.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@
1010
from .utils import expected_http_error
1111

1212

13+
@pytest.fixture(
14+
params=[
15+
"jupyter_server.files.handlers.FilesHandler",
16+
"jupyter_server.base.handlers.AuthenticatedFileHandler",
17+
]
18+
)
19+
def jp_argv(request):
20+
return ["--ContentsManager.files_handler_class=" + request.param]
21+
22+
1323
@pytest.fixture(
1424
params=[
1525
[False, ["å b"]],
@@ -33,6 +43,15 @@ async def fetch_expect_404(jp_fetch, *path_parts):
3343
assert expected_http_error(e, 404), [path_parts, e]
3444

3545

46+
async def test_file_types(jp_fetch, jp_root_dir):
47+
path = Path(jp_root_dir, "test")
48+
path.mkdir(parents=True, exist_ok=True)
49+
foos = ["foo.tar.gz", "foo.bz", "foo.foo"]
50+
for foo in foos:
51+
(path / foo).write_text(foo)
52+
await fetch_expect_200(jp_fetch, "test", foo)
53+
54+
3655
async def test_hidden_files(jp_fetch, jp_serverapp, jp_root_dir, maybe_hidden):
3756
is_hidden, path_parts = maybe_hidden
3857
path = Path(jp_root_dir, *path_parts)
@@ -85,7 +104,7 @@ async def test_contents_manager(jp_fetch, jp_serverapp, jp_root_dir):
85104

86105
r = await jp_fetch("files/test.txt", method="GET")
87106
assert r.code == 200
88-
assert r.headers["content-type"] == "text/plain; charset=UTF-8"
107+
assert "text/plain" in r.headers["content-type"]
89108
assert r.body.decode() == "foobar"
90109

91110

tests/test_utils.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import socket
33
import subprocess
44
import sys
5+
import uuid
56
import warnings
67
from pathlib import Path
78
from unittest.mock import patch
@@ -116,7 +117,9 @@ async def foo():
116117
@pytest.mark.skipif(os.name != "posix", reason="Requires unix sockets")
117118
def test_unix_socket_in_use(tmp_path):
118119
root_tmp_dir = Path("/tmp").resolve()
119-
server_address = os.path.join(root_tmp_dir, os.path.basename(tmp_path))
120+
server_address = os.path.join(root_tmp_dir, uuid.uuid4().hex)
121+
if os.path.exists(server_address):
122+
os.remove(server_address)
120123
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
121124
sock.bind(server_address)
122125
sock.listen(0)

0 commit comments

Comments
 (0)