From a6ebc44a488ed8f25ba4056c974d2060e16e6953 Mon Sep 17 00:00:00 2001 From: Jakub Roztocil Date: Sun, 6 Mar 2016 17:42:35 +0800 Subject: [PATCH] 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. --- tests/conftest.py | 14 ++++++++++++++ tests/test_auth.py | 16 ++++++++-------- tests/test_binary.py | 1 + tests/test_downloads.py | 20 ++++++++++---------- tests/test_httpie.py | 36 ++++++++++++++++++------------------ tests/test_ssl.py | 21 +++++++-------------- 6 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 tests/conftest.py diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..4b4a8bac --- /dev/null +++ b/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 diff --git a/tests/test_auth.py b/tests/test_auth.py index f3d1df88..1d7395b6 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -7,17 +7,17 @@ import httpie.input 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'} @@ -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 diff --git a/tests/test_binary.py b/tests/test_binary.py index 7c112045..9d4702e9 100644 --- a/tests/test_binary.py +++ b/tests/test_binary.py @@ -6,6 +6,7 @@ from fixtures import BIN_FILE_PATH, BIN_FILE_CONTENT, BIN_FILE_PATH_ARG class TestBinaryRequestData: + def test_binary_stdin(self, httpbin): with open(BIN_FILE_PATH, 'rb') as stdin: env = TestEnvironment( diff --git a/tests/test_downloads.py b/tests/test_downloads.py index 456886b5..2d973c33 100644 --- a/tests/test_downloads.py +++ b/tests/test_downloads.py @@ -94,21 +94,21 @@ class TestDownloadUtils: 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) @@ -118,20 +118,20 @@ class TestDownloads: 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') diff --git a/tests/test_httpie.py b/tests/test_httpie.py index dd48b1d1..dcfb0d76 100644 --- a/tests/test_httpie.py +++ b/tests/test_httpie.py @@ -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 @@ -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'] == \ diff --git a/tests/test_ssl.py b/tests/test_ssl.py index b2c7108a..a5ed54cd 100644 --- a/tests/test_ssl.py +++ b/tests/test_ssl.py @@ -19,14 +19,10 @@ CLIENT_PEM = os.path.join(TESTS_ROOT, 'client_certs', 'client.pem') 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' ) @@ -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 @@ -65,30 +58,30 @@ class TestClientCert: 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):