XX
This commit is contained in:
Jakub Roztocil 2014-04-24 15:48:01 +02:00
parent 6f28624134
commit 3cb124bba7
13 changed files with 230 additions and 634 deletions

View File

@ -5,10 +5,8 @@ import json
import shutil import shutil
import tempfile import tempfile
from requests.structures import CaseInsensitiveDict
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
# HACK: Prepend ../ to PYTHONPATH so that we can import httpie form there. # HACK: Prepend ../ to PYTHONPATH so that we can import httpie form there.
TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..'))) sys.path.insert(0, os.path.realpath(os.path.join(TESTS_ROOT, '..')))
from httpie import ExitStatus from httpie import ExitStatus
from httpie.models import Environment from httpie.models import Environment
@ -21,16 +19,23 @@ HTTPBIN_URL = os.environ.get('HTTPBIN_URL',
CRLF = '\r\n' CRLF = '\r\n'
COLOR = '\x1b['
HTTP_OK = 'HTTP/1.1 200' HTTP_OK = 'HTTP/1.1 200'
OK_COLOR = ( HTTP_OK_COLOR = (
'HTTP\x1b[39m\x1b[38;5;245m/\x1b[39m\x1b' 'HTTP\x1b[39m\x1b[38;5;245m/\x1b[39m\x1b'
'[38;5;37m1.1\x1b[39m\x1b[38;5;245m \x1b[39m\x1b[38;5;37m200' '[38;5;37m1.1\x1b[39m\x1b[38;5;245m \x1b[39m\x1b[38;5;37m200'
'\x1b[39m\x1b[38;5;245m \x1b[39m\x1b[38;5;136mOK' '\x1b[39m\x1b[38;5;245m \x1b[39m\x1b[38;5;136mOK'
) )
COLOR = '\x1b['
def httpbin(path): def httpbin(path):
"""
Return a fully-qualified URL for `path`.
>>> httpbin('/get')
'http://httpbin.org/get'
"""
url = HTTPBIN_URL + path url = HTTPBIN_URL + path
return url return url
@ -39,21 +44,17 @@ def mk_config_dir():
return tempfile.mkdtemp(prefix='httpie_test_config_dir_') return tempfile.mkdtemp(prefix='httpie_test_config_dir_')
class Response(object):
# noinspection PyDefaultArgument
def __init__(self, url, headers={}, status_code=200):
self.url = url
self.headers = CaseInsensitiveDict(headers)
self.status_code = status_code
class TestEnvironment(Environment): class TestEnvironment(Environment):
"""
Environment subclass with reasonable defaults suitable for testing.
"""
colors = 0 colors = 0
stdin_isatty = True, stdin_isatty = True,
stdout_isatty = True stdout_isatty = True
is_windows = False is_windows = False
_shutil = shutil # we need it in __del__ (would get gc'd)
_shutil = shutil # needed by __del__ (would get gc'd)
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -75,12 +76,41 @@ class TestEnvironment(Environment):
self._shutil.rmtree(self.config_dir) self._shutil.rmtree(self.config_dir)
class BytesResponse(bytes): class Response(object):
stderr = json = exit_status = None stderr = None
json = None
exit_status = None
class StrResponse(str): class BytesResponse(bytes, Response):
stderr = json = exit_status = None pass
class StrResponse(str, Response):
@property
def json(self):
if not hasattr(self, '_json'):
self._json = None
# De-serialize JSON body if possible.
if COLOR in self:
# Colorized output cannot be parsed.
pass
elif self.strip().startswith('{'):
# Looks like JSON body.
self._json = json.loads(self)
elif self.count('Content-Type:') == 1 and 'application/json' in self:
# Looks like a JSON HTTP message, try to extract its body.
try:
j = self.strip()[self.strip().rindex('\r\n\r\n'):]
except ValueError:
pass
else:
try:
self._json = json.loads(j)
except ValueError:
pass
return self._json
def http(*args, **kwargs): def http(*args, **kwargs):
@ -119,29 +149,11 @@ def http(*args, **kwargs):
stdout.seek(0) stdout.seek(0)
stderr.seek(0) stderr.seek(0)
output = stdout.read() output = stdout.read()
try: try:
r = StrResponse(output.decode('utf8')) r = StrResponse(output.decode('utf8'))
except UnicodeDecodeError: except UnicodeDecodeError:
r = BytesResponse(output) r = BytesResponse(output)
else:
if COLOR not in r:
# De-serialize JSON body if possible.
if r.strip().startswith('{'):
#noinspection PyTypeChecker
r.json = json.loads(r)
elif r.count('Content-Type:') == 1 and 'application/json' in r:
try:
j = r.strip()[r.strip().rindex('\r\n\r\n'):]
except ValueError:
pass
else:
try:
r.json = json.loads(j)
except ValueError:
pass
r.stderr = stderr.read() r.stderr = stderr.read()
r.exit_status = exit_status r.exit_status = exit_status
@ -150,3 +162,4 @@ def http(*args, **kwargs):
finally: finally:
stdout.close() stdout.close()
stderr.close() stderr.close()

View File

@ -9,13 +9,9 @@ import httpie.input
class AuthTest(TestCase): class AuthTest(TestCase):
def test_basic_auth(self): def test_basic_auth(self):
r = http( r = http('--auth=user:password', 'GET',
'--auth=user:password', httpbin('/basic-auth/user/password'))
'GET',
httpbin('/basic-auth/user/password')
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"authenticated": true' in r assert '"authenticated": true' in r
assert '"user": "user"' in r assert '"user": "user"' in r
@ -24,27 +20,15 @@ class AuthTest(TestCase):
requests.__version__ == '0.13.6', requests.__version__ == '0.13.6',
reason='Redirects with prefetch=False are broken in Requests 0.13.6') reason='Redirects with prefetch=False are broken in Requests 0.13.6')
def test_digest_auth(self): def test_digest_auth(self):
r = http( r = http('--auth-type=digest', '--auth=user:password', 'GET',
'--auth-type=digest', httpbin('/digest-auth/auth/user/password'))
'--auth=user:password',
'GET',
httpbin('/digest-auth/auth/user/password')
)
assert HTTP_OK in r assert HTTP_OK in r
assert r'"authenticated": true' in r assert r'"authenticated": true' in r
assert r'"user": "user"', r assert r'"user": "user"', r
def test_password_prompt(self): def test_password_prompt(self):
httpie.input.AuthCredentials._getpass = lambda self, prompt: 'password' httpie.input.AuthCredentials._getpass = lambda self, prompt: 'password'
r = http('--auth', 'user', 'GET', httpbin('/basic-auth/user/password'))
r = http(
'--auth',
'user',
'GET',
httpbin('/basic-auth/user/password')
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"authenticated": true' in r assert '"authenticated": true' in r
assert '"user": "user"' in r assert '"user": "user"' in r
@ -52,12 +36,9 @@ class AuthTest(TestCase):
def test_credentials_in_url(self): def test_credentials_in_url(self):
url = httpbin('/basic-auth/user/password') url = httpbin('/basic-auth/user/password')
url = 'http://user:password@' + url.split('http://', 1)[1] url = 'http://user:password@' + url.split('http://', 1)[1]
r = http( r = http('GET', url)
'GET',
url
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"authenticated": true'in r assert '"authenticated": true' in r
assert '"user": "user"' in r assert '"user": "user"' in r
def test_credentials_in_url_auth_flag_has_priority(self): def test_credentials_in_url_auth_flag_has_priority(self):
@ -65,11 +46,7 @@ class AuthTest(TestCase):
then the ones from -a are used.""" then the ones from -a are used."""
url = httpbin('/basic-auth/user/password') url = httpbin('/basic-auth/user/password')
url = 'http://user:wrong_password@' + url.split('http://', 1)[1] url = 'http://user:wrong_password@' + url.split('http://', 1)[1]
r = http( r = http('--auth=user:password', 'GET', url)
'--auth=user:password',
'GET',
url
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"authenticated": true' in r assert '"authenticated": true' in r
assert '"user": "user"' in r assert '"user": "user"' in r

View File

@ -8,7 +8,6 @@ from tests.fixtures import BIN_FILE_PATH, BIN_FILE_CONTENT, BIN_FILE_PATH_ARG
class BinaryRequestDataTest(TestCase): class BinaryRequestDataTest(TestCase):
def test_binary_stdin(self): def test_binary_stdin(self):
with open(BIN_FILE_PATH, 'rb') as stdin: with open(BIN_FILE_PATH, 'rb') as stdin:
env = TestEnvironment( env = TestEnvironment(
@ -16,47 +15,23 @@ class BinaryRequestDataTest(TestCase):
stdin_isatty=False, stdin_isatty=False,
stdout_isatty=False stdout_isatty=False
) )
r = http( r = http('--print=B', 'POST', httpbin('/post'), env=env)
'--print=B',
'POST',
httpbin('/post'),
env=env,
)
assert r == BIN_FILE_CONTENT assert r == BIN_FILE_CONTENT
def test_binary_file_path(self): def test_binary_file_path(self):
env = TestEnvironment( env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
stdin_isatty=True, r = http('--print=B', 'POST', httpbin('/post'),
stdout_isatty=False '@' + BIN_FILE_PATH_ARG, env=env, )
)
r = http(
'--print=B',
'POST',
httpbin('/post'),
'@' + BIN_FILE_PATH_ARG,
env=env,
)
assert r == BIN_FILE_CONTENT assert r == BIN_FILE_CONTENT
def test_binary_file_form(self): def test_binary_file_form(self):
env = TestEnvironment( env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
stdin_isatty=True, r = http('--print=B', '--form', 'POST', httpbin('/post'),
stdout_isatty=False 'test@' + BIN_FILE_PATH_ARG, env=env)
)
r = http(
'--print=B',
'--form',
'POST',
httpbin('/post'),
'test@' + BIN_FILE_PATH_ARG,
env=env,
)
assert bytes(BIN_FILE_CONTENT) in bytes(r) assert bytes(BIN_FILE_CONTENT) in bytes(r)
class BinaryResponseDataTest(TestCase): class BinaryResponseDataTest(TestCase):
url = 'http://www.google.com/favicon.ico' url = 'http://www.google.com/favicon.ico'
@property @property
@ -66,27 +41,16 @@ class BinaryResponseDataTest(TestCase):
return self._bindata return self._bindata
def test_binary_suppresses_when_terminal(self): def test_binary_suppresses_when_terminal(self):
r = http( r = http('GET', self.url)
'GET',
self.url
)
assert BINARY_SUPPRESSED_NOTICE.decode() in r assert BINARY_SUPPRESSED_NOTICE.decode() in r
def test_binary_suppresses_when_not_terminal_but_pretty(self): def test_binary_suppresses_when_not_terminal_but_pretty(self):
r = http( env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
'--pretty=all', r = http('--pretty=all', 'GET', self.url,
'GET', env=env)
self.url,
env=TestEnvironment(stdin_isatty=True,
stdout_isatty=False)
)
assert BINARY_SUPPRESSED_NOTICE.decode() in r assert BINARY_SUPPRESSED_NOTICE.decode() in r
def test_binary_included_and_correct_when_suitable(self): def test_binary_included_and_correct_when_suitable(self):
r = http( env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
'GET', r = http('GET', self.url, env=env)
self.url,
env=TestEnvironment(stdin_isatty=True,
stdout_isatty=False)
)
assert r == self.bindata assert r == self.bindata

View File

@ -18,7 +18,6 @@ from httpie.cli import parser
class ItemParsingTest(TestCase): class ItemParsingTest(TestCase):
def setUp(self): def setUp(self):
self.key_value_type = KeyValueArgType( self.key_value_type = KeyValueArgType(
*input.SEP_GROUP_ALL_ITEMS *input.SEP_GROUP_ALL_ITEMS
@ -98,57 +97,33 @@ class ItemParsingTest(TestCase):
class QuerystringTest(TestCase): class QuerystringTest(TestCase):
def test_query_string_params_in_url(self): def test_query_string_params_in_url(self):
r = http( r = http('--print=Hhb', 'GET', httpbin('/get?a=1&b=2'))
'--print=Hhb',
'GET',
httpbin('/get?a=1&b=2')
)
path = '/get?a=1&b=2' path = '/get?a=1&b=2'
url = httpbin(path) url = httpbin(path)
assert HTTP_OK in r assert HTTP_OK in r
assert 'GET %s HTTP/1.1' % path in r assert 'GET %s HTTP/1.1' % path in r
assert '"url": "%s"' % url in r assert '"url": "%s"' % url in r
def test_query_string_params_items(self): def test_query_string_params_items(self):
r = http( r = http('--print=Hhb', 'GET', httpbin('/get'), 'a==1', 'b==2')
'--print=Hhb',
'GET',
httpbin('/get'),
'a==1',
'b==2'
)
path = '/get?a=1&b=2' path = '/get?a=1&b=2'
url = httpbin(path) url = httpbin(path)
assert HTTP_OK in r assert HTTP_OK in r
assert 'GET %s HTTP/1.1' % path in r assert 'GET %s HTTP/1.1' % path in r
assert '"url": "%s"' % url in r assert '"url": "%s"' % url in r
def test_query_string_params_in_url_and_items_with_duplicates(self): def test_query_string_params_in_url_and_items_with_duplicates(self):
r = http( r = http('--print=Hhb', 'GET', httpbin('/get?a=1&a=1'),
'--print=Hhb', 'a==1', 'a==1', 'b==2')
'GET',
httpbin('/get?a=1&a=1'),
'a==1',
'a==1',
'b==2',
)
path = '/get?a=1&a=1&a=1&a=1&b=2' path = '/get?a=1&a=1&a=1&a=1&b=2'
url = httpbin(path) url = httpbin(path)
assert HTTP_OK in r assert HTTP_OK in r
assert 'GET %s HTTP/1.1' % path in r assert 'GET %s HTTP/1.1' % path in r
assert '"url": "%s"' % url in r assert '"url": "%s"' % url in r
class CLIParserTestCase(TestCase): class CLIParserTestCase(TestCase):
def test_expand_localhost_shorthand(self): def test_expand_localhost_shorthand(self):
args = parser.parse_args(args=[':'], env=TestEnvironment()) args = parser.parse_args(args=[':'], env=TestEnvironment())
assert args.url == 'http://localhost' assert args.url == 'http://localhost'
@ -193,7 +168,6 @@ class CLIParserTestCase(TestCase):
class ArgumentParserTestCase(TestCase): class ArgumentParserTestCase(TestCase):
def setUp(self): def setUp(self):
self.parser = input.Parser() self.parser = input.Parser()
@ -213,7 +187,6 @@ class ArgumentParserTestCase(TestCase):
assert self.parser.args.items == [] assert self.parser.args.items == []
def test_guess_when_method_not_set(self): def test_guess_when_method_not_set(self):
self.parser.args = argparse.Namespace() self.parser.args = argparse.Namespace()
self.parser.args.method = None self.parser.args.method = None
self.parser.args.url = 'http://example.com/' self.parser.args.url = 'http://example.com/'
@ -240,9 +213,9 @@ class ArgumentParserTestCase(TestCase):
assert self.parser.args.url == 'http://example.com/' assert self.parser.args.url == 'http://example.com/'
assert self.parser.args.items == [ assert self.parser.args.items == [
KeyValue(key='data', KeyValue(key='data',
value='field', value='field',
sep='=', sep='=',
orig='data=field') orig='data=field')
] ]
def test_guess_when_method_set_but_invalid_and_header_field(self): def test_guess_when_method_set_but_invalid_and_header_field(self):
@ -260,9 +233,9 @@ class ArgumentParserTestCase(TestCase):
assert self.parser.args.url == 'http://example.com/' assert self.parser.args.url == 'http://example.com/'
assert self.parser.args.items, [ assert self.parser.args.items, [
KeyValue(key='test', KeyValue(key='test',
value='header', value='header',
sep=':', sep=':',
orig='test:header') orig='test:header')
] ]
def test_guess_when_method_set_but_invalid_and_item_exists(self): def test_guess_when_method_set_but_invalid_and_item_exists(self):
@ -287,46 +260,27 @@ class ArgumentParserTestCase(TestCase):
class TestNoOptions(TestCase): class TestNoOptions(TestCase):
def test_valid_no_options(self): def test_valid_no_options(self):
r = http( r = http('--verbose', '--no-verbose', 'GET', httpbin('/get'))
'--verbose',
'--no-verbose',
'GET',
httpbin('/get')
)
assert 'GET /get HTTP/1.1' not in r assert 'GET /get HTTP/1.1' not in r
def test_invalid_no_options(self): def test_invalid_no_options(self):
r = http( r = http('--no-war', 'GET', httpbin('/get'))
'--no-war',
'GET',
httpbin('/get')
)
assert r.exit_status == 1 assert r.exit_status == 1
assert 'unrecognized arguments: --no-war' in r.stderr assert 'unrecognized arguments: --no-war' in r.stderr
assert 'GET /get HTTP/1.1' not in r assert 'GET /get HTTP/1.1' not in r
class IgnoreStdinTest(TestCase): class IgnoreStdinTest(TestCase):
def test_ignore_stdin(self): def test_ignore_stdin(self):
with open(FILE_PATH) as f: with open(FILE_PATH) as f:
r = http( env = TestEnvironment(stdin=f, stdin_isatty=False)
'--ignore-stdin', r = http('--ignore-stdin', '--verbose', httpbin('/get'), env=env)
'--verbose',
httpbin('/get'),
env=TestEnvironment(stdin=f, stdin_isatty=False)
)
assert HTTP_OK in r assert HTTP_OK in r
assert 'GET /get HTTP' in r, "Don't default to POST." assert 'GET /get HTTP' in r, "Don't default to POST."
assert FILE_CONTENT not in r, "Don't send stdin data." assert FILE_CONTENT not in r, "Don't send stdin data."
def test_ignore_stdin_cannot_prompt_password(self): def test_ignore_stdin_cannot_prompt_password(self):
r = http( r = http('--ignore-stdin', '--auth=no-password', httpbin('/get'))
'--ignore-stdin',
'--auth=username-without-password',
httpbin('/get'),
)
assert r.exit_status == ExitStatus.ERROR assert r.exit_status == ExitStatus.ERROR
assert 'because --ignore-stdin' in r.stderr assert 'because --ignore-stdin' in r.stderr

View File

@ -9,47 +9,29 @@ from tests.fixtures import FILE_PATH
class ImplicitHTTPMethodTest(TestCase): class ImplicitHTTPMethodTest(TestCase):
def test_implicit_GET(self): def test_implicit_GET(self):
r = http(httpbin('/get')) r = http(httpbin('/get'))
assert HTTP_OK in r assert HTTP_OK in r
def test_implicit_GET_with_headers(self): def test_implicit_GET_with_headers(self):
r = http( r = http(httpbin('/headers'), 'Foo:bar')
httpbin('/headers'),
'Foo:bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Foo": "bar"' in r assert '"Foo": "bar"' in r
def test_implicit_POST_json(self): def test_implicit_POST_json(self):
r = http( r = http(httpbin('/post'), 'hello=world')
httpbin('/post'),
'hello=world'
)
assert HTTP_OK in r assert HTTP_OK in r
assert r'\"hello\": \"world\"' in r assert r'\"hello\": \"world\"' in r
def test_implicit_POST_form(self): def test_implicit_POST_form(self):
r = http( r = http('--form', httpbin('/post'), 'foo=bar')
'--form',
httpbin('/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_implicit_POST_stdin(self): def test_implicit_POST_stdin(self):
with open(FILE_PATH) as f: with open(FILE_PATH) as f:
env = TestEnvironment( env = TestEnvironment(stdin_isatty=False, stdin=f)
stdin_isatty=False, r = http('--form', httpbin('/post'), env=env)
stdin=f,
)
r = http(
'--form',
httpbin('/post'),
env=env
)
assert HTTP_OK in r assert HTTP_OK in r
@ -60,53 +42,36 @@ class AutoContentTypeAndAcceptHeadersTest(TestCase):
-f is used. -f is used.
""" """
def test_GET_no_data_no_auto_headers(self): def test_GET_no_data_no_auto_headers(self):
# https://github.com/jkbr/httpie/issues/62 # https://github.com/jkbr/httpie/issues/62
r = http( r = http('GET', httpbin('/headers'))
'GET',
httpbin('/headers')
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Accept": "*/*"' in r assert '"Accept": "*/*"' in r
assert '"Content-Type": "application/json' not in r assert '"Content-Type": "application/json' not in r
def test_POST_no_data_no_auto_headers(self): def test_POST_no_data_no_auto_headers(self):
# JSON headers shouldn't be automatically set for POST with no data. # JSON headers shouldn't be automatically set for POST with no data.
r = http( r = http('POST', httpbin('/post'))
'POST',
httpbin('/post')
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Accept": "*/*"' in r assert '"Accept": "*/*"' in r
assert '"Content-Type": "application/json' not in r assert '"Content-Type": "application/json' not in r
def test_POST_with_data_auto_JSON_headers(self): def test_POST_with_data_auto_JSON_headers(self):
r = http( r = http('POST', httpbin('/post'), 'a=b')
'POST',
httpbin('/post'),
'a=b'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Accept": "application/json"' in r assert '"Accept": "application/json"' in r
assert '"Content-Type": "application/json; charset=utf-8' in r assert '"Content-Type": "application/json; charset=utf-8' in r
def test_GET_with_data_auto_JSON_headers(self): def test_GET_with_data_auto_JSON_headers(self):
# JSON headers should automatically be set also for GET with data. # JSON headers should automatically be set also for GET with data.
r = http( r = http('POST', httpbin('/post'), 'a=b')
'POST',
httpbin('/post'),
'a=b'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Accept": "application/json"' in r assert '"Accept": "application/json"' in r
assert '"Content-Type": "application/json; charset=utf-8' in r assert '"Content-Type": "application/json; charset=utf-8' in r
def test_POST_explicit_JSON_auto_JSON_accept(self): def test_POST_explicit_JSON_auto_JSON_accept(self):
r = http( r = http('--json', 'POST', httpbin('/post'))
'--json',
'POST',
httpbin('/post')
)
assert HTTP_OK in r assert HTTP_OK in r
assert r.json['headers']['Accept'] == 'application/json' assert r.json['headers']['Accept'] == 'application/json'
# Make sure Content-Type gets set even with no data. # Make sure Content-Type gets set even with no data.
@ -114,57 +79,30 @@ class AutoContentTypeAndAcceptHeadersTest(TestCase):
assert 'application/json' in r.json['headers']['Content-Type'] assert 'application/json' in r.json['headers']['Content-Type']
def test_GET_explicit_JSON_explicit_headers(self): def test_GET_explicit_JSON_explicit_headers(self):
r = http( r = http('--json', 'GET', httpbin('/headers'),
'--json', 'Accept:application/xml',
'GET', 'Content-Type:application/xml')
httpbin('/headers'),
'Accept:application/xml',
'Content-Type:application/xml'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Accept": "application/xml"' in r assert '"Accept": "application/xml"' in r
assert '"Content-Type": "application/xml"' in r assert '"Content-Type": "application/xml"' in r
def test_POST_form_auto_Content_Type(self): def test_POST_form_auto_Content_Type(self):
r = http( r = http('--form', 'POST', httpbin('/post'))
'--form',
'POST',
httpbin('/post')
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Content-Type": "application/x-www-form-urlencoded' in r assert '"Content-Type": "application/x-www-form-urlencoded' in r
def test_POST_form_Content_Type_override(self): def test_POST_form_Content_Type_override(self):
r = http( r = http('--form', 'POST', httpbin('/post'),
'--form', 'Content-Type:application/xml')
'POST',
httpbin('/post'),
'Content-Type:application/xml'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"Content-Type": "application/xml"' in r assert '"Content-Type": "application/xml"' in r
def test_print_only_body_when_stdout_redirected_by_default(self): def test_print_only_body_when_stdout_redirected_by_default(self):
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
r = http( r = http('GET', httpbin('/get'), env=env)
'GET',
httpbin('/get'),
env=TestEnvironment(
stdin_isatty=True,
stdout_isatty=False
)
)
assert 'HTTP/' not in r assert 'HTTP/' not in r
def test_print_overridable_when_stdout_redirected(self): def test_print_overridable_when_stdout_redirected(self):
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
r = http( r = http('--print=h', 'GET', httpbin('/get'), env=env)
'--print=h',
'GET',
httpbin('/get'),
env=TestEnvironment(
stdin_isatty=True,
stdout_isatty=False
)
)
assert HTTP_OK in r assert HTTP_OK in r

View File

@ -2,6 +2,8 @@ import os
import time import time
from unittest import TestCase from unittest import TestCase
from requests.structures import CaseInsensitiveDict
from httpie.compat import urlopen from httpie.compat import urlopen
from httpie.downloads import ( from httpie.downloads import (
parse_content_range, parse_content_range,
@ -11,13 +13,19 @@ from httpie.downloads import (
ContentRangeError, ContentRangeError,
Download, Download,
) )
from tests import httpbin, http, TestEnvironment, Response from tests import httpbin, http, TestEnvironment
class Response(object):
# noinspection PyDefaultArgument
def __init__(self, url, headers={}, status_code=200):
self.url = url
self.headers = CaseInsensitiveDict(headers)
self.status_code = status_code
class DownloadUtilsTest(TestCase): class DownloadUtilsTest(TestCase):
def test_Content_Range_parsing(self): def test_Content_Range_parsing(self):
parse = parse_content_range parse = parse_content_range
assert parse('bytes 100-199/200', 100) == 200 assert parse('bytes 100-199/200', 100) == 200
@ -73,20 +81,20 @@ class DownloadUtilsTest(TestCase):
) )
def test_unique_filename(self): def test_unique_filename(self):
def attempts(unique_on_attempt=0):
def make_exists(unique_on_attempt=0):
# noinspection PyUnresolvedReferences,PyUnusedLocal # noinspection PyUnresolvedReferences,PyUnusedLocal
def exists(filename): def exists(filename):
if exists.attempt == unique_on_attempt: if exists.attempt == unique_on_attempt:
return False return False
exists.attempt += 1 exists.attempt += 1
return True return True
exists.attempt = 0 exists.attempt = 0
return exists return exists
assert 'foo.bar' == get_unique_filename('foo.bar', make_exists()) assert 'foo.bar' == get_unique_filename('foo.bar', attempts(0))
assert 'foo.bar-1' == get_unique_filename('foo.bar', make_exists(1)) assert 'foo.bar-1' == get_unique_filename('foo.bar', attempts(1))
assert 'foo.bar-10' == get_unique_filename('foo.bar', make_exists(10)) assert 'foo.bar-10' == get_unique_filename('foo.bar', attempts(10))
class DownloadsTest(TestCase): class DownloadsTest(TestCase):
@ -95,14 +103,8 @@ class DownloadsTest(TestCase):
def test_actual_download(self): def test_actual_download(self):
url = httpbin('/robots.txt') url = httpbin('/robots.txt')
body = urlopen(url).read().decode() body = urlopen(url).read().decode()
r = http( env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
'--download', r = http('--download', url, env=env)
url,
env=TestEnvironment(
stdin_isatty=True,
stdout_isatty=False
)
)
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
@ -112,7 +114,7 @@ class DownloadsTest(TestCase):
download = Download(output_file=open(os.devnull, 'w')) download = Download(output_file=open(os.devnull, 'w'))
download.start(Response( download.start(Response(
url=httpbin('/'), url=httpbin('/'),
headers={'Content-Length': 10} headers={'Content-Length': 10}
)) ))
time.sleep(1.1) time.sleep(1.1)
download.chunk_downloaded(b'12345') download.chunk_downloaded(b'12345')

View File

@ -8,42 +8,30 @@ from tests import TestEnvironment, http, httpbin, HTTP_OK
class ExitStatusTest(TestCase): class ExitStatusTest(TestCase):
def test_ok_response_exits_0(self): def test_ok_response_exits_0(self):
r = http( r = http('GET', httpbin('/status/200'))
'GET',
httpbin('/status/200')
)
assert HTTP_OK in r assert HTTP_OK in r
assert r.exit_status == ExitStatus.OK assert r.exit_status == ExitStatus.OK
def test_error_response_exits_0_without_check_status(self): def test_error_response_exits_0_without_check_status(self):
r = http( r = http('GET', httpbin('/status/500'))
'GET',
httpbin('/status/500')
)
assert 'HTTP/1.1 500' in r assert 'HTTP/1.1 500' in r
assert r.exit_status == ExitStatus.OK assert r.exit_status == ExitStatus.OK
assert not r.stderr assert not r.stderr
@pytest.mark.skipif(True, reason='timeout broken in requests' @pytest.mark.skipif(
' (https://github.com/jkbr/httpie/issues/185)') True,
reason='timeout broken in requests'
' (https://github.com/jkbr/httpie/issues/185)')
def test_timeout_exit_status(self): def test_timeout_exit_status(self):
r = http( r = http('--timeout=0.5', 'GET', httpbin('/delay/1'))
'--timeout=0.5', assert HTTP_OK in r
'GET',
httpbin('/delay/1')
)
assert r.exit_status == ExitStatus.ERROR_TIMEOUT assert r.exit_status == ExitStatus.ERROR_TIMEOUT
def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self): def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(self):
r = http( env = TestEnvironment(stdout_isatty=False)
'--check-status', r = http('--check-status', '--headers', 'GET', httpbin('/status/301'),
'--headers', # non-terminal, force headers env=env)
'GET',
httpbin('/status/301'),
env=TestEnvironment(stdout_isatty=False,)
)
assert 'HTTP/1.1 301' in r assert 'HTTP/1.1 301' in r
assert r.exit_status == ExitStatus.ERROR_HTTP_3XX assert r.exit_status == ExitStatus.ERROR_HTTP_3XX
assert '301 moved permanently' in r.stderr.lower() assert '301 moved permanently' in r.stderr.lower()
@ -52,32 +40,19 @@ class ExitStatusTest(TestCase):
requests.__version__ == '0.13.6', requests.__version__ == '0.13.6',
reason='Redirects with prefetch=False are broken in Requests 0.13.6') reason='Redirects with prefetch=False are broken in Requests 0.13.6')
def test_3xx_check_status_redirects_allowed_exits_0(self): def test_3xx_check_status_redirects_allowed_exits_0(self):
r = http( r = http('--check-status', '--follow', 'GET', httpbin('/status/301'))
'--check-status',
'--follow',
'GET',
httpbin('/status/301')
)
# The redirect will be followed so 200 is expected. # The redirect will be followed so 200 is expected.
assert 'HTTP/1.1 200 OK' in r assert 'HTTP/1.1 200 OK' in r
assert r.exit_status == ExitStatus.OK assert r.exit_status == ExitStatus.OK
def test_4xx_check_status_exits_4(self): def test_4xx_check_status_exits_4(self):
r = http( r = http('--check-status', 'GET', httpbin('/status/401'))
'--check-status',
'GET',
httpbin('/status/401')
)
assert 'HTTP/1.1 401' in r assert 'HTTP/1.1 401' in r
assert r.exit_status == ExitStatus.ERROR_HTTP_4XX assert r.exit_status == ExitStatus.ERROR_HTTP_4XX
# Also stderr should be empty since stdout isn't redirected. # Also stderr should be empty since stdout isn't redirected.
assert not r.stderr assert not r.stderr
def test_5xx_check_status_exits_5(self): def test_5xx_check_status_exits_5(self):
r = http( r = http('--check-status', 'GET', httpbin('/status/500'))
'--check-status',
'GET',
httpbin('/status/500')
)
assert 'HTTP/1.1 500' in r assert 'HTTP/1.1 500' in r
assert r.exit_status == ExitStatus.ERROR_HTTP_5XX assert r.exit_status == ExitStatus.ERROR_HTTP_5XX

View File

@ -8,81 +8,43 @@ from tests.fixtures import FILE_PATH, FILE_CONTENT
class HTTPieTest(TestCase): class HTTPieTest(TestCase):
def test_GET(self): def test_GET(self):
r = http( r = http('GET', httpbin('/get'))
'GET',
httpbin('/get')
)
assert HTTP_OK in r assert HTTP_OK in r
def test_DELETE(self): def test_DELETE(self):
r = http( r = http('DELETE', httpbin('/delete'))
'DELETE',
httpbin('/delete')
)
assert HTTP_OK in r assert HTTP_OK in r
def test_PUT(self): def test_PUT(self):
r = http( r = http('PUT', httpbin('/put'), 'foo=bar')
'PUT',
httpbin('/put'),
'foo=bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert r'\"foo\": \"bar\"' in r assert r'\"foo\": \"bar\"' in r
def test_POST_JSON_data(self): def test_POST_JSON_data(self):
r = http( r = http('POST', httpbin('/post'), 'foo=bar')
'POST',
httpbin('/post'),
'foo=bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert r'\"foo\": \"bar\"' in r assert r'\"foo\": \"bar\"' in r
def test_POST_form(self): def test_POST_form(self):
r = http( r = http('--form', 'POST', httpbin('/post'), 'foo=bar')
'--form',
'POST',
httpbin('/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(self): def test_POST_form_multiple_values(self):
r = http( r = http('--form', 'POST', httpbin('/post'), 'foo=bar', 'foo=baz')
'--form',
'POST',
httpbin('/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(self): def test_POST_stdin(self):
with open(FILE_PATH) as f: with open(FILE_PATH) as f:
env = TestEnvironment( env = TestEnvironment(stdin=f, stdin_isatty=False)
stdin=f, r = http('--form', 'POST', httpbin('/post'), env=env)
stdin_isatty=False,
)
r = http(
'--form',
'POST',
httpbin('/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(self): def test_headers(self):
r = http( r = http('GET', httpbin('/headers'), 'Foo:bar')
'GET',
httpbin('/headers'),
'Foo:bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"User-Agent": "HTTPie' in r assert '"User-Agent": "HTTPie' in r
assert '"Foo": "bar"' in r assert '"Foo": "bar"' in r

View File

@ -9,38 +9,20 @@ from tests import (
class VerboseFlagTest(TestCase): class VerboseFlagTest(TestCase):
def test_verbose(self): def test_verbose(self):
r = http( r = http('--verbose', 'GET', httpbin('/get'), 'test-header:__test__')
'--verbose',
'GET',
httpbin('/get'),
'test-header:__test__'
)
assert HTTP_OK in r assert HTTP_OK in r
assert r.count('__test__') == 2 assert r.count('__test__') == 2
def test_verbose_form(self): def test_verbose_form(self):
# https://github.com/jkbr/httpie/issues/53 # https://github.com/jkbr/httpie/issues/53
r = http( r = http('--verbose', '--form', 'POST', httpbin('/post'),
'--verbose', 'foo=bar', 'baz=bar')
'--form',
'POST',
httpbin('/post'),
'foo=bar',
'baz=bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert 'foo=bar&baz=bar' in r assert 'foo=bar&baz=bar' in r
def test_verbose_json(self): def test_verbose_json(self):
r = http( r = http('--verbose', 'POST', httpbin('/post'), 'foo=bar', 'baz=bar')
'--verbose',
'POST',
httpbin('/post'),
'foo=bar',
'baz=bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert '"baz": "bar"' in r # request assert '"baz": "bar"' in r # request
assert r'\"baz\": \"bar\"' in r # response assert r'\"baz\": \"bar\"' in r # response
@ -50,35 +32,21 @@ class PrettyOptionsTest(TestCase):
"""Test the --pretty flag handling.""" """Test the --pretty flag handling."""
def test_pretty_enabled_by_default(self): def test_pretty_enabled_by_default(self):
r = http( env = TestEnvironment(colors=256)
'GET', r = http('GET', httpbin('/get'), env=env)
httpbin('/get'),
env=TestEnvironment(colors=256),
)
assert COLOR in r assert COLOR in r
def test_pretty_enabled_by_default_unless_stdout_redirected(self): def test_pretty_enabled_by_default_unless_stdout_redirected(self):
r = http( r = http('GET', httpbin('/get'))
'GET',
httpbin('/get')
)
assert COLOR not in r assert COLOR not in r
def test_force_pretty(self): def test_force_pretty(self):
r = http( env = TestEnvironment(stdout_isatty=False, colors=256)
'--pretty=all', r = http('--pretty=all', 'GET', httpbin('/get'), env=env, )
'GET',
httpbin('/get'),
env=TestEnvironment(stdout_isatty=False, colors=256),
)
assert COLOR in r assert COLOR in r
def test_force_ugly(self): def test_force_ugly(self):
r = http( r = http('--pretty=none', 'GET', httpbin('/get'))
'--pretty=none',
'GET',
httpbin('/get'),
)
assert COLOR not in r assert COLOR not in r
def test_subtype_based_pygments_lexer_match(self): def test_subtype_based_pygments_lexer_match(self):
@ -86,49 +54,34 @@ class PrettyOptionsTest(TestCase):
match any lexer. match any lexer.
""" """
r = http( env = TestEnvironment(colors=256)
'--print=B', r = http('--print=B', '--pretty=all', httpbin('/post'),
'--pretty=all', 'Content-Type:text/foo+json', 'a=b', env=env)
httpbin('/post'),
'Content-Type:text/foo+json',
'a=b',
env=TestEnvironment(colors=256)
)
assert COLOR in r assert COLOR in r
def test_colors_option(self): def test_colors_option(self):
r = http( env = TestEnvironment(colors=256)
'--print=B', r = http('--print=B', '--pretty=colors', 'GET', httpbin('/get'), 'a=b',
'--pretty=colors', env=env)
'GET',
httpbin('/get'),
'a=b',
env=TestEnvironment(colors=256),
)
#noinspection PyUnresolvedReferences
# Tests that the JSON data isn't formatted. # Tests that the JSON data isn't formatted.
assert not r.strip().count('\n') assert not r.strip().count('\n')
assert COLOR in r assert COLOR in r
def test_format_option(self): def test_format_option(self):
r = http( env = TestEnvironment(colors=256)
'--print=B', r = http('--print=B', '--pretty=format', 'GET', httpbin('/get'), 'a=b',
'--pretty=format', env=env)
'GET',
httpbin('/get'),
'a=b',
env=TestEnvironment(colors=256),
)
#noinspection PyUnresolvedReferences
# Tests that the JSON data is formatted. # Tests that the JSON data is formatted.
assert r.strip().count('\n') == 2 assert r.strip().count('\n') == 2
assert COLOR not in r assert COLOR not in r
class LineEndingsTest(TestCase): class LineEndingsTest(TestCase):
"""Test that CRLF is properly used in headers and """
as the headers/body separator.""" Test that CRLF is properly used in headers
and as the headers/body separator.
"""
def _validate_crlf(self, msg): def _validate_crlf(self, msg):
lines = iter(msg.splitlines(True)) lines = iter(msg.splitlines(True))
for header in lines: for header in lines:
@ -142,45 +95,23 @@ class LineEndingsTest(TestCase):
return body return body
def test_CRLF_headers_only(self): def test_CRLF_headers_only(self):
r = http( r = http('--headers', 'GET', httpbin('/get'))
'--headers',
'GET',
httpbin('/get')
)
body = self._validate_crlf(r) body = self._validate_crlf(r)
assert not body, 'Garbage after headers: %r' % r assert not body, 'Garbage after headers: %r' % r
def test_CRLF_ugly_response(self): def test_CRLF_ugly_response(self):
r = http( r = http('--pretty=none', 'GET', httpbin('/get'))
'--pretty=none',
'GET',
httpbin('/get')
)
self._validate_crlf(r) self._validate_crlf(r)
def test_CRLF_formatted_response(self): def test_CRLF_formatted_response(self):
r = http( r = http('--pretty=format', 'GET', httpbin('/get'))
'--pretty=format',
'GET',
httpbin('/get')
)
assert r.exit_status == ExitStatus.OK assert r.exit_status == ExitStatus.OK
self._validate_crlf(r) self._validate_crlf(r)
def test_CRLF_ugly_request(self): def test_CRLF_ugly_request(self):
r = http( r = http('--pretty=none', '--print=HB', 'GET', httpbin('/get'))
'--pretty=none',
'--print=HB',
'GET',
httpbin('/get')
)
self._validate_crlf(r) self._validate_crlf(r)
def test_CRLF_formatted_request(self): def test_CRLF_formatted_request(self):
r = http( r = http('--pretty=format', '--print=HB', 'GET', httpbin('/get'))
'--pretty=format',
'--print=HB',
'GET',
httpbin('/get')
)
self._validate_crlf(r) self._validate_crlf(r)

View File

@ -6,7 +6,6 @@ from tests import TestEnvironment, mk_config_dir, http, httpbin, HTTP_OK
class SessionsTest(TestCase): class SessionsTest(TestCase):
@property @property
def env(self): def env(self):
return TestEnvironment(config_dir=self.config_dir) return TestEnvironment(config_dir=self.config_dir)
@ -15,15 +14,9 @@ class SessionsTest(TestCase):
# Start a full-blown session with a custom request header, # Start a full-blown session with a custom request header,
# authorization, and response cookies. # authorization, and response cookies.
self.config_dir = mk_config_dir() self.config_dir = mk_config_dir()
r = http( r = http('--follow', '--session=test', '--auth=username:password',
'--follow', 'GET', httpbin('/cookies/set?hello=world'), 'Hello:World',
'--session=test', env=self.env)
'--auth=username:password',
'GET',
httpbin('/cookies/set?hello=world'),
'Hello:World',
env=self.env
)
assert HTTP_OK in r assert HTTP_OK in r
def tearDown(self): def tearDown(self):
@ -31,66 +24,37 @@ class SessionsTest(TestCase):
def test_session_create(self): def test_session_create(self):
# Verify that the session has been created. # Verify that the session has been created.
r = http( r = http('--session=test', 'GET', httpbin('/get'), env=self.env)
'--session=test',
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r assert HTTP_OK in r
assert r.json['headers']['Hello'] == 'World' assert r.json['headers']['Hello'] == 'World'
assert r.json['headers']['Cookie'] == 'hello=world' assert r.json['headers']['Cookie'] == 'hello=world'
assert 'Basic ' in r.json['headers']['Authorization'] assert 'Basic ' in r.json['headers']['Authorization']
def test_session_ignored_header_prefixes(self): def test_session_ignored_header_prefixes(self):
r = http( r = http('--session=test', 'GET', httpbin('/get'),
'--session=test', 'Content-Type: text/plain',
'GET', 'If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT',
httpbin('/get'), env=self.env)
'Content-Type: text/plain',
'If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT',
env=self.env
)
assert HTTP_OK in r assert HTTP_OK in r
r2 = http( r2 = http('--session=test', 'GET', httpbin('/get'))
'--session=test',
'GET',
httpbin('/get')
)
assert HTTP_OK in r2 assert HTTP_OK in r2
assert 'Content-Type' not in r2.json['headers'] assert 'Content-Type' not in r2.json['headers']
assert 'If-Unmodified-Since' not in r2.json['headers'] assert 'If-Unmodified-Since' not in r2.json['headers']
def test_session_update(self): def test_session_update(self):
# Get a response to a request from the original session. # Get a response to a request from the original session.
r1 = http( r1 = http('--session=test', 'GET', httpbin('/get'), env=self.env)
'--session=test',
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r1 assert HTTP_OK in r1
# Make a request modifying the session data. # Make a request modifying the session data.
r2 = http( r2 = http('--follow', '--session=test', '--auth=username:password2',
'--follow', 'GET', httpbin('/cookies/set?hello=world2'), 'Hello:World2',
'--session=test', env=self.env)
'--auth=username:password2',
'GET',
httpbin('/cookies/set?hello=world2'),
'Hello:World2',
env=self.env
)
assert HTTP_OK in r2 assert HTTP_OK in r2
# Get a response to a request from the updated session. # Get a response to a request from the updated session.
r3 = http( r3 = http('--session=test', 'GET', httpbin('/get'), env=self.env)
'--session=test',
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r3 assert HTTP_OK in r3
assert r3.json['headers']['Hello'] == 'World2' assert r3.json['headers']['Hello'] == 'World2'
assert r3.json['headers']['Cookie'] == 'hello=world2' assert r3.json['headers']['Cookie'] == 'hello=world2'
@ -99,34 +63,19 @@ class SessionsTest(TestCase):
def test_session_read_only(self): def test_session_read_only(self):
# Get a response from the original session. # Get a response from the original session.
r1 = http( r1 = http('--session=test', 'GET', httpbin('/get'), env=self.env)
'--session=test',
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r1 assert HTTP_OK in r1
# Make a request modifying the session data but # Make a request modifying the session data but
# with --session-read-only. # with --session-read-only.
r2 = http( r2 = http('--follow', '--session-read-only=test',
'--follow', '--auth=username:password2', 'GET',
'--session-read-only=test', httpbin('/cookies/set?hello=world2'), 'Hello:World2',
'--auth=username:password2', env=self.env)
'GET',
httpbin('/cookies/set?hello=world2'),
'Hello:World2',
env=self.env
)
assert HTTP_OK in r2 assert HTTP_OK in r2
# Get a response from the updated session. # Get a response from the updated session.
r3 = http( r3 = http('--session=test', 'GET', httpbin('/get'), env=self.env)
'--session=test',
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r3 assert HTTP_OK in r3
# Origin can differ on Travis. # Origin can differ on Travis.
@ -139,21 +88,11 @@ class SessionsTest(TestCase):
def test_session_by_path(self): def test_session_by_path(self):
session_path = os.path.join(self.config_dir, 'session-by-path.json') session_path = os.path.join(self.config_dir, 'session-by-path.json')
r1 = http( r1 = http('--session=' + session_path, 'GET', httpbin('/get'),
'--session=' + session_path, 'Foo:Bar', env=self.env)
'GET',
httpbin('/get'),
'Foo:Bar',
env=self.env
)
assert HTTP_OK in r1 assert HTTP_OK in r1
r2 = http( r2 = http('--session=' + session_path, 'GET', httpbin('/get'),
'--session=' + session_path, env=self.env)
'GET',
httpbin('/get'),
env=self.env
)
assert HTTP_OK in r2 assert HTTP_OK in r2
assert r2.json['headers']['Foo'] in 'Bar' assert r2.json['headers']['Foo'] in 'Bar'

View File

@ -16,19 +16,11 @@ class StreamTest(TestCase):
def test_pretty_redirected_stream(self): def test_pretty_redirected_stream(self):
"""Test that --stream works with prettified redirected output.""" """Test that --stream works with prettified redirected output."""
with open(BIN_FILE_PATH, 'rb') as f: with open(BIN_FILE_PATH, 'rb') as f:
r = http( env = TestEnvironment(colors=256, stdin=f,
'--verbose', stdin_isatty=False,
'--pretty=all', stdout_isatty=False)
'--stream', r = http('--verbose', '--pretty=all', '--stream', 'GET',
'GET', httpbin('/get'), env=env)
httpbin('/get'),
env=TestEnvironment(
colors=256,
stdin=f,
stdin_isatty=False,
stdout_isatty=False,
)
)
assert BINARY_SUPPRESSED_NOTICE.decode() in r assert BINARY_SUPPRESSED_NOTICE.decode() in r
# We get 'Bad Request' but it's okay. # We get 'Bad Request' but it's okay.
#self.assertIn(OK_COLOR, r) #self.assertIn(OK_COLOR, r)
@ -37,17 +29,9 @@ class StreamTest(TestCase):
"""Test that --stream works with non-prettified """Test that --stream works with non-prettified
redirected terminal output.""" redirected terminal output."""
with open(BIN_FILE_PATH, 'rb') as f: with open(BIN_FILE_PATH, 'rb') as f:
r = http( env = TestEnvironment(stdin=f, stdin_isatty=False)
'--pretty=none', r = http('--pretty=none', '--stream', '--verbose', 'GET',
'--stream', httpbin('/get'), env=env)
'--verbose',
'GET',
httpbin('/get'),
env=TestEnvironment(
stdin=f,
stdin_isatty=False
),
)
assert BINARY_SUPPRESSED_NOTICE.decode() in r assert BINARY_SUPPRESSED_NOTICE.decode() in r
# We get 'Bad Request' but it's okay. # We get 'Bad Request' but it's okay.
#self.assertIn(OK, r) #self.assertIn(OK, r)
@ -56,18 +40,10 @@ class StreamTest(TestCase):
"""Test that --stream works with non-prettified """Test that --stream works with non-prettified
redirected terminal output.""" redirected terminal output."""
with open(BIN_FILE_PATH, 'rb') as f: with open(BIN_FILE_PATH, 'rb') as f:
r = http( env = TestEnvironment(stdout_isatty=False, stdin=f,
'--pretty=none', stdin_isatty=False)
'--stream', r = http('--pretty=none', '--stream', '--verbose', 'GET',
'--verbose', httpbin('/get'), env=env)
'GET',
httpbin('/get'),
env=TestEnvironment(
stdout_isatty=False,
stdin=f,
stdin_isatty=False
)
)
# We get 'Bad Request' but it's okay. # We get 'Bad Request' but it's okay.
#self.assertIn(OK.encode(), r) #self.assertIn(OK.encode(), r)
assert BIN_FILE_CONTENT in r assert BIN_FILE_CONTENT in r

View File

@ -7,25 +7,13 @@ from tests.fixtures import FILE_PATH_ARG, FILE_PATH, FILE_CONTENT
class MultipartFormDataFileUploadTest(TestCase): class MultipartFormDataFileUploadTest(TestCase):
def test_non_existent_file_raises_parse_error(self): def test_non_existent_file_raises_parse_error(self):
self.assertRaises(ParseError, http, with self.assertRaises(ParseError):
'--form', http('--form', 'POST', httpbin('/post'), 'foo@/__does_not_exist__')
'POST',
httpbin('/post'),
'foo@/__does_not_exist__',
)
def test_upload_ok(self): def test_upload_ok(self):
r = http( r = http('--form', '--verbose', 'POST', httpbin('/post'),
'--form', 'test-file@%s' % FILE_PATH_ARG, 'foo=bar')
'--verbose',
'POST',
httpbin('/post'),
'test-file@%s' % FILE_PATH_ARG,
'foo=bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert 'Content-Disposition: form-data; name="foo"' in r assert 'Content-Disposition: form-data; name="foo"' in r
assert 'Content-Disposition: form-data; name="test-file";' \ assert 'Content-Disposition: form-data; name="test-file";' \
@ -39,44 +27,28 @@ class RequestBodyFromFilePathTest(TestCase):
`http URL @file' `http URL @file'
""" """
def test_request_body_from_file_by_path(self): def test_request_body_from_file_by_path(self):
r = http( r = http('--verbose', 'POST', httpbin('/post'), '@' + FILE_PATH_ARG)
'--verbose',
'POST',
httpbin('/post'),
'@' + FILE_PATH_ARG
)
assert HTTP_OK in r assert HTTP_OK in r
assert FILE_CONTENT in r assert FILE_CONTENT in r
assert '"Content-Type": "text/plain"' in r assert '"Content-Type": "text/plain"' in r
def test_request_body_from_file_by_path_with_explicit_content_type(self): def test_request_body_from_file_by_path_with_explicit_content_type(self):
r = http( r = http('POST', httpbin('/post'), '@' + FILE_PATH_ARG,
'POST', 'Content-Type:x-foo/bar')
httpbin('/post'),
'@' + FILE_PATH_ARG,
'Content-Type:x-foo/bar'
)
assert HTTP_OK in r assert HTTP_OK in r
assert FILE_CONTENT in r assert FILE_CONTENT in r
assert '"Content-Type": "x-foo/bar"' in r assert '"Content-Type": "x-foo/bar"' in r
def test_request_body_from_file_by_path_no_field_name_allowed(self): def test_request_body_from_file_by_path_no_field_name_allowed(self):
env = TestEnvironment(stdin_isatty=True) env = TestEnvironment(stdin_isatty=True)
r = http( r = http('POST', httpbin('/post'), 'field-name@' + FILE_PATH_ARG,
'POST', env=env)
httpbin('/post'),
'field-name@' + FILE_PATH_ARG,
env=env
)
assert 'perhaps you meant --form?' in r.stderr assert 'perhaps you meant --form?' in r.stderr
def test_request_body_from_file_by_path_no_data_items_allowed(self): def test_request_body_from_file_by_path_no_data_items_allowed(self):
r = http( env = TestEnvironment(stdin_isatty=False)
'POST', r = http('POST', httpbin('/post'), '@' + FILE_PATH_ARG, 'foo=bar',
httpbin('/post'), env=env)
'@' + FILE_PATH_ARG,
'foo=bar',
env=TestEnvironment(stdin_isatty=False)
)
assert 'cannot be mixed' in r.stderr assert 'cannot be mixed' in r.stderr

View File

@ -9,7 +9,6 @@ from httpie.compat import is_windows
class WindowsOnlyTests(TestCase): class WindowsOnlyTests(TestCase):
@pytest.mark.skipif(not is_windows, reason='windows-only') @pytest.mark.skipif(not is_windows, reason='windows-only')
def test_windows_colorized_output(self): def test_windows_colorized_output(self):
# Spits out the colorized output. # Spits out the colorized output.
@ -17,15 +16,9 @@ class WindowsOnlyTests(TestCase):
class FakeWindowsTest(TestCase): class FakeWindowsTest(TestCase):
def test_output_file_pretty_not_allowed_on_windows(self): def test_output_file_pretty_not_allowed_on_windows(self):
env = TestEnvironment(is_windows=True)
r = http( r = http('--output',
'--output', os.path.join(tempfile.gettempdir(), '__httpie_test_output__'),
os.path.join(tempfile.gettempdir(), '__httpie_test_output__'), '--pretty=all', 'GET', httpbin('/get'), env=env)
'--pretty=all',
'GET',
httpbin('/get'),
env=TestEnvironment(is_windows=True)
)
assert 'Only terminal output can be colorized on Windows' in r.stderr assert 'Only terminal output can be colorized on Windows' in r.stderr