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
1 changed files with 124 additions and 83 deletions

View File

@ -2,6 +2,7 @@
# Builtin imports
import logging
import os
try: # python 3
@ -9,6 +10,7 @@ try: # python 3
from html import unescape
except ImportError:
from HTMLParser import HTMLParser
unescape = HTMLParser().unescape
try:
@ -40,6 +42,7 @@ def _app(app):
@pytest.fixture
def app(tmpdir):
from pypiserver import app
return app(root=tmpdir.strpath, authenticated=[])
@ -70,15 +73,17 @@ def testpriv(priv):
@pytest.fixture
def search_xml():
"""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
@pytest.fixture(params=[
" ", # Mustcontain test below fails when string is empty.
"Hey there!",
"<html><body>Hey there!</body></html>",
])
@pytest.fixture(
params=[
" ", # Mustcontain test below fails when string is empty.
"Hey there!",
"<html><body>Hey there!</body></html>",
]
)
def welcome_file_no_vars(request, root):
"""Welcome file fixture
@ -127,37 +132,45 @@ def test_root_hostname(testapp):
def test_root_welcome_msg_no_vars(root, welcome_file_no_vars):
from pypiserver import app
app = app(root=root.strpath, welcome_file=welcome_file_no_vars.strpath)
testapp = webtest.TestApp(app)
resp = testapp.get("/")
from pypiserver import __version__ as pver
resp.mustcontain(welcome_file_no_vars.read(), no=pver)
def test_root_welcome_msg_all_vars(root, welcome_file_all_vars):
from pypiserver import app
app = app(root=root.strpath, welcome_file=welcome_file_all_vars.strpath)
testapp = webtest.TestApp(app)
resp = testapp.get("/")
from pypiserver import __version__ as pver
resp.mustcontain(pver)
def test_root_welcome_msg_antiXSS(testapp):
"""https://github.com/pypiserver/pypiserver/issues/77"""
resp = testapp.get(
"/?<alert>Red</alert>", headers={"Host": "somehost.org"})
resp = testapp.get("/?<alert>Red</alert>", headers={"Host": "somehost.org"})
resp.mustcontain("alert", "somehost.org", no="<alert>")
def test_root_remove_not_found_msg_antiXSS(testapp):
"""https://github.com/pypiserver/pypiserver/issues/77"""
resp = testapp.post("/", expect_errors=True,
headers={"Host": "somehost.org"},
params={':action': 'remove_pkg',
'name': '<alert>Red</alert>',
'version': '1.1.1'})
resp = testapp.post(
"/",
expect_errors=True,
headers={"Host": "somehost.org"},
params={
":action": "remove_pkg",
"name": "<alert>Red</alert>",
"version": "1.1.1",
},
)
resp.mustcontain("alert", "somehost.org", no="<alert>")
@ -165,7 +178,7 @@ def test_packages_redirect(testapp):
resp = testapp.get("/packages")
assert resp.status_code >= 300
assert resp.status_code < 400
assert resp.location.endswith('/packages/')
assert resp.location.endswith("/packages/")
def test_packages_empty(testapp):
@ -203,7 +216,7 @@ def test_simple_redirect(testapp):
resp = testapp.get("/simple")
assert resp.status_code >= 300
assert resp.status_code < 400
assert resp.location.endswith('/simple/')
assert resp.location.endswith("/simple/")
def test_simple_list_no_dotfiles(root, testapp):
@ -245,21 +258,24 @@ def test_simple_name_redirect(testapp):
resp = testapp.get("/simple/foobar")
assert resp.status_code >= 300
assert resp.status_code < 400
assert resp.location.endswith('/simple/foobar/')
assert resp.location.endswith("/simple/foobar/")
@pytest.mark.parametrize('package,normalized', [
('FooBar', 'foobar'),
('Foo.Bar', 'foo-bar'),
('foo_bar', 'foo-bar'),
('Foo-Bar', 'foo-bar'),
('foo--_.bar', 'foo-bar'),
])
@pytest.mark.parametrize(
"package,normalized",
[
("FooBar", "foobar"),
("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):
resp = testapp.get("/simple/{0}/".format(package))
assert resp.status_code >= 300
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):
@ -316,7 +332,9 @@ def test_nonroot_simple_index(root, testpriv):
def test_nonroot_simple_index_with_x_forwarded_host(root, testapp):
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")
assert len(links) == 1
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):
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")
assert len(links) == 1
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"""
resp = testpriv.get("/priv/")
hrefs = [x["href"] for x in resp.html("a")]
assert hrefs == ['/priv/packages/', '/priv/simple/',
'https://pypi.org/project/pypiserver/']
assert hrefs == [
"/priv/packages/",
"/priv/simple/",
"https://pypi.org/project/pypiserver/",
]
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):
from pypiserver import app
AGE = 86400
app_with_cache = webtest.TestApp(app(root=root.strpath, cache_control=AGE))
root.join("foo_bar-1.0.tar.gz").write("")
resp = app_with_cache.get("/packages/foo_bar-1.0.tar.gz")
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):
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)
def test_upload_badAction(root, testapp):
resp = testapp.post("/", params={':action': 'BAD'}, expect_errors=1)
assert resp.status == '400 Bad Request'
resp = testapp.post("/", params={":action": "BAD"}, expect_errors=1)
assert resp.status == "400 Bad Request"
assert "Unsupported ':action' field: BAD" in unescape(resp.text)
@pytest.mark.parametrize("package", [f[0]
for f in test_core.files
if f[1] and '/' not in f[0]])
@pytest.mark.parametrize(
"package", [f[0] for f in test_core.files if f[1] and "/" not in f[0]]
)
def test_upload(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'},
upload_files=[('content', package, b'')])
resp = testapp.post(
"/",
params={":action": "file_upload"},
upload_files=[("content", package, b"")],
)
assert resp.status_int == 200
uploaded_pkgs = [f.basename for f in root.listdir()]
assert len(uploaded_pkgs) == 1
assert uploaded_pkgs[0].lower() == package.lower()
@pytest.mark.parametrize("package", [f[0]
for f in test_core.files
if f[1] and '/' not in f[0]])
@pytest.mark.parametrize(
"package", [f[0] for f in test_core.files if f[1] and "/" not in f[0]]
)
def test_upload_with_signature(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'},
upload_files=[
('content', package, b''),
('gpg_signature', '%s.asc' % package, b'')])
resp = testapp.post(
"/",
params={":action": "file_upload"},
upload_files=[
("content", package, b""),
("gpg_signature", "%s.asc" % package, b""),
],
)
assert resp.status_int == 200
uploaded_pkgs = [f.basename.lower() for f in root.listdir()]
assert len(uploaded_pkgs) == 2
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", [
f[0] for f in test_core.files
if f[1] is None])
@pytest.mark.parametrize(
"package", [f[0] for f in test_core.files if f[1] is None]
)
def test_upload_badFilename(package, root, testapp):
resp = testapp.post("/", params={':action': 'file_upload'},
upload_files=[('content', package, b'')],
expect_errors=1)
assert resp.status == '400 Bad Request'
resp = testapp.post(
"/",
params={":action": "file_upload"},
upload_files=[("content", package, b"")],
expect_errors=1,
)
assert resp.status == "400 Bad Request"
assert "Bad filename: %s" % package in resp.text
@pytest.mark.parametrize(("name", "version"), [
@pytest.mark.parametrize(
("name", "version"),
[
(None, None),
(None, ''),
('', None),
(None, '1'),
('pkg', None),
('', '1'),
('pkg', ''),
])
(None, ""),
("", None),
(None, "1"),
("pkg", None),
("", "1"),
("pkg", ""),
],
)
def test_remove_pkg_missingNaveVersion(name, version, root, testapp):
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)
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)
def test_remove_pkg_notFound(root, testapp):
resp = testapp.post("/", expect_errors=1,
params={
':action': 'remove_pkg',
'name': 'foo',
'version': '123',
})
assert resp.status == '404 Not Found'
resp = testapp.post(
"/",
expect_errors=1,
params={":action": "remove_pkg", "name": "foo", "version": "123"},
)
assert resp.status == "404 Not Found"
assert "foo (123) not found" in unescape(resp.text)
@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', 'other-2.0.tar.gz'], [('test', '1.0')]),
(['test-2.0-py2.py3-none-any.whl'], [('test', '2.0')]),
(['other-2.0.tar.gz'], [])
])
@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", "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):
"""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
"""
for pkg in pkgs:
root.join(pkg).write('')
resp = testapp.post('/RPC2', search_xml)
root.join(pkg).write("")
resp = testapp.post("/RPC2", search_xml)
parsed = xmlrpclib.loads(resp.text)
assert len(parsed) == 2 and parsed[1] == 'search'
assert len(parsed) == 2 and parsed[1] == "search"
if not matches:
assert len(parsed[0]) == 1 and not parsed[0][0]
else:
assert len(parsed[0][0]) == len(matches) and parsed[0][0]
for returned in parsed[0][0]:
print(returned)
assert returned['name'] in [match[0] for match in matches]
assert returned['version'] in [match[1] for match in matches]
assert returned["name"] in [match[0] for match in matches]
assert returned["version"] in [match[1] for match in matches]
@pytest.mark.xfail()