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:
Jakub Roztocil 2016-03-06 17:42:35 +08:00
parent 5e03aeceb7
commit a6ebc44a48
6 changed files with 58 additions and 50 deletions

14
tests/conftest.py Normal file
View 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

View File

@ -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

View File

@ -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(

View File

@ -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')

View File

@ -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'] == \

View File

@ -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):