Skip to content

Commit

Permalink
Run tests against both HTTP and HTTPS
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jkbrzt committed Mar 6, 2016
1 parent 5e03aec commit a6ebc44
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 50 deletions.
14 changes: 14 additions & 0 deletions tests/conftest.py
@@ -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
16 changes: 8 additions & 8 deletions tests/test_auth.py
Expand Up @@ -7,17 +7,17 @@
import httpie.cli


def test_basic_auth(httpbin):
def test_basic_auth(httpbin_both):
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 r.json == {'authenticated': True, 'user': 'user'}


@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',
'GET', httpbin.url + '/digest-auth/auth/user/password')
'GET', httpbin_both.url + '/digest-auth/auth/user/password')
assert HTTP_OK in r
assert r.json == {'authenticated': True, 'user': 'user'}

Expand All @@ -31,18 +31,18 @@ def test_password_prompt(httpbin):
assert r.json == {'authenticated': True, 'user': 'user'}


def test_credentials_in_url(httpbin):
url = add_auth(httpbin.url + '/basic-auth/user/password',
def test_credentials_in_url(httpbin_both):
url = add_auth(httpbin_both.url + '/basic-auth/user/password',
auth='user:password')
r = http('GET', url)
assert HTTP_OK in r
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,
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')
r = http('--auth=user:password', 'GET', url)
assert HTTP_OK in r
Expand Down
1 change: 1 addition & 0 deletions tests/test_binary.py
Expand Up @@ -6,6 +6,7 @@


class TestBinaryRequestData:

def test_binary_stdin(self, httpbin):
with open(BIN_FILE_PATH, 'rb') as stdin:
env = TestEnvironment(
Expand Down
20 changes: 10 additions & 10 deletions tests/test_downloads.py
Expand Up @@ -94,21 +94,21 @@ def exists(filename):
class TestDownloads:
# TODO: more tests

def test_actual_download(self, httpbin):
url = httpbin.url + '/robots.txt'
body = urlopen(url).read().decode()
def test_actual_download(self, httpbin_both, httpbin):
robots_txt = '/robots.txt'
body = urlopen(httpbin + robots_txt).read().decode()
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 '[K' in r.stderr
assert 'Done' in r.stderr
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')
downloader = Downloader(output_file=devnull, progress_file=devnull)
downloader.start(Response(
url=httpbin.url + '/',
url=httpbin_both.url + '/',
headers={'Content-Length': 10}
))
time.sleep(1.1)
Expand All @@ -118,20 +118,20 @@ def test_download_with_Content_Length(self, httpbin):
downloader.finish()
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')
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)
downloader.chunk_downloaded(b'12345')
downloader.finish()
assert not downloader.interrupted

def test_download_interrupted(self, httpbin):
def test_download_interrupted(self, httpbin_both):
devnull = open(os.devnull, 'w')
downloader = Downloader(output_file=devnull, progress_file=devnull)
downloader.start(Response(
url=httpbin.url + '/',
url=httpbin_both.url + '/',
headers={'Content-Length': 5}
))
downloader.chunk_downloaded(b'1234')
Expand Down
36 changes: 18 additions & 18 deletions tests/test_httpie.py
Expand Up @@ -26,50 +26,50 @@ def test_version():
assert httpie.__version__ == r.stderr.strip() + r.strip()


def test_GET(httpbin):
r = http('GET', httpbin.url + '/get')
def test_GET(httpbin_both):
r = http('GET', httpbin_both + '/get')
assert HTTP_OK in r


def test_DELETE(httpbin):
r = http('DELETE', httpbin.url + '/delete')
def test_DELETE(httpbin_both):
r = http('DELETE', httpbin_both + '/delete')
assert HTTP_OK in r


def test_PUT(httpbin):
r = http('PUT', httpbin.url + '/put', 'foo=bar')
def test_PUT(httpbin_both):
r = http('PUT', httpbin_both + '/put', 'foo=bar')
assert HTTP_OK in r
assert r.json['json']['foo'] == 'bar'


def test_POST_JSON_data(httpbin):
r = http('POST', httpbin.url + '/post', 'foo=bar')
def test_POST_JSON_data(httpbin_both):
r = http('POST', httpbin_both + '/post', 'foo=bar')
assert HTTP_OK in r
assert r.json['json']['foo'] == 'bar'


def test_POST_form(httpbin):
r = http('--form', 'POST', httpbin.url + '/post', 'foo=bar')
def test_POST_form(httpbin_both):
r = http('--form', 'POST', httpbin_both + '/post', 'foo=bar')
assert HTTP_OK in r
assert '"foo": "bar"' in r


def test_POST_form_multiple_values(httpbin):
r = http('--form', 'POST', httpbin.url + '/post', 'foo=bar', 'foo=baz')
def test_POST_form_multiple_values(httpbin_both):
r = http('--form', 'POST', httpbin_both + '/post', 'foo=bar', 'foo=baz')
assert HTTP_OK in r
assert r.json['form'] == {'foo': ['bar', 'baz']}


def test_POST_stdin(httpbin):
def test_POST_stdin(httpbin_both):
with open(FILE_PATH) as f:
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 FILE_CONTENT in r


def test_headers(httpbin):
r = http('GET', httpbin.url + '/headers', 'Foo:bar')
def test_headers(httpbin_both):
r = http('GET', httpbin_both + '/headers', 'Foo:bar')
assert HTTP_OK in r
assert '"User-Agent": "HTTPie' in r, r
assert '"Foo": "bar"' in r
Expand All @@ -79,8 +79,8 @@ def test_headers(httpbin):
is_py26,
reason='the `object_pairs_hook` arg for `json.loads()` is Py>2.6 only'
)
def test_json_input_preserve_order(httpbin):
r = http('PATCH', httpbin.url + '/patch',
def test_json_input_preserve_order(httpbin_both):
r = http('PATCH', httpbin_both + '/patch',
'order:={"map":{"1":"first","2":"second"}}')
assert HTTP_OK in r
assert r.json['data'] == \
Expand Down
21 changes: 7 additions & 14 deletions tests/test_ssl.py
Expand Up @@ -19,14 +19,10 @@
CA_BUNDLE = pytest_httpbin.certs.where()


@pytest.mark.parametrize(
argnames='ssl_version',
argvalues=SSL_VERSION_ARG_MAPPING.keys()
)
@pytest.mark.parametrize('ssl_version', SSL_VERSION_ARG_MAPPING.keys())
def test_ssl_version(httpbin_secure, ssl_version):
try:
r = http(
'--verify', CA_BUNDLE,
'--ssl', ssl_version,
httpbin_secure + '/get'
)
Expand All @@ -43,20 +39,17 @@ class TestClientCert:

def test_cert_and_key(self, httpbin_secure):
r = http(httpbin_secure + '/get',
'--verify', CA_BUNDLE,
'--cert', CLIENT_CERT,
'--cert-key', CLIENT_KEY)
assert HTTP_OK in r

def test_cert_pem(self, httpbin_secure):
r = http(httpbin_secure + '/get',
'--verify', CA_BUNDLE,
'--cert', CLIENT_PEM)
assert HTTP_OK in r

def test_cert_file_not_found(self, httpbin_secure):
r = http(httpbin_secure + '/get',
'--verify', CA_BUNDLE,
'--cert', '/__not_found__',
error_exit_ok=True)
assert r.exit_status == ExitStatus.ERROR
Expand All @@ -65,30 +58,30 @@ def test_cert_file_not_found(self, httpbin_secure):
def test_cert_file_invalid(self, httpbin_secure):
with pytest.raises(SSLError):
http(httpbin_secure + '/get',
'--verify', CA_BUNDLE,
'--cert', __file__)

def test_cert_ok_but_missing_key(self, httpbin_secure):
with pytest.raises(SSLError):
http(httpbin_secure + '/get',
'--verify', CA_BUNDLE,
'--cert', CLIENT_CERT)


class TestServerCert:

def test_verify_no_OK(self, httpbin_secure):
r = http(httpbin_secure.url + '/get', '--verify=no')
assert HTTP_OK in r

def test_verify_custom_ca_bundle_path(
self, httpbin_secure):
r = http(httpbin_secure.url + '/get', '--verify', CA_BUNDLE)
self, httpbin_secure_untrusted):
r = http(httpbin_secure_untrusted + '/get', '--verify', CA_BUNDLE)
assert HTTP_OK in r

def test_self_signed_server_cert_by_default_raises_ssl_error(
self, httpbin_secure):
self,
httpbin_secure_untrusted):
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):
with pytest.raises(SSLError):
Expand Down

0 comments on commit a6ebc44

Please sign in to comment.