fmt: tests/test_app.py

This commit is contained in:
Matthew Planchard 2019-09-17 20:29:48 -05:00
parent 9496be122f
commit a52c0d6f4c
No known key found for this signature in database
GPG Key ID: 4ABC11DF33394F00

@ -2,6 +2,7 @@
# Builtin imports # Builtin imports
import logging import logging
import os
try: # python 3 try: # python 3
@ -9,6 +10,7 @@ try: # python 3
from html import unescape from html import unescape
except ImportError: except ImportError:
from HTMLParser import HTMLParser from HTMLParser import HTMLParser
unescape = HTMLParser().unescape unescape = HTMLParser().unescape
try: try:
@ -40,6 +42,7 @@ def _app(app):
@pytest.fixture @pytest.fixture
def app(tmpdir): def app(tmpdir):
from pypiserver import app from pypiserver import app
return app(root=tmpdir.strpath, authenticated=[]) return app(root=tmpdir.strpath, authenticated=[])
@ -70,15 +73,17 @@ def testpriv(priv):
@pytest.fixture @pytest.fixture
def search_xml(): def search_xml():
"""Return an xml dom suitable for passing to search""" """Return an xml dom suitable for passing to search"""
xml = '<xml><methodName>search</methodName><string>test</string></xml>' xml = "<xml><methodName>search</methodName><string>test</string></xml>"
return xml return xml
@pytest.fixture(params=[ @pytest.fixture(
" ", # Mustcontain test below fails when string is empty. params=[
"Hey there!", " ", # Mustcontain test below fails when string is empty.
"<html><body>Hey there!</body></html>", "Hey there!",
]) "<html><body>Hey there!</body></html>",
]
)
def welcome_file_no_vars(request, root): def welcome_file_no_vars(request, root):
"""Welcome file fixture """Welcome file fixture
@ -127,37 +132,45 @@ def test_root_hostname(testapp):
def test_root_welcome_msg_no_vars(root, welcome_file_no_vars): def test_root_welcome_msg_no_vars(root, welcome_file_no_vars):
from pypiserver import app from pypiserver import app
app = app(root=root.strpath, welcome_file=welcome_file_no_vars.strpath) app = app(root=root.strpath, welcome_file=welcome_file_no_vars.strpath)
testapp = webtest.TestApp(app) testapp = webtest.TestApp(app)
resp = testapp.get("/") resp = testapp.get("/")
from pypiserver import __version__ as pver from pypiserver import __version__ as pver
resp.mustcontain(welcome_file_no_vars.read(), no=pver) resp.mustcontain(welcome_file_no_vars.read(), no=pver)
def test_root_welcome_msg_all_vars(root, welcome_file_all_vars): def test_root_welcome_msg_all_vars(root, welcome_file_all_vars):
from pypiserver import app from pypiserver import app
app = app(root=root.strpath, welcome_file=welcome_file_all_vars.strpath) app = app(root=root.strpath, welcome_file=welcome_file_all_vars.strpath)
testapp = webtest.TestApp(app) testapp = webtest.TestApp(app)
resp = testapp.get("/") resp = testapp.get("/")
from pypiserver import __version__ as pver from pypiserver import __version__ as pver
resp.mustcontain(pver) resp.mustcontain(pver)
def test_root_welcome_msg_antiXSS(testapp): def test_root_welcome_msg_antiXSS(testapp):
"""https://github.com/pypiserver/pypiserver/issues/77""" """https://github.com/pypiserver/pypiserver/issues/77"""
resp = testapp.get( resp = testapp.get("/?<alert>Red</alert>", headers={"Host": "somehost.org"})
"/?<alert>Red</alert>", headers={"Host": "somehost.org"})
resp.mustcontain("alert", "somehost.org", no="<alert>") resp.mustcontain("alert", "somehost.org", no="<alert>")
def test_root_remove_not_found_msg_antiXSS(testapp): def test_root_remove_not_found_msg_antiXSS(testapp):
"""https://github.com/pypiserver/pypiserver/issues/77""" """https://github.com/pypiserver/pypiserver/issues/77"""
resp = testapp.post("/", expect_errors=True, resp = testapp.post(
headers={"Host": "somehost.org"}, "/",
params={':action': 'remove_pkg', expect_errors=True,
'name': '<alert>Red</alert>', headers={"Host": "somehost.org"},
'version': '1.1.1'}) params={
":action": "remove_pkg",
"name": "<alert>Red</alert>",
"version": "1.1.1",
},
)
resp.mustcontain("alert", "somehost.org", no="<alert>") resp.mustcontain("alert", "somehost.org", no="<alert>")
@ -165,7 +178,7 @@ def test_packages_redirect(testapp):
resp = testapp.get("/packages") resp = testapp.get("/packages")
assert resp.status_code >= 300 assert resp.status_code >= 300
assert resp.status_code < 400 assert resp.status_code < 400
assert resp.location.endswith('/packages/') assert resp.location.endswith("/packages/")
def test_packages_empty(testapp): def test_packages_empty(testapp):
@ -203,7 +216,7 @@ def test_simple_redirect(testapp):
resp = testapp.get("/simple") resp = testapp.get("/simple")
assert resp.status_code >= 300 assert resp.status_code >= 300
assert resp.status_code < 400 assert resp.status_code < 400
assert resp.location.endswith('/simple/') assert resp.location.endswith("/simple/")
def test_simple_list_no_dotfiles(root, testapp): def test_simple_list_no_dotfiles(root, testapp):
@ -245,21 +258,24 @@ def test_simple_name_redirect(testapp):
resp = testapp.get("/simple/foobar") resp = testapp.get("/simple/foobar")
assert resp.status_code >= 300 assert resp.status_code >= 300
assert resp.status_code < 400 assert resp.status_code < 400
assert resp.location.endswith('/simple/foobar/') assert resp.location.endswith("/simple/foobar/")
@pytest.mark.parametrize('package,normalized', [ @pytest.mark.parametrize(
('FooBar', 'foobar'), "package,normalized",
('Foo.Bar', 'foo-bar'), [
('foo_bar', 'foo-bar'), ("FooBar", "foobar"),
('Foo-Bar', 'foo-bar'), ("Foo.Bar", "foo-bar"),
('foo--_.bar', 'foo-bar'), ("foo_bar", "foo-bar"),
]) ("Foo-Bar", "foo-bar"),
("foo--_.bar", "foo-bar"),
],
)
def test_simple_normalized_name_redirect(testapp, package, normalized): def test_simple_normalized_name_redirect(testapp, package, normalized):
resp = testapp.get("/simple/{0}/".format(package)) resp = testapp.get("/simple/{0}/".format(package))
assert resp.status_code >= 300 assert resp.status_code >= 300
assert resp.status_code < 400 assert resp.status_code < 400
assert resp.location.endswith('/simple/{0}/'.format(normalized)) assert resp.location.endswith("/simple/{0}/".format(normalized))
def test_simple_index(root, testapp): def test_simple_index(root, testapp):
@ -316,7 +332,9 @@ def test_nonroot_simple_index(root, testpriv):
def test_nonroot_simple_index_with_x_forwarded_host(root, testapp): def test_nonroot_simple_index_with_x_forwarded_host(root, testapp):
root.join("foobar-1.0.zip").write("") root.join("foobar-1.0.zip").write("")
resp = testapp.get("/simple/foobar/", headers={"X-Forwarded-Host": "forwarded.ed/priv/"}) resp = testapp.get(
"/simple/foobar/", headers={"X-Forwarded-Host": "forwarded.ed/priv/"}
)
links = resp.html("a") links = resp.html("a")
assert len(links) == 1 assert len(links) == 1
assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#") assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#")
@ -332,7 +350,9 @@ def test_nonroot_simple_packages(root, testpriv):
def test_nonroot_simple_packages_with_x_forwarded_host(root, testapp): def test_nonroot_simple_packages_with_x_forwarded_host(root, testapp):
root.join("foobar-1.0.zip").write("123") root.join("foobar-1.0.zip").write("123")
resp = testapp.get("/packages/", headers={"X-Forwarded-Host": "forwarded/priv/"}) resp = testapp.get(
"/packages/", headers={"X-Forwarded-Host": "forwarded/priv/"}
)
links = resp.html("a") links = resp.html("a")
assert len(links) == 1 assert len(links) == 1
assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#") assert links[0]["href"].startswith("/priv/packages/foobar-1.0.zip#")
@ -342,8 +362,11 @@ def test_root_no_relative_paths(testpriv):
"""https://github.com/pypiserver/pypiserver/issues/25""" """https://github.com/pypiserver/pypiserver/issues/25"""
resp = testpriv.get("/priv/") resp = testpriv.get("/priv/")
hrefs = [x["href"] for x in resp.html("a")] hrefs = [x["href"] for x in resp.html("a")]
assert hrefs == ['/priv/packages/', '/priv/simple/', assert hrefs == [
'https://pypi.org/project/pypiserver/'] "/priv/packages/",
"/priv/simple/",
"https://pypi.org/project/pypiserver/",
]
def test_simple_index_list_no_duplicates(root, testapp): def test_simple_index_list_no_duplicates(root, testapp):
@ -391,103 +414,121 @@ def test_no_cache_control_set(root, _app, testapp):
def test_cache_control_set(root): def test_cache_control_set(root):
from pypiserver import app from pypiserver import app
AGE = 86400 AGE = 86400
app_with_cache = webtest.TestApp(app(root=root.strpath, cache_control=AGE)) app_with_cache = webtest.TestApp(app(root=root.strpath, cache_control=AGE))
root.join("foo_bar-1.0.tar.gz").write("") root.join("foo_bar-1.0.tar.gz").write("")
resp = app_with_cache.get("/packages/foo_bar-1.0.tar.gz") resp = app_with_cache.get("/packages/foo_bar-1.0.tar.gz")
assert "Cache-Control" in resp.headers assert "Cache-Control" in resp.headers
assert resp.headers["Cache-Control"] == 'public, max-age=%s' % AGE assert resp.headers["Cache-Control"] == "public, max-age=%s" % AGE
def test_upload_noAction(root, testapp): def test_upload_noAction(root, testapp):
resp = testapp.post("/", expect_errors=1) resp = testapp.post("/", expect_errors=1)
assert resp.status == '400 Bad Request' assert resp.status == "400 Bad Request"
assert "Missing ':action' field!" in unescape(resp.text) assert "Missing ':action' field!" in unescape(resp.text)
def test_upload_badAction(root, testapp): def test_upload_badAction(root, testapp):
resp = testapp.post("/", params={':action': 'BAD'}, expect_errors=1) resp = testapp.post("/", params={":action": "BAD"}, expect_errors=1)
assert resp.status == '400 Bad Request' assert resp.status == "400 Bad Request"
assert "Unsupported ':action' field: BAD" in unescape(resp.text) assert "Unsupported ':action' field: BAD" in unescape(resp.text)
@pytest.mark.parametrize("package", [f[0] @pytest.mark.parametrize(
for f in test_core.files "package", [f[0] for f in test_core.files if f[1] and "/" not in f[0]]
if f[1] and '/' not in f[0]]) )
def test_upload(package, root, testapp): def test_upload(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'}, resp = testapp.post(
upload_files=[('content', package, b'')]) "/",
params={":action": "file_upload"},
upload_files=[("content", package, b"")],
)
assert resp.status_int == 200 assert resp.status_int == 200
uploaded_pkgs = [f.basename for f in root.listdir()] uploaded_pkgs = [f.basename for f in root.listdir()]
assert len(uploaded_pkgs) == 1 assert len(uploaded_pkgs) == 1
assert uploaded_pkgs[0].lower() == package.lower() assert uploaded_pkgs[0].lower() == package.lower()
@pytest.mark.parametrize("package", [f[0] @pytest.mark.parametrize(
for f in test_core.files "package", [f[0] for f in test_core.files if f[1] and "/" not in f[0]]
if f[1] and '/' not in f[0]]) )
def test_upload_with_signature(package, root, testapp): def test_upload_with_signature(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'}, resp = testapp.post(
upload_files=[ "/",
('content', package, b''), params={":action": "file_upload"},
('gpg_signature', '%s.asc' % package, b'')]) upload_files=[
("content", package, b""),
("gpg_signature", "%s.asc" % package, b""),
],
)
assert resp.status_int == 200 assert resp.status_int == 200
uploaded_pkgs = [f.basename.lower() for f in root.listdir()] uploaded_pkgs = [f.basename.lower() for f in root.listdir()]
assert len(uploaded_pkgs) == 2 assert len(uploaded_pkgs) == 2
assert package.lower() in uploaded_pkgs assert package.lower() in uploaded_pkgs
assert '%s.asc' % package.lower() in uploaded_pkgs assert "%s.asc" % package.lower() in uploaded_pkgs
@pytest.mark.parametrize("package", [ @pytest.mark.parametrize(
f[0] for f in test_core.files "package", [f[0] for f in test_core.files if f[1] is None]
if f[1] is None]) )
def test_upload_badFilename(package, root, testapp): def test_upload_badFilename(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'}, resp = testapp.post(
upload_files=[('content', package, b'')], "/",
expect_errors=1) params={":action": "file_upload"},
assert resp.status == '400 Bad Request' upload_files=[("content", package, b"")],
expect_errors=1,
)
assert resp.status == "400 Bad Request"
assert "Bad filename: %s" % package in resp.text assert "Bad filename: %s" % package in resp.text
@pytest.mark.parametrize(("name", "version"), [ @pytest.mark.parametrize(
("name", "version"),
[
(None, None), (None, None),
(None, ''), (None, ""),
('', None), ("", None),
(None, '1'), (None, "1"),
('pkg', None), ("pkg", None),
('', '1'), ("", "1"),
('pkg', ''), ("pkg", ""),
]) ],
)
def test_remove_pkg_missingNaveVersion(name, version, root, testapp): def test_remove_pkg_missingNaveVersion(name, version, root, testapp):
msg = "Missing 'name'/'version' fields: name=%s, version=%s" msg = "Missing 'name'/'version' fields: name=%s, version=%s"
params = {':action': 'remove_pkg', 'name': name, 'version': version} params = {":action": "remove_pkg", "name": name, "version": version}
params = dict((k, v) for k, v in params.items() if v is not None) params = dict((k, v) for k, v in params.items() if v is not None)
resp = testapp.post("/", expect_errors=1, params=params) resp = testapp.post("/", expect_errors=1, params=params)
assert resp.status == '400 Bad Request' assert resp.status == "400 Bad Request"
assert msg % (name, version) in unescape(resp.text) assert msg % (name, version) in unescape(resp.text)
def test_remove_pkg_notFound(root, testapp): def test_remove_pkg_notFound(root, testapp):
resp = testapp.post("/", expect_errors=1, resp = testapp.post(
params={ "/",
':action': 'remove_pkg', expect_errors=1,
'name': 'foo', params={":action": "remove_pkg", "name": "foo", "version": "123"},
'version': '123', )
}) assert resp.status == "404 Not Found"
assert resp.status == '404 Not Found'
assert "foo (123) not found" in unescape(resp.text) assert "foo (123) not found" in unescape(resp.text)
@pytest.mark.parametrize('pkgs,matches', [ @pytest.mark.parametrize(
([], []), "pkgs,matches",
(['test-1.0.tar.gz'], [('test', '1.0')]), [
(['test-1.0.tar.gz', 'test-test-2.0.1.tar.gz'], ([], []),
[('test', '1.0'), ('test-test', '2.0.1')]), (["test-1.0.tar.gz"], [("test", "1.0")]),
(['test-1.0.tar.gz', 'other-2.0.tar.gz'], [('test', '1.0')]), (
(['test-2.0-py2.py3-none-any.whl'], [('test', '2.0')]), ["test-1.0.tar.gz", "test-test-2.0.1.tar.gz"],
(['other-2.0.tar.gz'], []) [("test", "1.0"), ("test-test", "2.0.1")],
]) ),
(["test-1.0.tar.gz", "other-2.0.tar.gz"], [("test", "1.0")]),
(["test-2.0-py2.py3-none-any.whl"], [("test", "2.0")]),
(["other-2.0.tar.gz"], []),
],
)
def test_search(root, testapp, search_xml, pkgs, matches): def test_search(root, testapp, search_xml, pkgs, matches):
"""Test the search functionality at the RPC2 endpoint """Test the search functionality at the RPC2 endpoint
@ -520,18 +561,18 @@ def test_search(root, testapp, search_xml, pkgs, matches):
version) matches for the "test" query version) matches for the "test" query
""" """
for pkg in pkgs: for pkg in pkgs:
root.join(pkg).write('') root.join(pkg).write("")
resp = testapp.post('/RPC2', search_xml) resp = testapp.post("/RPC2", search_xml)
parsed = xmlrpclib.loads(resp.text) parsed = xmlrpclib.loads(resp.text)
assert len(parsed) == 2 and parsed[1] == 'search' assert len(parsed) == 2 and parsed[1] == "search"
if not matches: if not matches:
assert len(parsed[0]) == 1 and not parsed[0][0] assert len(parsed[0]) == 1 and not parsed[0][0]
else: else:
assert len(parsed[0][0]) == len(matches) and parsed[0][0] assert len(parsed[0][0]) == len(matches) and parsed[0][0]
for returned in parsed[0][0]: for returned in parsed[0][0]:
print(returned) print(returned)
assert returned['name'] in [match[0] for match in matches] assert returned["name"] in [match[0] for match in matches]
assert returned['version'] in [match[1] for match in matches] assert returned["version"] in [match[1] for match in matches]
@pytest.mark.xfail() @pytest.mark.xfail()