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">
<thead>
<tr>
<th class="name">Name</th>
<th class="lastModified">Last Modified</th>
<th class="size">Size</th>
<th class="name"><a onclick="sort('name');">Name</a></th>
<th class="last-modified"><a onclick="sort('last-modified');">Last Modified</a></th>
<th class="size"><a onclick="sort('size');">Size</a></th>
<th class="type">Type</th>
</tr>
</thead>
@ -417,6 +417,82 @@ class DirListingHandler(FileBaseHandler):
""" % {'path': os.path.normpath(urllib.unquote(self.path))}
footer = """</tbody></table></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>
</html>""" % {'version': __version__}
content = []

View File

@ -1,4 +1,5 @@
import io
import os
import pytest
import requests
import subprocess
@ -51,21 +52,6 @@ def datadir(tmp_path):
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):
url = '{}://{}:{}{}'.format(protocol, host, port, path)
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
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)
assert r.status_code == 200
assert r.text == expected_data
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'
return r # for additional tests
@ -97,6 +86,7 @@ def test_correct_headers(run_servefile, datadir):
data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p))
r = make_request()
assert r.status_code == 200
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):
data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p))
# redirect
r = make_request(allow_redirects=False)
assert r.status_code == 302
assert r.headers.get('Location') == '/testfile'
r = requests.get("http://127.0.0.1:8080")
download_ok(r, data)
# normal download
check_download(data, fname='testfile')
def test_specify_port(run_servefile, datadir):
data = "NOOT NOOT"
p = datadir({'testfile': data}) / 'testfile'
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):
# test with about 10 mb of data
data = "x" * (10 * 1024 ** 2)
p = datadir({'testfile': data}) / 'testfile'
run_servefile(str(p))
r = make_request()
download_ok(r, data)
check_download(data, fname='testfile')
def test_authentication(run_servefile, datadir):
@ -146,8 +135,7 @@ def test_authentication(run_servefile, datadir):
assert '401 - Unauthorized' in r.text
assert r.status_code == 401
r = make_request(auth=('user', 'password'))
download_ok(r, data)
check_download(data, fname='testfile', auth=('user', 'password'))
def test_serve_directory(run_servefile, datadir):
@ -244,7 +232,7 @@ def test_tar_mode(run_servefile, datadir):
# test contents of tar file
r = make_request()
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 tar.getmember('foo').isdir()
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):
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):