diff --git a/httpie/client.py b/httpie/client.py index 999a0722..899535b4 100644 --- a/httpie/client.py +++ b/httpie/client.py @@ -3,7 +3,7 @@ import sys import http.client import requests -from decorator import contextmanager +from contextlib import contextmanager from requests.adapters import HTTPAdapter from requests.structures import CaseInsensitiveDict diff --git a/tests/test_compress.py b/tests/test_compress.py new file mode 100644 index 00000000..089ea619 --- /dev/null +++ b/tests/test_compress.py @@ -0,0 +1,110 @@ +""" +We test against httpbin which doesn't return the request data in a +consistent way: + +1. Non-form requests: the `data` field contains base64 encoded version of +our zlib-encoded request data. + +2. Form requests: `form` contains a messed up version of the data. + +""" +import base64 +import zlib + +from fixtures import FILE_PATH, FILE_CONTENT +from utils import http, HTTP_OK, MockEnvironment + + +def assert_decompressed_equal(base64_compressed_data, expected_str): + compressed_data = base64.b64decode( + base64_compressed_data.split(',', 1)[1]) + data = zlib.decompress(compressed_data) + actual_str = data.decode() + + # FIXME: contains a trailing linebreak with an uploaded file + actual_str = actual_str.rstrip() + + assert actual_str == expected_str + + +def test_compress_skip_negative_ratio(httpbin_both): + r = http( + '--compress', + httpbin_both + '/post', + 'foo=bar', + ) + assert HTTP_OK in r + assert 'Content-Encoding' not in r.json['headers'] + assert r.json['json'] == {'foo': 'bar'} + + +def test_compress_force_with_negative_ratio(httpbin_both): + r = http( + '--compress', + '--compress', + httpbin_both + '/post', + 'foo=bar', + ) + assert HTTP_OK in r + assert r.json['headers']['Content-Encoding'] == 'deflate' + assert_decompressed_equal(r.json['data'], '{"foo": "bar"}') + + +def test_compress_json(httpbin_both): + r = http( + '--compress', + '--compress', + httpbin_both + '/post', + 'foo=bar', + ) + assert HTTP_OK in r + assert r.json['headers']['Content-Encoding'] == 'deflate' + assert_decompressed_equal(r.json['data'], '{"foo": "bar"}') + assert r.json['json'] is None + + +def test_compress_form(httpbin_both): + r = http( + '--form', + '--compress', + '--compress', + httpbin_both + '/post', + 'foo=bar', + ) + assert HTTP_OK in r + assert r.json['headers']['Content-Encoding'] == 'deflate' + assert r.json['data'] == "" + assert '"foo": "bar"' not in r + + +def test_compress_stdin(httpbin_both): + with open(FILE_PATH) as f: + env = MockEnvironment(stdin=f, stdin_isatty=False) + r = http( + '--compress', + '--compress', + 'PATCH', + httpbin_both + '/patch', + env=env, + ) + assert HTTP_OK in r + assert r.json['headers']['Content-Encoding'] == 'deflate' + assert_decompressed_equal(r.json['data'], FILE_CONTENT.strip()) + assert not r.json['json'] + + +def test_compress_file(httpbin_both): + r = http( + '--form', + '--compress', + '--compress', + 'PUT', + httpbin_both + '/put', + 'file@' + FILE_PATH, + ) + assert HTTP_OK in r + assert r.json['headers']['Content-Encoding'] == 'deflate' + assert r.json['headers']['Content-Type'].startswith( + 'multipart/form-data; boundary=') + assert r.json['files'] == {} + assert FILE_CONTENT not in r diff --git a/tests/test_httpie.py b/tests/test_httpie.py index 7123d19c..745e18e2 100644 --- a/tests/test_httpie.py +++ b/tests/test_httpie.py @@ -49,28 +49,12 @@ def test_POST_JSON_data(httpbin_both): assert r.json['json']['foo'] == 'bar' -def test_POST_JSON_data_compressed(httpbin_both): - r = http('--compress', '--compress', 'POST', httpbin_both + '/post', 'foo=bar') - assert HTTP_OK in r - assert r.json['headers']['Content-Encoding'] == 'deflate' - assert r.json['data'].startswith('data:application/octet-stream;') - assert r.json['json'] is None - - 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_compressed(httpbin_both): - r = http('--form', '--compress', '--compress', 'POST', httpbin_both + '/post', 'foo=bar') - assert HTTP_OK in r - assert r.json['headers']['Content-Encoding'] == 'deflate' - assert r.json['data'] == "" - assert '"foo": "bar"' not in r - - def test_POST_form_multiple_values(httpbin_both): r = http('--form', 'POST', httpbin_both + '/post', 'foo=bar', 'foo=baz') assert HTTP_OK in r @@ -85,31 +69,12 @@ def test_POST_stdin(httpbin_both): assert FILE_CONTENT in r -def test_POST_stdin_compressed(httpbin_both): - with open(FILE_PATH) as f: - env = MockEnvironment(stdin=f, stdin_isatty=False) - r = http('--form', '--compress', '--compress', 'POST', httpbin_both + '/post', env=env) - assert HTTP_OK in r - assert r.json['headers']['Content-Encoding'] == 'deflate' - assert r.json['data'] == "" - assert FILE_CONTENT not in r - - def test_POST_file(httpbin_both): r = http('--form', 'POST', httpbin_both + '/post', 'file@' + FILE_PATH) assert HTTP_OK in r assert FILE_CONTENT in r -def test_POST_file_compressed(httpbin_both): - r = http('--form', '--compress', '--compress', 'POST', httpbin_both + '/post', 'file@' + FILE_PATH) - assert HTTP_OK in r - assert r.json['headers']['Content-Encoding'] == 'deflate' - assert r.json['headers']['Content-Type'].startswith('multipart/form-data; boundary=') - assert r.json['files'] == {} - assert FILE_CONTENT not in r - - def test_headers(httpbin_both): r = http('GET', httpbin_both + '/headers', 'Foo:bar') assert HTTP_OK in r diff --git a/tests/utils.py b/tests/utils.py index d51f8cb9..19939ca3 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -108,7 +108,7 @@ class StrCLIResponse(str, BaseCLIResponse): def json(self): """ Return deserialized JSON body, if one included in the output - and is parseable. + and is parsable. """ if not hasattr(self, '_json'):