mirror of
https://github.com/httpie/cli.git
synced 2024-11-25 09:13:25 +01:00
Run tests against both HTTP and HTTPS
Some of the tests now use the `httpbin_both` fixture from pytest-httpbin. Also, made httpbin's CA trusted by default and added `httpbin_secure_untrusted` fixture to allow overriding that for particular tests.
This commit is contained in:
parent
5e03aeceb7
commit
a6ebc44a48
14
tests/conftest.py
Normal file
14
tests/conftest.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import pytest
|
||||||
|
from pytest_httpbin.plugin import httpbin_ca_bundle
|
||||||
|
|
||||||
|
|
||||||
|
# Make httpbin's CA trusted by default
|
||||||
|
pytest.fixture(autouse=True)(httpbin_ca_bundle)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='function')
|
||||||
|
def httpbin_secure_untrusted(monkeypatch, httpbin_secure):
|
||||||
|
"""Like the `httpbin_secure` fixture, but without the
|
||||||
|
make-CA-trusted-by-default"""
|
||||||
|
monkeypatch.delenv('REQUESTS_CA_BUNDLE')
|
||||||
|
return httpbin_secure
|
@ -7,17 +7,17 @@ import httpie.input
|
|||||||
import httpie.cli
|
import httpie.cli
|
||||||
|
|
||||||
|
|
||||||
def test_basic_auth(httpbin):
|
def test_basic_auth(httpbin_both):
|
||||||
r = http('--auth=user:password',
|
r = http('--auth=user:password',
|
||||||
'GET', httpbin.url + '/basic-auth/user/password')
|
'GET', httpbin_both + '/basic-auth/user/password')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json == {'authenticated': True, 'user': 'user'}
|
assert r.json == {'authenticated': True, 'user': 'user'}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('argument_name', ['--auth-type', '-A'])
|
@pytest.mark.parametrize('argument_name', ['--auth-type', '-A'])
|
||||||
def test_digest_auth(httpbin, argument_name):
|
def test_digest_auth(httpbin_both, argument_name):
|
||||||
r = http(argument_name + '=digest', '--auth=user:password',
|
r = http(argument_name + '=digest', '--auth=user:password',
|
||||||
'GET', httpbin.url + '/digest-auth/auth/user/password')
|
'GET', httpbin_both.url + '/digest-auth/auth/user/password')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json == {'authenticated': True, 'user': 'user'}
|
assert r.json == {'authenticated': True, 'user': 'user'}
|
||||||
|
|
||||||
@ -31,18 +31,18 @@ def test_password_prompt(httpbin):
|
|||||||
assert r.json == {'authenticated': True, 'user': 'user'}
|
assert r.json == {'authenticated': True, 'user': 'user'}
|
||||||
|
|
||||||
|
|
||||||
def test_credentials_in_url(httpbin):
|
def test_credentials_in_url(httpbin_both):
|
||||||
url = add_auth(httpbin.url + '/basic-auth/user/password',
|
url = add_auth(httpbin_both.url + '/basic-auth/user/password',
|
||||||
auth='user:password')
|
auth='user:password')
|
||||||
r = http('GET', url)
|
r = http('GET', url)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json == {'authenticated': True, 'user': 'user'}
|
assert r.json == {'authenticated': True, 'user': 'user'}
|
||||||
|
|
||||||
|
|
||||||
def test_credentials_in_url_auth_flag_has_priority(httpbin):
|
def test_credentials_in_url_auth_flag_has_priority(httpbin_both):
|
||||||
"""When credentials are passed in URL and via -a at the same time,
|
"""When credentials are passed in URL and via -a at the same time,
|
||||||
then the ones from -a are used."""
|
then the ones from -a are used."""
|
||||||
url = add_auth(httpbin.url + '/basic-auth/user/password',
|
url = add_auth(httpbin_both.url + '/basic-auth/user/password',
|
||||||
auth='user:wrong')
|
auth='user:wrong')
|
||||||
r = http('--auth=user:password', 'GET', url)
|
r = http('--auth=user:password', 'GET', url)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
@ -6,6 +6,7 @@ from fixtures import BIN_FILE_PATH, BIN_FILE_CONTENT, BIN_FILE_PATH_ARG
|
|||||||
|
|
||||||
|
|
||||||
class TestBinaryRequestData:
|
class TestBinaryRequestData:
|
||||||
|
|
||||||
def test_binary_stdin(self, httpbin):
|
def test_binary_stdin(self, httpbin):
|
||||||
with open(BIN_FILE_PATH, 'rb') as stdin:
|
with open(BIN_FILE_PATH, 'rb') as stdin:
|
||||||
env = TestEnvironment(
|
env = TestEnvironment(
|
||||||
|
@ -94,21 +94,21 @@ class TestDownloadUtils:
|
|||||||
class TestDownloads:
|
class TestDownloads:
|
||||||
# TODO: more tests
|
# TODO: more tests
|
||||||
|
|
||||||
def test_actual_download(self, httpbin):
|
def test_actual_download(self, httpbin_both, httpbin):
|
||||||
url = httpbin.url + '/robots.txt'
|
robots_txt = '/robots.txt'
|
||||||
body = urlopen(url).read().decode()
|
body = urlopen(httpbin + robots_txt).read().decode()
|
||||||
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
||||||
r = http('--download', url, env=env)
|
r = http('--download', httpbin_both.url + robots_txt, env=env)
|
||||||
assert 'Downloading' in r.stderr
|
assert 'Downloading' in r.stderr
|
||||||
assert '[K' in r.stderr
|
assert '[K' in r.stderr
|
||||||
assert 'Done' in r.stderr
|
assert 'Done' in r.stderr
|
||||||
assert body == r
|
assert body == r
|
||||||
|
|
||||||
def test_download_with_Content_Length(self, httpbin):
|
def test_download_with_Content_Length(self, httpbin_both):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
||||||
downloader.start(Response(
|
downloader.start(Response(
|
||||||
url=httpbin.url + '/',
|
url=httpbin_both.url + '/',
|
||||||
headers={'Content-Length': 10}
|
headers={'Content-Length': 10}
|
||||||
))
|
))
|
||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
@ -118,20 +118,20 @@ class TestDownloads:
|
|||||||
downloader.finish()
|
downloader.finish()
|
||||||
assert not downloader.interrupted
|
assert not downloader.interrupted
|
||||||
|
|
||||||
def test_download_no_Content_Length(self, httpbin):
|
def test_download_no_Content_Length(self, httpbin_both):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
||||||
downloader.start(Response(url=httpbin.url + '/'))
|
downloader.start(Response(url=httpbin_both.url + '/'))
|
||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
downloader.chunk_downloaded(b'12345')
|
downloader.chunk_downloaded(b'12345')
|
||||||
downloader.finish()
|
downloader.finish()
|
||||||
assert not downloader.interrupted
|
assert not downloader.interrupted
|
||||||
|
|
||||||
def test_download_interrupted(self, httpbin):
|
def test_download_interrupted(self, httpbin_both):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
downloader = Downloader(output_file=devnull, progress_file=devnull)
|
||||||
downloader.start(Response(
|
downloader.start(Response(
|
||||||
url=httpbin.url + '/',
|
url=httpbin_both.url + '/',
|
||||||
headers={'Content-Length': 5}
|
headers={'Content-Length': 5}
|
||||||
))
|
))
|
||||||
downloader.chunk_downloaded(b'1234')
|
downloader.chunk_downloaded(b'1234')
|
||||||
|
@ -26,50 +26,50 @@ def test_version():
|
|||||||
assert httpie.__version__ == r.stderr.strip() + r.strip()
|
assert httpie.__version__ == r.stderr.strip() + r.strip()
|
||||||
|
|
||||||
|
|
||||||
def test_GET(httpbin):
|
def test_GET(httpbin_both):
|
||||||
r = http('GET', httpbin.url + '/get')
|
r = http('GET', httpbin_both + '/get')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
|
|
||||||
def test_DELETE(httpbin):
|
def test_DELETE(httpbin_both):
|
||||||
r = http('DELETE', httpbin.url + '/delete')
|
r = http('DELETE', httpbin_both + '/delete')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
|
|
||||||
def test_PUT(httpbin):
|
def test_PUT(httpbin_both):
|
||||||
r = http('PUT', httpbin.url + '/put', 'foo=bar')
|
r = http('PUT', httpbin_both + '/put', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json']['foo'] == 'bar'
|
assert r.json['json']['foo'] == 'bar'
|
||||||
|
|
||||||
|
|
||||||
def test_POST_JSON_data(httpbin):
|
def test_POST_JSON_data(httpbin_both):
|
||||||
r = http('POST', httpbin.url + '/post', 'foo=bar')
|
r = http('POST', httpbin_both + '/post', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json']['foo'] == 'bar'
|
assert r.json['json']['foo'] == 'bar'
|
||||||
|
|
||||||
|
|
||||||
def test_POST_form(httpbin):
|
def test_POST_form(httpbin_both):
|
||||||
r = http('--form', 'POST', httpbin.url + '/post', 'foo=bar')
|
r = http('--form', 'POST', httpbin_both + '/post', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert '"foo": "bar"' in r
|
assert '"foo": "bar"' in r
|
||||||
|
|
||||||
|
|
||||||
def test_POST_form_multiple_values(httpbin):
|
def test_POST_form_multiple_values(httpbin_both):
|
||||||
r = http('--form', 'POST', httpbin.url + '/post', 'foo=bar', 'foo=baz')
|
r = http('--form', 'POST', httpbin_both + '/post', 'foo=bar', 'foo=baz')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['form'] == {'foo': ['bar', 'baz']}
|
assert r.json['form'] == {'foo': ['bar', 'baz']}
|
||||||
|
|
||||||
|
|
||||||
def test_POST_stdin(httpbin):
|
def test_POST_stdin(httpbin_both):
|
||||||
with open(FILE_PATH) as f:
|
with open(FILE_PATH) as f:
|
||||||
env = TestEnvironment(stdin=f, stdin_isatty=False)
|
env = TestEnvironment(stdin=f, stdin_isatty=False)
|
||||||
r = http('--form', 'POST', httpbin.url + '/post', env=env)
|
r = http('--form', 'POST', httpbin_both + '/post', env=env)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert FILE_CONTENT in r
|
assert FILE_CONTENT in r
|
||||||
|
|
||||||
|
|
||||||
def test_headers(httpbin):
|
def test_headers(httpbin_both):
|
||||||
r = http('GET', httpbin.url + '/headers', 'Foo:bar')
|
r = http('GET', httpbin_both + '/headers', 'Foo:bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert '"User-Agent": "HTTPie' in r, r
|
assert '"User-Agent": "HTTPie' in r, r
|
||||||
assert '"Foo": "bar"' in r
|
assert '"Foo": "bar"' in r
|
||||||
@ -79,8 +79,8 @@ def test_headers(httpbin):
|
|||||||
is_py26,
|
is_py26,
|
||||||
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'
|
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'
|
||||||
)
|
)
|
||||||
def test_json_input_preserve_order(httpbin):
|
def test_json_input_preserve_order(httpbin_both):
|
||||||
r = http('PATCH', httpbin.url + '/patch',
|
r = http('PATCH', httpbin_both + '/patch',
|
||||||
'order:={"map":{"1":"first","2":"second"}}')
|
'order:={"map":{"1":"first","2":"second"}}')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['data'] == \
|
assert r.json['data'] == \
|
||||||
|
@ -19,14 +19,10 @@ CLIENT_PEM = os.path.join(TESTS_ROOT, 'client_certs', 'client.pem')
|
|||||||
CA_BUNDLE = pytest_httpbin.certs.where()
|
CA_BUNDLE = pytest_httpbin.certs.where()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize('ssl_version', SSL_VERSION_ARG_MAPPING.keys())
|
||||||
argnames='ssl_version',
|
|
||||||
argvalues=SSL_VERSION_ARG_MAPPING.keys()
|
|
||||||
)
|
|
||||||
def test_ssl_version(httpbin_secure, ssl_version):
|
def test_ssl_version(httpbin_secure, ssl_version):
|
||||||
try:
|
try:
|
||||||
r = http(
|
r = http(
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--ssl', ssl_version,
|
'--ssl', ssl_version,
|
||||||
httpbin_secure + '/get'
|
httpbin_secure + '/get'
|
||||||
)
|
)
|
||||||
@ -43,20 +39,17 @@ class TestClientCert:
|
|||||||
|
|
||||||
def test_cert_and_key(self, httpbin_secure):
|
def test_cert_and_key(self, httpbin_secure):
|
||||||
r = http(httpbin_secure + '/get',
|
r = http(httpbin_secure + '/get',
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--cert', CLIENT_CERT,
|
'--cert', CLIENT_CERT,
|
||||||
'--cert-key', CLIENT_KEY)
|
'--cert-key', CLIENT_KEY)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_cert_pem(self, httpbin_secure):
|
def test_cert_pem(self, httpbin_secure):
|
||||||
r = http(httpbin_secure + '/get',
|
r = http(httpbin_secure + '/get',
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--cert', CLIENT_PEM)
|
'--cert', CLIENT_PEM)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_cert_file_not_found(self, httpbin_secure):
|
def test_cert_file_not_found(self, httpbin_secure):
|
||||||
r = http(httpbin_secure + '/get',
|
r = http(httpbin_secure + '/get',
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--cert', '/__not_found__',
|
'--cert', '/__not_found__',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
assert r.exit_status == ExitStatus.ERROR
|
assert r.exit_status == ExitStatus.ERROR
|
||||||
@ -65,30 +58,30 @@ class TestClientCert:
|
|||||||
def test_cert_file_invalid(self, httpbin_secure):
|
def test_cert_file_invalid(self, httpbin_secure):
|
||||||
with pytest.raises(SSLError):
|
with pytest.raises(SSLError):
|
||||||
http(httpbin_secure + '/get',
|
http(httpbin_secure + '/get',
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--cert', __file__)
|
'--cert', __file__)
|
||||||
|
|
||||||
def test_cert_ok_but_missing_key(self, httpbin_secure):
|
def test_cert_ok_but_missing_key(self, httpbin_secure):
|
||||||
with pytest.raises(SSLError):
|
with pytest.raises(SSLError):
|
||||||
http(httpbin_secure + '/get',
|
http(httpbin_secure + '/get',
|
||||||
'--verify', CA_BUNDLE,
|
|
||||||
'--cert', CLIENT_CERT)
|
'--cert', CLIENT_CERT)
|
||||||
|
|
||||||
|
|
||||||
class TestServerCert:
|
class TestServerCert:
|
||||||
|
|
||||||
def test_verify_no_OK(self, httpbin_secure):
|
def test_verify_no_OK(self, httpbin_secure):
|
||||||
r = http(httpbin_secure.url + '/get', '--verify=no')
|
r = http(httpbin_secure.url + '/get', '--verify=no')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_verify_custom_ca_bundle_path(
|
def test_verify_custom_ca_bundle_path(
|
||||||
self, httpbin_secure):
|
self, httpbin_secure_untrusted):
|
||||||
r = http(httpbin_secure.url + '/get', '--verify', CA_BUNDLE)
|
r = http(httpbin_secure_untrusted + '/get', '--verify', CA_BUNDLE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_self_signed_server_cert_by_default_raises_ssl_error(
|
def test_self_signed_server_cert_by_default_raises_ssl_error(
|
||||||
self, httpbin_secure):
|
self,
|
||||||
|
httpbin_secure_untrusted):
|
||||||
with pytest.raises(SSLError):
|
with pytest.raises(SSLError):
|
||||||
http(httpbin_secure.url + '/get')
|
http(httpbin_secure_untrusted.url + '/get')
|
||||||
|
|
||||||
def test_verify_custom_ca_bundle_invalid_path(self, httpbin_secure):
|
def test_verify_custom_ca_bundle_invalid_path(self, httpbin_secure):
|
||||||
with pytest.raises(SSLError):
|
with pytest.raises(SSLError):
|
||||||
|
Loading…
Reference in New Issue
Block a user