File: test_files.py

package info (click to toggle)
jupyter-server 1.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 1,844 kB
  • sloc: python: 12,331; makefile: 175; javascript: 72
file content (144 lines) | stat: -rw-r--r-- 4,610 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import os
import pytest
from pathlib import Path
import tornado

from .utils import expected_http_error

from nbformat import writes
from nbformat.v4 import (new_notebook,
                         new_markdown_cell, new_code_cell,
                         new_output)


@pytest.fixture(params=[
    [False, ['å b']],
    [False, ['å b', 'ç. d']],
    [True, ['.å b']],
    [True, ['å b', '.ç d']]
])
def maybe_hidden(request):
    return request.param


async def fetch_expect_200(jp_fetch, *path_parts):
    r = await jp_fetch('files', *path_parts, method='GET')
    assert (r.body.decode() == path_parts[-1]), (path_parts, r.body)


async def fetch_expect_404(jp_fetch, *path_parts):
    with pytest.raises(tornado.httpclient.HTTPClientError) as e:
        await jp_fetch('files', *path_parts, method='GET')
    assert expected_http_error(e, 404), [path_parts, e]


async def test_hidden_files(jp_fetch, jp_serverapp, jp_root_dir, maybe_hidden):
    is_hidden, path_parts = maybe_hidden
    path = Path(jp_root_dir, *path_parts)
    path.mkdir(parents=True, exist_ok=True)

    foos = ['foo', '.foo']
    for foo in foos:
        (path / foo).write_text(foo)

    if is_hidden:
        for foo in foos:
            await fetch_expect_404(jp_fetch, *path_parts, foo)
    else:
        await fetch_expect_404(jp_fetch, *path_parts, '.foo')
        await fetch_expect_200(jp_fetch, *path_parts, 'foo')

    jp_serverapp.contents_manager.allow_hidden = True

    for foo in foos:
        await fetch_expect_200(jp_fetch, *path_parts, foo)


async def test_contents_manager(jp_fetch, jp_serverapp, jp_root_dir):
    """make sure ContentsManager returns right files (ipynb, bin, txt)."""
    nb = new_notebook(
        cells=[
            new_markdown_cell(u'Created by test ³'),
            new_code_cell("print(2*6)", outputs=[
                new_output("stream", text="12"),
            ])
        ]
    )
    jp_root_dir.joinpath('testnb.ipynb').write_text(writes(nb, version=4), encoding='utf-8')
    jp_root_dir.joinpath('test.bin').write_bytes(b'\xff' + os.urandom(5))
    jp_root_dir.joinpath('test.txt').write_text('foobar')

    r = await jp_fetch(
        'files/testnb.ipynb',
        method='GET'
    )
    assert r.code == 200
    assert 'print(2*6)' in r.body.decode('utf-8')

    r = await jp_fetch(
        'files/test.bin',
        method='GET'
    )
    assert r.code == 200
    assert r.headers['content-type'] == 'application/octet-stream'
    assert r.body[:1] == b'\xff'
    assert len(r.body) == 6

    r = await jp_fetch(
        'files/test.txt',
        method='GET'
    )
    assert r.code == 200
    assert r.headers['content-type'] == 'text/plain; charset=UTF-8'
    assert r.body.decode() == 'foobar'


async def test_download(jp_fetch, jp_serverapp, jp_root_dir):
    text = 'hello'
    jp_root_dir.joinpath('test.txt').write_text(text)

    r = await jp_fetch(
        'files', 'test.txt',
        method='GET'
    )
    disposition = r.headers.get('Content-Disposition', '')
    assert 'attachment' not in disposition

    r = await jp_fetch(
        'files', 'test.txt',
        method='GET',
        params={'download': True}
    )
    disposition = r.headers.get('Content-Disposition', '')
    assert 'attachment' in disposition
    assert "filename*=utf-8''test.txt" in disposition


async def test_old_files_redirect(jp_fetch, jp_serverapp, jp_root_dir):
    """pre-2.0 'files/' prefixed links are properly redirected"""
    jp_root_dir.joinpath('files').mkdir(parents=True, exist_ok=True)
    jp_root_dir.joinpath('sub', 'files').mkdir(parents=True, exist_ok=True)

    for prefix in ('', 'sub'):
        jp_root_dir.joinpath(prefix, 'files', 'f1.txt').write_text(prefix + '/files/f1')
        jp_root_dir.joinpath(prefix, 'files', 'f2.txt').write_text(prefix + '/files/f2')
        jp_root_dir.joinpath(prefix, 'f2.txt').write_text(prefix + '/f2')
        jp_root_dir.joinpath(prefix, 'f3.txt').write_text(prefix + '/f3')

    # These depend on the tree handlers
    #
    # def test_download(self):
    #     rootdir = self.root_dir

    #     text = 'hello'
    #     with open(pjoin(rootdir, 'test.txt'), 'w') as f:
    #         f.write(text)

    #     r = self.request('GET', 'files/test.txt')
    #     disposition = r.headers.get('Content-Disposition', '')
    #     self.assertNotIn('attachment', disposition)

    #     r = self.request('GET', 'files/test.txt?download=1')
    #     disposition = r.headers.get('Content-Disposition', '')
    #     self.assertIn('attachment', disposition)
    #     self.assertIn("filename*=utf-8''test.txt", disposition)