Compare commits

..

4 Commits

Author SHA1 Message Date
Sebastian Lohff 1ec1671cb1 Refactor tests, add compression test 2019-02-17 20:55:37 +01:00
Sebastian Lohff 0dcd09ac80 Python3 compability for tests 2019-02-17 20:55:37 +01:00
Sebastian Lohff ae1800e157 Initial tests 2019-02-17 20:55:37 +01:00
MasterofJOKers 08ac08718b List view allows sorting by "Last Modified", "Name", "Size"
This is implemented in JavaScript, because for implementing it in
Python, the concept of creating the directory listing view would have to
be changed.
2019-02-17 20:19:22 +01:00
2 changed files with 103 additions and 32 deletions

View File

@ -407,9 +407,9 @@ class DirListingHandler(FileBaseHandler):
<table summary="Directory Listing"> <table summary="Directory Listing">
<thead> <thead>
<tr> <tr>
<th class="name">Name</th> <th class="name"><a onclick="sort('name');">Name</a></th>
<th class="lastModified">Last Modified</th> <th class="last-modified"><a onclick="sort('last-modified');">Last Modified</a></th>
<th class="size">Size</th> <th class="size"><a onclick="sort('size');">Size</a></th>
<th class="type">Type</th> <th class="type">Type</th>
</tr> </tr>
</thead> </thead>
@ -417,6 +417,82 @@ class DirListingHandler(FileBaseHandler):
""" % {'path': os.path.normpath(urllib.unquote(self.path))} """ % {'path': os.path.normpath(urllib.unquote(self.path))}
footer = """</tbody></table></div> footer = """</tbody></table></div>
<div class="footer"><a href="http://seba-geek.de/stuff/servefile/">servefile %(version)s</a></div> <div class="footer"><a href="http://seba-geek.de/stuff/servefile/">servefile %(version)s</a></div>
<script>
function unhumanize(text){
var powers = {'K': 1, 'M': 2, 'G': 3, 'T': 4};
var number = parseFloat(text.slice(0, text.length - 1));
var unit = text.slice(text.length - 1);
return number * Math.pow(1024, powers[unit]);
}
function compare_class(cls, modifier, a, b){
var atext = a.getElementsByClassName(cls).item(0).textContent,
btext = b.getElementsByClassName(cls).item(0).textContent,
atype = a.getElementsByClassName("type").item(0).innerHTML,
btype = b.getElementsByClassName("type").item(0).innerHTML;
// always keep directories on top
if (atype !== btype) {
if (atype === "Directory")
return -1
if (btype === "Directory")
return 1
}
if (cls === "name"){
if (atype === "Directory")
atext = atext.slice(0, atext.length - 1);
if (btype === "Directory")
btext = btext.slice(0, btext.length - 1);
}
if (cls === "size"){
aint = unhumanize(atext);
bint = unhumanize(btext);
// don't change the order of same-size objects
if (aint === bint)
return 1;
return aint > bint ? modifier : -modifier;
}
else
return atext.localeCompare(btext) * modifier;
}
function move_rows(e, i, a){
if (i === a.length - 1)
return;
var par = e.parentNode,
next = e.nextSibling;
if (next === a[i+1])
return;
par.removeChild(a[i+1]);
if (next)
par.insertBefore(a[i+1], next);
else
par.appendChild(a[i+1]);
}
function sort(cls){
var arr = Array.prototype.slice.call(document.getElementsByTagName("tr"));
var e = arr.shift();
if (!e.sort_modifier || e.sort_cls !== cls)
if (cls === "name")
e.sort_modifier = -1;
else
e.sort_modifier = 1;
e.sort_cls = cls;
e.sort_modifier = -1 * e.sort_modifier;
arr = arr.sort(function (a, b) { return compare_class(cls, e.sort_modifier, a, b); });
arr.forEach(move_rows);
}
var e = document.getElementsByTagName("tr").item(0);
e.sort_modifier = 1;
e.sort_cls = "name";
</script>
</body> </body>
</html>""" % {'version': __version__} </html>""" % {'version': __version__}
content = [] content = []

View File

@ -1,4 +1,5 @@
import io import io
import os
import pytest import pytest
import requests import requests
import subprocess import subprocess
@ -51,21 +52,6 @@ def datadir(tmp_path):
return _datadir return _datadir
@pytest.fixture(scope='class')
def servefile_simple(run_servefile, datadir):
data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p))
return dict(host='localhost', port=8080, protocol='http')
def download_ok(r, expected_data, expected_code=200):
assert r.status_code == expected_code
assert r.text == expected_data
def make_request(path='/', host='localhost', port=8080, method='get', protocol='http', **kwargs): def make_request(path='/', host='localhost', port=8080, method='get', protocol='http', **kwargs):
url = '{}://{}:{}{}'.format(protocol, host, port, path) url = '{}://{}:{}{}'.format(protocol, host, port, path)
print('Calling {} on {} with {}'.format(method, url, kwargs)) print('Calling {} on {} with {}'.format(method, url, kwargs))
@ -74,12 +60,15 @@ def make_request(path='/', host='localhost', port=8080, method='get', protocol='
return r return r
def check_download(expected_data=None, path='/', status_code=200, **kwargs): def check_download(expected_data=None, path='/', fname=None, status_code=200, **kwargs):
if fname is None:
fname = os.path.basename(path)
r = make_request(path, **kwargs) r = make_request(path, **kwargs)
assert r.status_code == 200 assert r.status_code == 200
assert r.text == expected_data assert r.text == expected_data
assert r.headers.get('Content-Type') == 'application/octet-stream' assert r.headers.get('Content-Type') == 'application/octet-stream'
# assert r.headers.get('Content-Disposition') == 'attachment; filename=""' if fname:
assert r.headers.get('Content-Disposition') == 'attachment; filename="{}"'.format(fname)
assert r.headers.get('Content-Transfer-Encoding') == 'binary' assert r.headers.get('Content-Transfer-Encoding') == 'binary'
return r # for additional tests return r # for additional tests
@ -97,6 +86,7 @@ def test_correct_headers(run_servefile, datadir):
data = "NOOT NOOT" data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile' p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p)) run_servefile(str(p))
r = make_request() r = make_request()
assert r.status_code == 200 assert r.status_code == 200
assert r.headers.get('Content-Type') == 'application/octet-stream' assert r.headers.get('Content-Type') == 'application/octet-stream'
@ -107,33 +97,32 @@ def test_correct_headers(run_servefile, datadir):
def test_redirect_and_download(run_servefile, datadir): def test_redirect_and_download(run_servefile, datadir):
data = "NOOT NOOT" data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile' p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p)) run_servefile(str(p))
# redirect
r = make_request(allow_redirects=False) r = make_request(allow_redirects=False)
assert r.status_code == 302 assert r.status_code == 302
assert r.headers.get('Location') == '/testfile' assert r.headers.get('Location') == '/testfile'
r = requests.get("http://127.0.0.1:8080") # normal download
download_ok(r, data) check_download(data, fname='testfile')
def test_specify_port(run_servefile, datadir): def test_specify_port(run_servefile, datadir):
data = "NOOT NOOT" data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile' p = datadir({'testfile': data}) / 'testfile'
run_servefile([str(p), '-p', '8081']) run_servefile([str(p), '-p', '8081'])
r = make_request(port=8081)
download_ok(r, data) check_download(data, fname='testfile', port=8081)
def test_big_download(run_servefile, datadir): def test_big_download(run_servefile, datadir):
# test with about 10 mb of data # test with about 10 mb of data
data = "x" * (10 * 1024 ** 2) data = "x" * (10 * 1024 ** 2)
p = datadir({'testfile': data}) / 'testfile' p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p)) run_servefile(str(p))
r = make_request()
download_ok(r, data) check_download(data, fname='testfile')
def test_authentication(run_servefile, datadir): def test_authentication(run_servefile, datadir):
@ -146,8 +135,7 @@ def test_authentication(run_servefile, datadir):
assert '401 - Unauthorized' in r.text assert '401 - Unauthorized' in r.text
assert r.status_code == 401 assert r.status_code == 401
r = make_request(auth=('user', 'password')) check_download(data, fname='testfile', auth=('user', 'password'))
download_ok(r, data)
def test_serve_directory(run_servefile, datadir): def test_serve_directory(run_servefile, datadir):
@ -244,7 +232,7 @@ def test_tar_mode(run_servefile, datadir):
# test contents of tar file # test contents of tar file
r = make_request() r = make_request()
assert r.status_code == 200 assert r.status_code == 200
tar = tarfile.open(fileobj=io.BytesIO(r.text.encode())) tar = tarfile.open(fileobj=io.BytesIO(r.content))
assert len(tar.getmembers()) == 3 assert len(tar.getmembers()) == 3
assert tar.getmember('foo').isdir() assert tar.getmember('foo').isdir()
for filename, content in d['foo'].items(): for filename, content in d['foo'].items():
@ -254,7 +242,14 @@ def test_tar_mode(run_servefile, datadir):
def test_tar_compression(run_servefile, datadir): def test_tar_compression(run_servefile, datadir):
pass d = {'foo': 'blubb'}
p = datadir(d)
run_servefile(['-c', 'gzip', '-t', str(p / 'foo')])
r = make_request()
assert r.status_code == 200
tar = tarfile.open(fileobj=io.BytesIO(r.content), mode='r:gz')
assert len(tar.getmembers()) == 1
def test_https(run_servefile, datadir): def test_https(run_servefile, datadir):