forked from extern/httpie-cli
Run tests against local httpbin instance via pytest-httpbin.
This commit is contained in:
parent
79329ed1c6
commit
2a72ae23d5
@ -105,8 +105,13 @@ class HTTPRequest(HTTPMessage):
|
|||||||
if 'Host' not in self._orig.headers:
|
if 'Host' not in self._orig.headers:
|
||||||
headers['Host'] = url.netloc.split('@')[-1]
|
headers['Host'] = url.netloc.split('@')[-1]
|
||||||
|
|
||||||
headers = ['%s: %s' % (name, value)
|
headers = [
|
||||||
for name, value in headers.items()]
|
'%s: %s' % (
|
||||||
|
name,
|
||||||
|
value if isinstance(value, str) else value.decode('utf8')
|
||||||
|
)
|
||||||
|
for name, value in headers.items()
|
||||||
|
]
|
||||||
|
|
||||||
headers.insert(0, request_line)
|
headers.insert(0, request_line)
|
||||||
headers = '\r\n'.join(headers).strip()
|
headers = '\r\n'.join(headers).strip()
|
||||||
|
@ -2,4 +2,5 @@ tox
|
|||||||
pytest
|
pytest
|
||||||
pytest-xdist
|
pytest-xdist
|
||||||
pytest-cov
|
pytest-cov
|
||||||
|
pytest-httpbin
|
||||||
docutils
|
docutils
|
||||||
|
1
setup.py
1
setup.py
@ -26,6 +26,7 @@ class PyTest(TestCommand):
|
|||||||
|
|
||||||
tests_require = [
|
tests_require = [
|
||||||
'pytest',
|
'pytest',
|
||||||
|
'pytest-httpbin',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,42 +2,45 @@
|
|||||||
import requests
|
import requests
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from utils import http, httpbin, HTTP_OK
|
from utils import http, add_auth, HTTP_OK
|
||||||
import httpie.input
|
import httpie.input
|
||||||
|
|
||||||
|
|
||||||
class TestAuth:
|
class TestAuth:
|
||||||
def test_basic_auth(self):
|
def test_basic_auth(self, httpbin):
|
||||||
r = http('--auth=user:password',
|
r = http('--auth=user:password',
|
||||||
'GET', httpbin('/basic-auth/user/password'))
|
'GET', httpbin.url + '/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.skipif(
|
@pytest.mark.skipif(
|
||||||
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, httpbin):
|
||||||
r = http('--auth-type=digest', '--auth=user:password',
|
r = http('--auth-type=digest', '--auth=user:password',
|
||||||
'GET', httpbin('/digest-auth/auth/user/password'))
|
'GET', httpbin.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'}
|
||||||
|
|
||||||
def test_password_prompt(self):
|
def test_password_prompt(self, httpbin):
|
||||||
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.url + '/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'}
|
||||||
|
|
||||||
def test_credentials_in_url(self):
|
def test_credentials_in_url(self, httpbin):
|
||||||
url = httpbin('/basic-auth/user/password', auth='user:password')
|
url = add_auth(httpbin.url + '/basic-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(self):
|
def test_credentials_in_url_auth_flag_has_priority(self, httpbin):
|
||||||
"""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 = httpbin('/basic-auth/user/password', auth='user:wrong')
|
url = add_auth(httpbin.url + '/basic-auth/user/password',
|
||||||
|
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
|
||||||
assert r.json == {'authenticated': True, 'user': 'user'}
|
assert r.json == {'authenticated': True, 'user': 'user'}
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
"""Tests for dealing with binary request and response data."""
|
"""Tests for dealing with binary request and response data."""
|
||||||
from httpie.compat import urlopen
|
from httpie.compat import urlopen
|
||||||
from httpie.output.streams import BINARY_SUPPRESSED_NOTICE
|
from httpie.output.streams import BINARY_SUPPRESSED_NOTICE
|
||||||
from utils import TestEnvironment, http, httpbin
|
from utils import TestEnvironment, http
|
||||||
from fixtures import BIN_FILE_PATH, BIN_FILE_CONTENT, BIN_FILE_PATH_ARG
|
from fixtures import BIN_FILE_PATH, BIN_FILE_CONTENT, BIN_FILE_PATH_ARG
|
||||||
|
|
||||||
|
|
||||||
class TestBinaryRequestData:
|
class TestBinaryRequestData:
|
||||||
def test_binary_stdin(self):
|
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(
|
||||||
stdin=stdin,
|
stdin=stdin,
|
||||||
stdin_isatty=False,
|
stdin_isatty=False,
|
||||||
stdout_isatty=False
|
stdout_isatty=False
|
||||||
)
|
)
|
||||||
r = http('--print=B', 'POST', httpbin('/post'), env=env)
|
r = http('--print=B', 'POST', httpbin.url + '/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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
||||||
r = http('--print=B', 'POST', httpbin('/post'),
|
r = http('--print=B', 'POST', httpbin.url + '/post',
|
||||||
'@' + BIN_FILE_PATH_ARG, env=env, )
|
'@' + 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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
||||||
r = http('--print=B', '--form', 'POST', httpbin('/post'),
|
r = http('--print=B', '--form', 'POST', httpbin.url + '/post',
|
||||||
'test@' + BIN_FILE_PATH_ARG, env=env)
|
'test@' + BIN_FILE_PATH_ARG, env=env)
|
||||||
assert bytes(BIN_FILE_CONTENT) in bytes(r)
|
assert bytes(BIN_FILE_CONTENT) in bytes(r)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ from httpie import input
|
|||||||
from httpie.input import KeyValue, KeyValueArgType
|
from httpie.input import KeyValue, KeyValueArgType
|
||||||
from httpie import ExitStatus
|
from httpie import ExitStatus
|
||||||
from httpie.cli import parser
|
from httpie.cli import parser
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, http, HTTP_OK
|
||||||
from fixtures import (
|
from fixtures import (
|
||||||
FILE_PATH_ARG, JSON_FILE_PATH_ARG,
|
FILE_PATH_ARG, JSON_FILE_PATH_ARG,
|
||||||
JSON_FILE_CONTENT, FILE_CONTENT, FILE_PATH
|
JSON_FILE_CONTENT, FILE_CONTENT, FILE_PATH
|
||||||
@ -93,27 +93,28 @@ class TestItemParsing:
|
|||||||
|
|
||||||
|
|
||||||
class TestQuerystring:
|
class TestQuerystring:
|
||||||
def test_query_string_params_in_url(self):
|
def test_query_string_params_in_url(self, httpbin):
|
||||||
r = http('--print=Hhb', 'GET', httpbin('/get?a=1&b=2'))
|
r = http('--print=Hhb', 'GET', httpbin.url + '/get?a=1&b=2')
|
||||||
path = '/get?a=1&b=2'
|
path = '/get?a=1&b=2'
|
||||||
url = httpbin(path)
|
url = httpbin.url + 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, httpbin):
|
||||||
r = http('--print=Hhb', 'GET', httpbin('/get'), 'a==1', 'b==2')
|
r = http('--print=Hhb', 'GET', httpbin.url + '/get', 'a==1')
|
||||||
path = '/get?a=1&b=2'
|
path = '/get?a=1'
|
||||||
url = httpbin(path)
|
url = httpbin.url + 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('--print=Hhb', 'GET', httpbin('/get?a=1&a=1'),
|
httpbin):
|
||||||
'a==1', 'a==1', 'b==2')
|
r = http('--print=Hhb', 'GET',
|
||||||
path = '/get?a=1&a=1&a=1&a=1&b=2'
|
httpbin.url + '/get?a=1&a=1', 'a==1', 'a==1')
|
||||||
url = httpbin(path)
|
path = '/get?a=1&a=1&a=1&a=1'
|
||||||
|
url = httpbin.url + 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
|
||||||
@ -257,12 +258,13 @@ class TestArgumentParser:
|
|||||||
|
|
||||||
|
|
||||||
class TestNoOptions:
|
class TestNoOptions:
|
||||||
def test_valid_no_options(self):
|
|
||||||
r = http('--verbose', '--no-verbose', 'GET', httpbin('/get'))
|
def test_valid_no_options(self, httpbin):
|
||||||
|
r = http('--verbose', '--no-verbose', 'GET', httpbin.url + '/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, httpbin):
|
||||||
r = http('--no-war', 'GET', httpbin('/get'),
|
r = http('--no-war', 'GET', httpbin.url + '/get',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
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
|
||||||
@ -270,16 +272,18 @@ class TestNoOptions:
|
|||||||
|
|
||||||
|
|
||||||
class TestIgnoreStdin:
|
class TestIgnoreStdin:
|
||||||
def test_ignore_stdin(self):
|
|
||||||
|
def test_ignore_stdin(self, httpbin):
|
||||||
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('--ignore-stdin', '--verbose', httpbin('/get'), env=env)
|
r = http('--ignore-stdin', '--verbose', httpbin.url + '/get',
|
||||||
|
env=env)
|
||||||
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, httpbin):
|
||||||
r = http('--ignore-stdin', '--auth=no-password', httpbin('/get'),
|
r = http('--ignore-stdin', '--auth=no-password', httpbin.url + '/get',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
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
|
||||||
|
@ -2,34 +2,34 @@
|
|||||||
Tests for the provided defaults regarding HTTP method, and --json vs. --form.
|
Tests for the provided defaults regarding HTTP method, and --json vs. --form.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, http, HTTP_OK, no_content_type
|
||||||
from fixtures import FILE_PATH
|
from fixtures import FILE_PATH
|
||||||
|
|
||||||
|
|
||||||
class TestImplicitHTTPMethod:
|
class TestImplicitHTTPMethod:
|
||||||
def test_implicit_GET(self):
|
def test_implicit_GET(self, httpbin):
|
||||||
r = http(httpbin('/get'))
|
r = http(httpbin.url + '/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, httpbin):
|
||||||
r = http(httpbin('/headers'), 'Foo:bar')
|
r = http(httpbin.url + '/headers', 'Foo:bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['headers']['Foo'] == 'bar'
|
assert r.json['headers']['Foo'] == 'bar'
|
||||||
|
|
||||||
def test_implicit_POST_json(self):
|
def test_implicit_POST_json(self, httpbin):
|
||||||
r = http(httpbin('/post'), 'hello=world')
|
r = http(httpbin.url + '/post', 'hello=world')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json'] == {'hello': 'world'}
|
assert r.json['json'] == {'hello': 'world'}
|
||||||
|
|
||||||
def test_implicit_POST_form(self):
|
def test_implicit_POST_form(self, httpbin):
|
||||||
r = http('--form', httpbin('/post'), 'foo=bar')
|
r = http('--form', httpbin.url + '/post', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['form'] == {'foo': 'bar'}
|
assert r.json['form'] == {'foo': 'bar'}
|
||||||
|
|
||||||
def test_implicit_POST_stdin(self):
|
def test_implicit_POST_stdin(self, httpbin):
|
||||||
with open(FILE_PATH) as f:
|
with open(FILE_PATH) as f:
|
||||||
env = TestEnvironment(stdin_isatty=False, stdin=f)
|
env = TestEnvironment(stdin_isatty=False, stdin=f)
|
||||||
r = http('--form', httpbin('/post'), env=env)
|
r = http('--form', httpbin.url + '/post', env=env)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
|
|
||||||
@ -41,66 +41,66 @@ class TestAutoContentTypeAndAcceptHeaders:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_GET_no_data_no_auto_headers(self):
|
def test_GET_no_data_no_auto_headers(self, httpbin):
|
||||||
# https://github.com/jakubroztocil/httpie/issues/62
|
# https://github.com/jakubroztocil/httpie/issues/62
|
||||||
r = http('GET', httpbin('/headers'))
|
r = http('GET', httpbin.url + '/headers')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['headers']['Accept'] == '*/*'
|
assert r.json['headers']['Accept'] == '*/*'
|
||||||
assert 'Content-Type' not in r.json['headers']
|
assert no_content_type(r.json['headers'])
|
||||||
|
|
||||||
def test_POST_no_data_no_auto_headers(self):
|
def test_POST_no_data_no_auto_headers(self, httpbin):
|
||||||
# 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('POST', httpbin('/post'))
|
r = http('POST', httpbin.url + '/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, httpbin):
|
||||||
r = http('POST', httpbin('/post'), 'a=b')
|
r = http('POST', httpbin.url + '/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, httpbin):
|
||||||
# JSON headers should automatically be set also for GET with data.
|
# JSON headers should automatically be set also for GET with data.
|
||||||
r = http('POST', httpbin('/post'), 'a=b')
|
r = http('POST', httpbin.url + '/post', 'a=b')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert '"Accept": "application/json"' in r, r
|
assert '"Accept": "application/json"' in r, 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, httpbin):
|
||||||
r = http('--json', 'POST', httpbin('/post'))
|
r = http('--json', 'POST', httpbin.url + '/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.
|
||||||
# https://github.com/jakubroztocil/httpie/issues/137
|
# https://github.com/jakubroztocil/httpie/issues/137
|
||||||
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, httpbin):
|
||||||
r = http('--json', 'GET', httpbin('/headers'),
|
r = http('--json', 'GET', httpbin.url + '/headers',
|
||||||
'Accept:application/xml',
|
'Accept:application/xml',
|
||||||
'Content-Type: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, httpbin):
|
||||||
r = http('--form', 'POST', httpbin('/post'))
|
r = http('--form', 'POST', httpbin.url + '/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, httpbin):
|
||||||
r = http('--form', 'POST', httpbin('/post'),
|
r = http('--form', 'POST', httpbin.url + '/post',
|
||||||
'Content-Type:application/xml')
|
'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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
||||||
r = http('GET', httpbin('/get'), env=env)
|
r = http('GET', httpbin.url + '/get', env=env)
|
||||||
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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
env = TestEnvironment(stdin_isatty=True, stdout_isatty=False)
|
||||||
r = http('--print=h', 'GET', httpbin('/get'), env=env)
|
r = http('--print=h', 'GET', httpbin.url + '/get', env=env)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
@ -9,7 +9,7 @@ from httpie.downloads import (
|
|||||||
parse_content_range, filename_from_content_disposition, filename_from_url,
|
parse_content_range, filename_from_content_disposition, filename_from_url,
|
||||||
get_unique_filename, ContentRangeError, Download,
|
get_unique_filename, ContentRangeError, Download,
|
||||||
)
|
)
|
||||||
from utils import httpbin, http, TestEnvironment
|
from utils import http, TestEnvironment
|
||||||
|
|
||||||
|
|
||||||
class Response(object):
|
class Response(object):
|
||||||
@ -94,8 +94,8 @@ class TestDownloadUtils:
|
|||||||
class TestDownloads:
|
class TestDownloads:
|
||||||
# TODO: more tests
|
# TODO: more tests
|
||||||
|
|
||||||
def test_actual_download(self):
|
def test_actual_download(self, httpbin):
|
||||||
url = httpbin('/robots.txt')
|
url = httpbin.url + '/robots.txt'
|
||||||
body = urlopen(url).read().decode()
|
body = urlopen(url).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', url, env=env)
|
||||||
@ -104,11 +104,11 @@ class TestDownloads:
|
|||||||
assert 'Done' in r.stderr
|
assert 'Done' in r.stderr
|
||||||
assert body == r
|
assert body == r
|
||||||
|
|
||||||
def test_download_with_Content_Length(self):
|
def test_download_with_Content_Length(self, httpbin):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
download = Download(output_file=devnull, progress_file=devnull)
|
download = Download(output_file=devnull, progress_file=devnull)
|
||||||
download.start(Response(
|
download.start(Response(
|
||||||
url=httpbin('/'),
|
url=httpbin.url + '/',
|
||||||
headers={'Content-Length': 10}
|
headers={'Content-Length': 10}
|
||||||
))
|
))
|
||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
@ -118,20 +118,20 @@ class TestDownloads:
|
|||||||
download.finish()
|
download.finish()
|
||||||
assert not download.interrupted
|
assert not download.interrupted
|
||||||
|
|
||||||
def test_download_no_Content_Length(self):
|
def test_download_no_Content_Length(self, httpbin):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
download = Download(output_file=devnull, progress_file=devnull)
|
download = Download(output_file=devnull, progress_file=devnull)
|
||||||
download.start(Response(url=httpbin('/')))
|
download.start(Response(url=httpbin.url + '/'))
|
||||||
time.sleep(1.1)
|
time.sleep(1.1)
|
||||||
download.chunk_downloaded(b'12345')
|
download.chunk_downloaded(b'12345')
|
||||||
download.finish()
|
download.finish()
|
||||||
assert not download.interrupted
|
assert not download.interrupted
|
||||||
|
|
||||||
def test_download_interrupted(self):
|
def test_download_interrupted(self, httpbin):
|
||||||
devnull = open(os.devnull, 'w')
|
devnull = open(os.devnull, 'w')
|
||||||
download = Download(output_file=devnull, progress_file=devnull)
|
download = Download(output_file=devnull, progress_file=devnull)
|
||||||
download.start(Response(
|
download.start(Response(
|
||||||
url=httpbin('/'),
|
url=httpbin.url + '/',
|
||||||
headers={'Content-Length': 5}
|
headers={'Content-Length': 5}
|
||||||
))
|
))
|
||||||
download.chunk_downloaded(b'1234')
|
download.chunk_downloaded(b'1234')
|
||||||
|
@ -2,18 +2,18 @@ import requests
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from httpie import ExitStatus
|
from httpie import ExitStatus
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, http, HTTP_OK
|
||||||
|
|
||||||
|
|
||||||
class TestExitStatus:
|
class TestExitStatus:
|
||||||
def test_ok_response_exits_0(self):
|
def test_ok_response_exits_0(self, httpbin):
|
||||||
r = http('GET', httpbin('/status/200'))
|
r = http('GET', httpbin.url + '/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, httpbin):
|
||||||
r = http('GET', httpbin('/status/500'))
|
r = http('GET', httpbin.url + '/status/500')
|
||||||
assert 'HTTP/1.1 500' in r
|
assert '500 INTERNAL SERVER ERRO' in r
|
||||||
assert r.exit_status == ExitStatus.OK
|
assert r.exit_status == ExitStatus.OK
|
||||||
assert not r.stderr
|
assert not r.stderr
|
||||||
|
|
||||||
@ -21,40 +21,43 @@ class TestExitStatus:
|
|||||||
tuple(map(int, requests.__version__.split('.'))) < (2, 3, 0),
|
tuple(map(int, requests.__version__.split('.'))) < (2, 3, 0),
|
||||||
reason='timeout broken in requests prior v2.3.0 (#185)'
|
reason='timeout broken in requests prior v2.3.0 (#185)'
|
||||||
)
|
)
|
||||||
def test_timeout_exit_status(self):
|
def test_timeout_exit_status(self, httpbin):
|
||||||
|
|
||||||
r = http('--timeout=0.5', 'GET', httpbin('/delay/1'),
|
r = http('--timeout=0.5', 'GET', httpbin.url + '/delay/1',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
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, httpbin):
|
||||||
env = TestEnvironment(stdout_isatty=False)
|
env = TestEnvironment(stdout_isatty=False)
|
||||||
r = http('--check-status', '--headers', 'GET', httpbin('/status/301'),
|
r = http('--check-status', '--headers',
|
||||||
|
'GET', httpbin.url + '/status/301',
|
||||||
env=env, error_exit_ok=True)
|
env=env, error_exit_ok=True)
|
||||||
assert 'HTTP/1.1 301' in r
|
assert '301 MOVED PERMANENTLY' 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()
|
||||||
|
|
||||||
@pytest.mark.skipif(
|
@pytest.mark.skipif(
|
||||||
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, httpbin):
|
||||||
r = http('--check-status', '--follow', 'GET', httpbin('/status/301'),
|
r = http('--check-status', '--follow',
|
||||||
|
'GET', httpbin.url + '/status/301',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
# 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_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, httpbin):
|
||||||
r = http('--check-status', 'GET', httpbin('/status/401'),
|
r = http('--check-status', 'GET', httpbin.url + '/status/401',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
assert 'HTTP/1.1 401' in r
|
assert '401 UNAUTHORIZED' 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, httpbin):
|
||||||
r = http('--check-status', 'GET', httpbin('/status/500'),
|
r = http('--check-status', 'GET', httpbin.url + '/status/500',
|
||||||
error_exit_ok=True)
|
error_exit_ok=True)
|
||||||
assert 'HTTP/1.1 500' in r
|
assert '500 INTERNAL SERVER ERROR' in r
|
||||||
assert r.exit_status == ExitStatus.ERROR_HTTP_5XX
|
assert r.exit_status == ExitStatus.ERROR_HTTP_5XX
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""High-level tests."""
|
"""High-level tests."""
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, http, HTTP_OK
|
||||||
from fixtures import FILE_PATH, FILE_CONTENT
|
from fixtures import FILE_PATH, FILE_CONTENT
|
||||||
import httpie
|
import httpie
|
||||||
|
|
||||||
@ -23,43 +23,43 @@ class TestHTTPie:
|
|||||||
# FIXME: py3 has version in stdout, py2 in stderr
|
# FIXME: py3 has version in stdout, py2 in stderr
|
||||||
assert httpie.__version__ == r.stderr.strip() + r.strip()
|
assert httpie.__version__ == r.stderr.strip() + r.strip()
|
||||||
|
|
||||||
def test_GET(self):
|
def test_GET(self, httpbin):
|
||||||
r = http('GET', httpbin('/get'))
|
r = http('GET', httpbin.url + '/get')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_DELETE(self):
|
def test_DELETE(self, httpbin):
|
||||||
r = http('DELETE', httpbin('/delete'))
|
r = http('DELETE', httpbin.url + '/delete')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_PUT(self):
|
def test_PUT(self, httpbin):
|
||||||
r = http('PUT', httpbin('/put'), 'foo=bar')
|
r = http('PUT', httpbin.url + '/put', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r'\"foo\": \"bar\"' in r
|
assert r.json['json']['foo'] == 'bar'
|
||||||
|
|
||||||
def test_POST_JSON_data(self):
|
def test_POST_JSON_data(self, httpbin):
|
||||||
r = http('POST', httpbin('/post'), 'foo=bar')
|
r = http('POST', httpbin.url + '/post', 'foo=bar')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r'\"foo\": \"bar\"' in r
|
assert r.json['json']['foo'] == 'bar'
|
||||||
|
|
||||||
def test_POST_form(self):
|
def test_POST_form(self, httpbin):
|
||||||
r = http('--form', 'POST', httpbin('/post'), 'foo=bar')
|
r = http('--form', 'POST', httpbin.url + '/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, httpbin):
|
||||||
r = http('--form', 'POST', httpbin('/post'), 'foo=bar', 'foo=baz')
|
r = http('--form', 'POST', httpbin.url + '/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, httpbin):
|
||||||
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('/post'), env=env)
|
r = http('--form', 'POST', httpbin.url + '/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, httpbin):
|
||||||
r = http('GET', httpbin('/headers'), 'Foo:bar')
|
r = http('GET', httpbin.url + '/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
|
||||||
|
@ -2,27 +2,28 @@ import pytest
|
|||||||
|
|
||||||
from httpie import ExitStatus
|
from httpie import ExitStatus
|
||||||
from httpie.output.formatters.colors import get_lexer
|
from httpie.output.formatters.colors import get_lexer
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK, COLOR, CRLF
|
from utils import TestEnvironment, http, HTTP_OK, COLOR, CRLF
|
||||||
|
|
||||||
|
|
||||||
class TestVerboseFlag:
|
class TestVerboseFlag:
|
||||||
def test_verbose(self):
|
def test_verbose(self, httpbin):
|
||||||
r = http('--verbose', 'GET', httpbin('/get'), 'test-header:__test__')
|
r = http('--verbose',
|
||||||
|
'GET', httpbin.url + '/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, httpbin):
|
||||||
# https://github.com/jakubroztocil/httpie/issues/53
|
# https://github.com/jakubroztocil/httpie/issues/53
|
||||||
r = http('--verbose', '--form', 'POST', httpbin('/post'),
|
r = http('--verbose', '--form', 'POST', httpbin.url + '/post',
|
||||||
'A=B', 'C=D')
|
'A=B', 'C=D')
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert 'A=B&C=D' in r
|
assert 'A=B&C=D' in r
|
||||||
|
|
||||||
def test_verbose_json(self):
|
def test_verbose_json(self, httpbin):
|
||||||
r = http('--verbose', 'POST', httpbin('/post'), 'foo=bar', 'baz=bar')
|
r = http('--verbose',
|
||||||
|
'POST', httpbin.url + '/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
|
||||||
assert r'\"baz\": \"bar\"' in r # response
|
|
||||||
|
|
||||||
|
|
||||||
class TestColors:
|
class TestColors:
|
||||||
@ -47,45 +48,47 @@ class TestColors:
|
|||||||
class TestPrettyOptions:
|
class TestPrettyOptions:
|
||||||
"""Test the --pretty flag handling."""
|
"""Test the --pretty flag handling."""
|
||||||
|
|
||||||
def test_pretty_enabled_by_default(self):
|
def test_pretty_enabled_by_default(self, httpbin):
|
||||||
env = TestEnvironment(colors=256)
|
env = TestEnvironment(colors=256)
|
||||||
r = http('GET', httpbin('/get'), env=env)
|
r = http('GET', httpbin.url + '/get', env=env)
|
||||||
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, httpbin):
|
||||||
r = http('GET', httpbin('/get'))
|
r = http('GET', httpbin.url + '/get')
|
||||||
assert COLOR not in r
|
assert COLOR not in r
|
||||||
|
|
||||||
def test_force_pretty(self):
|
def test_force_pretty(self, httpbin):
|
||||||
env = TestEnvironment(stdout_isatty=False, colors=256)
|
env = TestEnvironment(stdout_isatty=False, colors=256)
|
||||||
r = http('--pretty=all', 'GET', httpbin('/get'), env=env, )
|
r = http('--pretty=all', 'GET', httpbin.url + '/get', env=env, )
|
||||||
assert COLOR in r
|
assert COLOR in r
|
||||||
|
|
||||||
def test_force_ugly(self):
|
def test_force_ugly(self, httpbin):
|
||||||
r = http('--pretty=none', 'GET', httpbin('/get'))
|
r = http('--pretty=none', 'GET', httpbin.url + '/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, httpbin):
|
||||||
"""Test that media subtype is used if type/subtype doesn't
|
"""Test that media subtype is used if type/subtype doesn't
|
||||||
match any lexer.
|
match any lexer.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
env = TestEnvironment(colors=256)
|
env = TestEnvironment(colors=256)
|
||||||
r = http('--print=B', '--pretty=all', httpbin('/post'),
|
r = http('--print=B', '--pretty=all', httpbin.url + '/post',
|
||||||
'Content-Type:text/foo+json', 'a=b', env=env)
|
'Content-Type:text/foo+json', 'a=b', env=env)
|
||||||
assert COLOR in r
|
assert COLOR in r
|
||||||
|
|
||||||
def test_colors_option(self):
|
def test_colors_option(self, httpbin):
|
||||||
env = TestEnvironment(colors=256)
|
env = TestEnvironment(colors=256)
|
||||||
r = http('--print=B', '--pretty=colors', 'GET', httpbin('/get'), 'a=b',
|
r = http('--print=B', '--pretty=colors',
|
||||||
|
'GET', httpbin.url + '/get', 'a=b',
|
||||||
env=env)
|
env=env)
|
||||||
# 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, httpbin):
|
||||||
env = TestEnvironment(colors=256)
|
env = TestEnvironment(colors=256)
|
||||||
r = http('--print=B', '--pretty=format', 'GET', httpbin('/get'), 'a=b',
|
r = http('--print=B', '--pretty=format',
|
||||||
|
'GET', httpbin.url + '/get', 'a=b',
|
||||||
env=env)
|
env=env)
|
||||||
# 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
|
||||||
@ -110,24 +113,24 @@ class TestLineEndings:
|
|||||||
assert CRLF not in body
|
assert CRLF not in body
|
||||||
return body
|
return body
|
||||||
|
|
||||||
def test_CRLF_headers_only(self):
|
def test_CRLF_headers_only(self, httpbin):
|
||||||
r = http('--headers', 'GET', httpbin('/get'))
|
r = http('--headers', 'GET', httpbin.url + '/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, httpbin):
|
||||||
r = http('--pretty=none', 'GET', httpbin('/get'))
|
r = http('--pretty=none', 'GET', httpbin.url + '/get')
|
||||||
self._validate_crlf(r)
|
self._validate_crlf(r)
|
||||||
|
|
||||||
def test_CRLF_formatted_response(self):
|
def test_CRLF_formatted_response(self, httpbin):
|
||||||
r = http('--pretty=format', 'GET', httpbin('/get'))
|
r = http('--pretty=format', 'GET', httpbin.url + '/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, httpbin):
|
||||||
r = http('--pretty=none', '--print=HB', 'GET', httpbin('/get'))
|
r = http('--pretty=none', '--print=HB', 'GET', httpbin.url + '/get')
|
||||||
self._validate_crlf(r)
|
self._validate_crlf(r)
|
||||||
|
|
||||||
def test_CRLF_formatted_request(self):
|
def test_CRLF_formatted_request(self, httpbin):
|
||||||
r = http('--pretty=format', '--print=HB', 'GET', httpbin('/get'))
|
r = http('--pretty=format', '--print=HB', 'GET', httpbin.url + '/get')
|
||||||
self._validate_crlf(r)
|
self._validate_crlf(r)
|
||||||
|
@ -4,14 +4,14 @@ import socket
|
|||||||
from utils import http, HTTP_OK
|
from utils import http, HTTP_OK
|
||||||
|
|
||||||
|
|
||||||
def test_Host_header_overwrite():
|
def test_Host_header_overwrite(httpbin):
|
||||||
"""
|
"""
|
||||||
https://github.com/jakubroztocil/httpie/issues/235
|
https://github.com/jakubroztocil/httpie/issues/235
|
||||||
|
|
||||||
"""
|
"""
|
||||||
host = 'httpbin.org'
|
host = 'httpbin.org'
|
||||||
url = 'http://{httpbin_ip}/get'.format(
|
url = httpbin.url + '/get'
|
||||||
httpbin_ip=socket.gethostbyname(host))
|
r = http('--print=hH', url, 'host:{0}'.format(host))
|
||||||
r = http('--print=hH', url, 'host:{}'.format(host))
|
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.lower().count('host:') == 1
|
assert r.lower().count('host:') == 1
|
||||||
|
assert 'host: {0}'.format(host) in r
|
||||||
|
@ -3,12 +3,14 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from httpie.plugins.builtin import HTTPBasicAuth
|
from httpie.plugins.builtin import HTTPBasicAuth
|
||||||
from utils import TestEnvironment, mk_config_dir, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, mk_config_dir, http, HTTP_OK, \
|
||||||
|
no_content_type
|
||||||
from fixtures import UNICODE
|
from fixtures import UNICODE
|
||||||
|
|
||||||
|
|
||||||
class SessionTestBase(object):
|
class SessionTestBase(object):
|
||||||
def setup_method(self, method):
|
|
||||||
|
def start_session(self, httpbin):
|
||||||
"""Create and reuse a unique config dir for each test."""
|
"""Create and reuse a unique config dir for each test."""
|
||||||
self.config_dir = mk_config_dir()
|
self.config_dir = mk_config_dir()
|
||||||
|
|
||||||
@ -33,67 +35,70 @@ class TestSessionFlow(SessionTestBase):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setup_method(self, method):
|
def start_session(self, httpbin):
|
||||||
"""
|
"""
|
||||||
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.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
super(TestSessionFlow, self).setup_method(method)
|
super(TestSessionFlow, self).start_session(httpbin)
|
||||||
r1 = http('--follow', '--session=test', '--auth=username:password',
|
r1 = http('--follow', '--session=test', '--auth=username:password',
|
||||||
'GET', httpbin('/cookies/set?hello=world'), 'Hello:World',
|
'GET', httpbin.url + '/cookies/set?hello=world',
|
||||||
|
'Hello:World',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r1
|
assert HTTP_OK in r1
|
||||||
|
|
||||||
def test_session_created_and_reused(self):
|
def test_session_created_and_reused(self, httpbin):
|
||||||
|
self.start_session(httpbin)
|
||||||
# Verify that the session created in setup_method() has been used.
|
# Verify that the session created in setup_method() has been used.
|
||||||
r2 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r2 = http('--session=test',
|
||||||
|
'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
assert r2.json['headers']['Hello'] == 'World'
|
assert r2.json['headers']['Hello'] == 'World'
|
||||||
assert r2.json['headers']['Cookie'] == 'hello=world'
|
assert r2.json['headers']['Cookie'] == 'hello=world'
|
||||||
assert 'Basic ' in r2.json['headers']['Authorization']
|
assert 'Basic ' in r2.json['headers']['Authorization']
|
||||||
|
|
||||||
def test_session_update(self):
|
def test_session_update(self, httpbin):
|
||||||
|
self.start_session(httpbin)
|
||||||
# Get a response to a request from the original session.
|
# Get a response to a request from the original session.
|
||||||
r2 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r2 = http('--session=test', 'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
|
|
||||||
# Make a request modifying the session data.
|
# Make a request modifying the session data.
|
||||||
r3 = http('--follow', '--session=test', '--auth=username:password2',
|
r3 = http('--follow', '--session=test', '--auth=username:password2',
|
||||||
'GET', httpbin('/cookies/set?hello=world2'), 'Hello:World2',
|
'GET', httpbin.url + '/cookies/set?hello=world2', 'Hello:World2',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r3
|
assert HTTP_OK in r3
|
||||||
|
|
||||||
# Get a response to a request from the updated session.
|
# Get a response to a request from the updated session.
|
||||||
r4 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r4 = http('--session=test', 'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r4
|
assert HTTP_OK in r4
|
||||||
assert r4.json['headers']['Hello'] == 'World2'
|
assert r4.json['headers']['Hello'] == 'World2'
|
||||||
assert r4.json['headers']['Cookie'] == 'hello=world2'
|
assert r4.json['headers']['Cookie'] == 'hello=world2'
|
||||||
assert (r2.json['headers']['Authorization'] !=
|
assert (r2.json['headers']['Authorization'] !=
|
||||||
r4.json['headers']['Authorization'])
|
r4.json['headers']['Authorization'])
|
||||||
|
|
||||||
def test_session_read_only(self):
|
def test_session_read_only(self, httpbin):
|
||||||
|
self.start_session(httpbin)
|
||||||
# Get a response from the original session.
|
# Get a response from the original session.
|
||||||
r2 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r2 = http('--session=test', 'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
|
|
||||||
# Make a request modifying the session data but
|
# Make a request modifying the session data but
|
||||||
# with --session-read-only.
|
# with --session-read-only.
|
||||||
r3 = http('--follow', '--session-read-only=test',
|
r3 = http('--follow', '--session-read-only=test',
|
||||||
'--auth=username:password2', 'GET',
|
'--auth=username:password2', 'GET',
|
||||||
httpbin('/cookies/set?hello=world2'), 'Hello:World2',
|
httpbin.url + '/cookies/set?hello=world2', 'Hello:World2',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r3
|
assert HTTP_OK in r3
|
||||||
|
|
||||||
# Get a response from the updated session.
|
# Get a response from the updated session.
|
||||||
r4 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r4 = http('--session=test', 'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r4
|
assert HTTP_OK in r4
|
||||||
|
|
||||||
# Origin can differ on Travis.
|
# Origin can differ on Travis.
|
||||||
del r2.json['origin'], r4.json['origin']
|
del r2.json['origin'], r4.json['origin']
|
||||||
# Different for each request.
|
# Different for each request.
|
||||||
del r2.json['headers']['X-Request-Id']
|
|
||||||
del r4.json['headers']['X-Request-Id']
|
|
||||||
|
|
||||||
# Should be the same as before r3.
|
# Should be the same as before r3.
|
||||||
assert r2.json == r4.json
|
assert r2.json == r4.json
|
||||||
@ -102,51 +107,58 @@ class TestSessionFlow(SessionTestBase):
|
|||||||
class TestSession(SessionTestBase):
|
class TestSession(SessionTestBase):
|
||||||
"""Stand-alone session tests."""
|
"""Stand-alone session tests."""
|
||||||
|
|
||||||
def test_session_ignored_header_prefixes(self):
|
def test_session_ignored_header_prefixes(self, httpbin):
|
||||||
r1 = http('--session=test', 'GET', httpbin('/get'),
|
self.start_session(httpbin)
|
||||||
|
r1 = http('--session=test', 'GET', httpbin.url + '/get',
|
||||||
'Content-Type: text/plain',
|
'Content-Type: text/plain',
|
||||||
'If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT',
|
'If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r1
|
assert HTTP_OK in r1
|
||||||
|
|
||||||
r2 = http('--session=test', 'GET', httpbin('/get'), env=self.env())
|
r2 = http('--session=test', 'GET', httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
assert 'Content-Type' not in r2.json['headers']
|
assert no_content_type(r2.json['headers'])
|
||||||
assert 'If-Unmodified-Since' not in r2.json['headers']
|
assert 'If-Unmodified-Since' not in r2.json['headers']
|
||||||
|
|
||||||
def test_session_by_path(self):
|
def test_session_by_path(self, httpbin):
|
||||||
|
self.start_session(httpbin)
|
||||||
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('--session=' + session_path, 'GET', httpbin('/get'),
|
r1 = http('--session=' + session_path, 'GET', httpbin.url + '/get',
|
||||||
'Foo:Bar', env=self.env())
|
'Foo:Bar', env=self.env())
|
||||||
assert HTTP_OK in r1
|
assert HTTP_OK in r1
|
||||||
|
|
||||||
r2 = http('--session=' + session_path, 'GET', httpbin('/get'),
|
r2 = http('--session=' + session_path, 'GET', httpbin.url + '/get',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
assert r2.json['headers']['Foo'] == 'Bar'
|
assert r2.json['headers']['Foo'] == 'Bar'
|
||||||
|
|
||||||
def test_session_unicode(self):
|
def test_session_unicode(self, httpbin):
|
||||||
r1 = http('--session=test', '--auth', u'test:' + UNICODE,
|
self.start_session(httpbin)
|
||||||
'GET', httpbin('/get'),
|
|
||||||
u'Test:%s' % UNICODE,
|
r1 = http('--session=test', u'--auth=test:' + UNICODE,
|
||||||
|
'GET', httpbin.url + '/get', u'Test:%s' % UNICODE,
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r1
|
assert HTTP_OK in r1
|
||||||
|
|
||||||
r2 = http('--session=test', '--verbose', 'GET',
|
r2 = http('--session=test', '--verbose', 'GET',
|
||||||
httpbin('/get'), env=self.env())
|
httpbin.url + '/get', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
|
|
||||||
|
# FIXME: Authorization *sometimes* is not present on Python3
|
||||||
assert (r2.json['headers']['Authorization']
|
assert (r2.json['headers']['Authorization']
|
||||||
== HTTPBasicAuth.make_header(u'test', UNICODE))
|
== HTTPBasicAuth.make_header(u'test', UNICODE))
|
||||||
# httpbin doesn't interpret utf8 headers
|
# httpbin doesn't interpret utf8 headers
|
||||||
assert UNICODE in r2
|
assert UNICODE in r2
|
||||||
|
|
||||||
def test_session_default_header_value_overwritten(self):
|
def test_session_default_header_value_overwritten(self, httpbin):
|
||||||
|
self.start_session(httpbin)
|
||||||
# https://github.com/jakubroztocil/httpie/issues/180
|
# https://github.com/jakubroztocil/httpie/issues/180
|
||||||
r1 = http('--session=test', httpbin('/headers'), 'User-Agent:custom',
|
r1 = http('--session=test',
|
||||||
|
httpbin.url + '/headers', 'User-Agent:custom',
|
||||||
env=self.env())
|
env=self.env())
|
||||||
assert HTTP_OK in r1
|
assert HTTP_OK in r1
|
||||||
assert r1.json['headers']['User-Agent'] == 'custom'
|
assert r1.json['headers']['User-Agent'] == 'custom'
|
||||||
|
|
||||||
r2 = http('--session=test', httpbin('/headers'), env=self.env())
|
r2 = http('--session=test', httpbin.url + '/headers', env=self.env())
|
||||||
assert HTTP_OK in r2
|
assert HTTP_OK in r2
|
||||||
assert r2.json['headers']['User-Agent'] == 'custom'
|
assert r2.json['headers']['User-Agent'] == 'custom'
|
||||||
|
@ -2,7 +2,7 @@ import pytest
|
|||||||
|
|
||||||
from httpie.compat import is_windows
|
from httpie.compat import is_windows
|
||||||
from httpie.output.streams import BINARY_SUPPRESSED_NOTICE
|
from httpie.output.streams import BINARY_SUPPRESSED_NOTICE
|
||||||
from utils import http, httpbin, TestEnvironment
|
from utils import http, TestEnvironment
|
||||||
from fixtures import BIN_FILE_CONTENT, BIN_FILE_PATH
|
from fixtures import BIN_FILE_CONTENT, BIN_FILE_PATH
|
||||||
|
|
||||||
|
|
||||||
@ -11,26 +11,26 @@ class TestStream:
|
|||||||
|
|
||||||
@pytest.mark.skipif(is_windows,
|
@pytest.mark.skipif(is_windows,
|
||||||
reason='Pretty redirect not supported under Windows')
|
reason='Pretty redirect not supported under Windows')
|
||||||
def test_pretty_redirected_stream(self):
|
def test_pretty_redirected_stream(self, httpbin):
|
||||||
"""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:
|
||||||
env = TestEnvironment(colors=256, stdin=f,
|
env = TestEnvironment(colors=256, stdin=f,
|
||||||
stdin_isatty=False,
|
stdin_isatty=False,
|
||||||
stdout_isatty=False)
|
stdout_isatty=False)
|
||||||
r = http('--verbose', '--pretty=all', '--stream', 'GET',
|
r = http('--verbose', '--pretty=all', '--stream', 'GET',
|
||||||
httpbin('/get'), env=env)
|
httpbin.url + '/get', env=env)
|
||||||
assert BINARY_SUPPRESSED_NOTICE.decode() in r
|
assert BINARY_SUPPRESSED_NOTICE.decode() in r
|
||||||
|
|
||||||
def test_encoded_stream(self):
|
def test_encoded_stream(self, httpbin):
|
||||||
"""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:
|
||||||
env = TestEnvironment(stdin=f, stdin_isatty=False)
|
env = TestEnvironment(stdin=f, stdin_isatty=False)
|
||||||
r = http('--pretty=none', '--stream', '--verbose', 'GET',
|
r = http('--pretty=none', '--stream', '--verbose', 'GET',
|
||||||
httpbin('/get'), env=env)
|
httpbin.url + '/get', env=env)
|
||||||
assert BINARY_SUPPRESSED_NOTICE.decode() in r
|
assert BINARY_SUPPRESSED_NOTICE.decode() in r
|
||||||
|
|
||||||
def test_redirected_stream(self):
|
def test_redirected_stream(self, httpbin):
|
||||||
"""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:
|
||||||
@ -38,5 +38,5 @@ class TestStream:
|
|||||||
stdin_isatty=False,
|
stdin_isatty=False,
|
||||||
stdin=f)
|
stdin=f)
|
||||||
r = http('--pretty=none', '--stream', '--verbose', 'GET',
|
r = http('--pretty=none', '--stream', '--verbose', 'GET',
|
||||||
httpbin('/get'), env=env)
|
httpbin.url + '/get', env=env)
|
||||||
assert BIN_FILE_CONTENT in r
|
assert BIN_FILE_CONTENT in r
|
||||||
|
@ -3,85 +3,85 @@
|
|||||||
Various unicode handling related tests.
|
Various unicode handling related tests.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from utils import http, httpbin, HTTP_OK
|
from utils import http, HTTP_OK
|
||||||
from fixtures import UNICODE
|
from fixtures import UNICODE
|
||||||
|
|
||||||
|
|
||||||
class TestUnicode:
|
class TestUnicode:
|
||||||
|
|
||||||
def test_unicode_headers(self):
|
def test_unicode_headers(self, httpbin):
|
||||||
# httpbin doesn't interpret utf8 headers
|
# httpbin doesn't interpret utf8 headers
|
||||||
r = http(httpbin('/headers'), u'Test:%s' % UNICODE)
|
r = http(httpbin.url + '/headers', u'Test:%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
|
|
||||||
def test_unicode_headers_verbose(self):
|
def test_unicode_headers_verbose(self, httpbin):
|
||||||
# httpbin doesn't interpret utf8 headers
|
# httpbin doesn't interpret utf8 headers
|
||||||
r = http('--verbose', httpbin('/headers'), u'Test:%s' % UNICODE)
|
r = http('--verbose', httpbin.url + '/headers', u'Test:%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert UNICODE in r
|
assert UNICODE in r
|
||||||
|
|
||||||
def test_unicode_form_item(self):
|
def test_unicode_form_item(self, httpbin):
|
||||||
r = http('--form', 'POST', httpbin('/post'), u'test=%s' % UNICODE)
|
r = http('--form', 'POST', httpbin.url + '/post', u'test=%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['form'] == {'test': UNICODE}
|
assert r.json['form'] == {'test': UNICODE}
|
||||||
|
|
||||||
def test_unicode_form_item_verbose(self):
|
def test_unicode_form_item_verbose(self, httpbin):
|
||||||
r = http('--verbose', '--form',
|
r = http('--verbose', '--form',
|
||||||
'POST', httpbin('/post'), u'test=%s' % UNICODE)
|
'POST', httpbin.url + '/post', u'test=%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert UNICODE in r
|
assert UNICODE in r
|
||||||
|
|
||||||
def test_unicode_json_item(self):
|
def test_unicode_json_item(self, httpbin):
|
||||||
r = http('--json', 'POST', httpbin('/post'), u'test=%s' % UNICODE)
|
r = http('--json', 'POST', httpbin.url + '/post', u'test=%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json'] == {'test': UNICODE}
|
assert r.json['json'] == {'test': UNICODE}
|
||||||
|
|
||||||
def test_unicode_json_item_verbose(self):
|
def test_unicode_json_item_verbose(self, httpbin):
|
||||||
r = http('--verbose', '--json',
|
r = http('--verbose', '--json',
|
||||||
'POST', httpbin('/post'), u'test=%s' % UNICODE)
|
'POST', httpbin.url + '/post', u'test=%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert UNICODE in r
|
assert UNICODE in r
|
||||||
|
|
||||||
def test_unicode_raw_json_item(self):
|
def test_unicode_raw_json_item(self, httpbin):
|
||||||
r = http('--json', 'POST', httpbin('/post'),
|
r = http('--json', 'POST', httpbin.url + '/post',
|
||||||
u'test:={ "%s" : [ "%s" ] }' % (UNICODE, UNICODE))
|
u'test:={ "%s" : [ "%s" ] }' % (UNICODE, UNICODE))
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json'] == {'test': {UNICODE: [UNICODE]}}
|
assert r.json['json'] == {'test': {UNICODE: [UNICODE]}}
|
||||||
|
|
||||||
def test_unicode_raw_json_item_verbose(self):
|
def test_unicode_raw_json_item_verbose(self, httpbin):
|
||||||
r = http('--json', 'POST', httpbin('/post'),
|
r = http('--json', 'POST', httpbin.url + '/post',
|
||||||
u'test:={ "%s" : [ "%s" ] }' % (UNICODE, UNICODE))
|
u'test:={ "%s" : [ "%s" ] }' % (UNICODE, UNICODE))
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['json'] == {'test': {UNICODE: [UNICODE]}}
|
assert r.json['json'] == {'test': {UNICODE: [UNICODE]}}
|
||||||
|
|
||||||
def test_unicode_url_query_arg_item(self):
|
def test_unicode_url_query_arg_item(self, httpbin):
|
||||||
r = http(httpbin('/get'), u'test==%s' % UNICODE)
|
r = http(httpbin.url + '/get', u'test==%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['args'] == {'test': UNICODE}, r
|
assert r.json['args'] == {'test': UNICODE}, r
|
||||||
|
|
||||||
def test_unicode_url_query_arg_item_verbose(self):
|
def test_unicode_url_query_arg_item_verbose(self, httpbin):
|
||||||
r = http('--verbose', httpbin('/get'), u'test==%s' % UNICODE)
|
r = http('--verbose', httpbin.url + '/get', u'test==%s' % UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert UNICODE in r
|
assert UNICODE in r
|
||||||
|
|
||||||
def test_unicode_url(self):
|
def test_unicode_url(self, httpbin):
|
||||||
r = http(httpbin(u'/get?test=' + UNICODE))
|
r = http(httpbin.url + u'/get?test=' + UNICODE)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert r.json['args'] == {'test': UNICODE}
|
assert r.json['args'] == {'test': UNICODE}
|
||||||
|
|
||||||
# def test_unicode_url_verbose(self):
|
# def test_unicode_url_verbose(self):
|
||||||
# r = http(httpbin('--verbose', u'/get?test=' + UNICODE))
|
# r = http(httpbin.url + '--verbose', u'/get?test=' + UNICODE)
|
||||||
# assert HTTP_OK in r
|
# assert HTTP_OK in r
|
||||||
|
|
||||||
def test_unicode_basic_auth(self):
|
def test_unicode_basic_auth(self, httpbin):
|
||||||
# it doesn't really authenticate us because httpbin
|
# it doesn't really authenticate us because httpbin
|
||||||
# doesn't interpret the utf8-encoded auth
|
# doesn't interpret the utf8-encoded auth
|
||||||
http('--verbose', '--auth', u'test:%s' % UNICODE,
|
http('--verbose', '--auth', u'test:%s' % UNICODE,
|
||||||
httpbin(u'/basic-auth/test/' + UNICODE))
|
httpbin.url + u'/basic-auth/test/' + UNICODE)
|
||||||
|
|
||||||
def test_unicode_digest_auth(self):
|
def test_unicode_digest_auth(self, httpbin):
|
||||||
# it doesn't really authenticate us because httpbin
|
# it doesn't really authenticate us because httpbin
|
||||||
# doesn't interpret the utf8-encoded auth
|
# doesn't interpret the utf8-encoded auth
|
||||||
http('--auth-type=digest',
|
http('--auth-type=digest',
|
||||||
'--auth', u'test:%s' % UNICODE,
|
'--auth', u'test:%s' % UNICODE,
|
||||||
httpbin(u'/digest-auth/auth/test/' + UNICODE))
|
httpbin.url + u'/digest-auth/auth/test/' + UNICODE)
|
||||||
|
@ -3,23 +3,25 @@ import os
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from httpie.input import ParseError
|
from httpie.input import ParseError
|
||||||
from utils import TestEnvironment, http, httpbin, HTTP_OK
|
from utils import TestEnvironment, http, HTTP_OK
|
||||||
from fixtures import FILE_PATH_ARG, FILE_PATH, FILE_CONTENT
|
from fixtures import FILE_PATH_ARG, FILE_PATH, FILE_CONTENT
|
||||||
|
|
||||||
|
|
||||||
class TestMultipartFormDataFileUpload:
|
class TestMultipartFormDataFileUpload:
|
||||||
def test_non_existent_file_raises_parse_error(self):
|
|
||||||
with pytest.raises(ParseError):
|
|
||||||
http('--form', 'POST', httpbin('/post'), 'foo@/__does_not_exist__')
|
|
||||||
|
|
||||||
def test_upload_ok(self):
|
def test_non_existent_file_raises_parse_error(self, httpbin):
|
||||||
r = http('--form', '--verbose', 'POST', httpbin('/post'),
|
with pytest.raises(ParseError):
|
||||||
|
http('--form',
|
||||||
|
'POST', httpbin.url + '/post', 'foo@/__does_not_exist__')
|
||||||
|
|
||||||
|
def test_upload_ok(self, httpbin):
|
||||||
|
r = http('--form', '--verbose', 'POST', httpbin.url + '/post',
|
||||||
'test-file@%s' % FILE_PATH_ARG, 'foo=bar')
|
'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";' \
|
||||||
' filename="%s"' % os.path.basename(FILE_PATH) in r
|
' filename="%s"' % os.path.basename(FILE_PATH) in r
|
||||||
assert r.count(FILE_CONTENT) == 2
|
assert FILE_CONTENT in r
|
||||||
assert '"foo": "bar"' in r
|
assert '"foo": "bar"' in r
|
||||||
|
|
||||||
|
|
||||||
@ -29,27 +31,32 @@ class TestRequestBodyFromFilePath:
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_request_body_from_file_by_path(self):
|
def test_request_body_from_file_by_path(self, httpbin):
|
||||||
r = http('--verbose', 'POST', httpbin('/post'), '@' + FILE_PATH_ARG)
|
r = http('--verbose',
|
||||||
|
'POST', httpbin.url + '/post', '@' + FILE_PATH_ARG)
|
||||||
assert HTTP_OK in r
|
assert HTTP_OK in r
|
||||||
assert FILE_CONTENT in r, r
|
assert FILE_CONTENT in r, 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(
|
||||||
r = http('POST', httpbin('/post'), '@' + FILE_PATH_ARG,
|
self, httpbin):
|
||||||
'Content-Type:x-foo/bar')
|
r = http('--verbose',
|
||||||
|
'POST', httpbin.url + '/post', '@' + FILE_PATH_ARG,
|
||||||
|
'Content-Type:text/plain; charset=utf8')
|
||||||
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: text/plain; charset=utf8' 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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=True)
|
env = TestEnvironment(stdin_isatty=True)
|
||||||
r = http('POST', httpbin('/post'), 'field-name@' + FILE_PATH_ARG,
|
r = http('POST', httpbin.url + '/post', 'field-name@' + FILE_PATH_ARG,
|
||||||
env=env, error_exit_ok=True)
|
env=env, error_exit_ok=True)
|
||||||
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, httpbin):
|
||||||
env = TestEnvironment(stdin_isatty=False)
|
env = TestEnvironment(stdin_isatty=False)
|
||||||
r = http('POST', httpbin('/post'), '@' + FILE_PATH_ARG, 'foo=bar',
|
r = http('POST', httpbin.url + '/post', '@' + FILE_PATH_ARG, 'foo=bar',
|
||||||
env=env, error_exit_ok=True)
|
env=env, error_exit_ok=True)
|
||||||
assert 'cannot be mixed' in r.stderr
|
assert 'cannot be mixed' in r.stderr
|
||||||
|
@ -4,7 +4,7 @@ import tempfile
|
|||||||
import pytest
|
import pytest
|
||||||
from httpie.context import Environment
|
from httpie.context import Environment
|
||||||
|
|
||||||
from utils import TestEnvironment, http, httpbin
|
from utils import TestEnvironment, http
|
||||||
from httpie.compat import is_windows
|
from httpie.compat import is_windows
|
||||||
|
|
||||||
|
|
||||||
@ -13,17 +13,17 @@ class TestWindowsOnly:
|
|||||||
|
|
||||||
@pytest.mark.skipif(True,
|
@pytest.mark.skipif(True,
|
||||||
reason='this test for some reason kills the process')
|
reason='this test for some reason kills the process')
|
||||||
def test_windows_colorized_output(self):
|
def test_windows_colorized_output(self, httpbin):
|
||||||
# Spits out the colorized output.
|
# Spits out the colorized output.
|
||||||
http(httpbin('/get'), env=Environment())
|
http(httpbin.url + '/get', env=Environment())
|
||||||
|
|
||||||
|
|
||||||
class TestFakeWindows:
|
class TestFakeWindows:
|
||||||
def test_output_file_pretty_not_allowed_on_windows(self):
|
def test_output_file_pretty_not_allowed_on_windows(self, httpbin):
|
||||||
env = TestEnvironment(is_windows=True)
|
env = TestEnvironment(is_windows=True)
|
||||||
output_file = os.path.join(
|
output_file = os.path.join(
|
||||||
tempfile.gettempdir(), '__httpie_test_output__')
|
tempfile.gettempdir(), '__httpie_test_output__')
|
||||||
r = http('--output', output_file,
|
r = http('--output', output_file,
|
||||||
'--pretty=all', 'GET', httpbin('/get'),
|
'--pretty=all', 'GET', httpbin.url + '/get',
|
||||||
env=env, error_exit_ok=True)
|
env=env, error_exit_ok=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
|
||||||
|
@ -20,7 +20,7 @@ TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
|||||||
|
|
||||||
CRLF = '\r\n'
|
CRLF = '\r\n'
|
||||||
COLOR = '\x1b['
|
COLOR = '\x1b['
|
||||||
HTTP_OK = 'HTTP/1.1 200'
|
HTTP_OK = '200 OK'
|
||||||
HTTP_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'
|
||||||
@ -28,22 +28,19 @@ HTTP_OK_COLOR = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def httpbin(path, auth=None,
|
def no_content_type(headers):
|
||||||
base=os.environ.get('HTTPBIN_URL', 'http://httpbin.org')):
|
return (
|
||||||
"""
|
'Content-Type' not in headers
|
||||||
Return a fully-qualified httpbin URL for `path`.
|
# We need to do also this because of this issue:
|
||||||
|
# <https://github.com/kevin1024/pytest-httpbin/issues/5>
|
||||||
|
# TODO: remove this function once the issue is if fixed
|
||||||
|
or headers['Content-Type'] == 'text/plain'
|
||||||
|
)
|
||||||
|
|
||||||
>>> httpbin('/get')
|
|
||||||
'http://httpbin.org/get'
|
|
||||||
|
|
||||||
>>> httpbin('/get', auth='user:password')
|
def add_auth(url, auth):
|
||||||
'http://user:password@httpbin.org/get'
|
proto, rest = url.split('://', 1)
|
||||||
|
return proto + '://' + auth + '@' + rest
|
||||||
"""
|
|
||||||
if auth:
|
|
||||||
proto, rest = base.split('://', 1)
|
|
||||||
base = proto + '://' + auth + '@' + rest
|
|
||||||
return base.rstrip('/') + path
|
|
||||||
|
|
||||||
|
|
||||||
class TestEnvironment(Environment):
|
class TestEnvironment(Environment):
|
||||||
@ -104,7 +101,7 @@ def http(*args, **kwargs):
|
|||||||
|
|
||||||
$ http --auth=user:password GET httpbin.org/basic-auth/user/password
|
$ http --auth=user:password GET httpbin.org/basic-auth/user/password
|
||||||
|
|
||||||
>>> r = http('-a', 'user:pw', httpbin('/basic-auth/user/pw'))
|
>>> r = http('-a', 'user:pw', 'httpbin.org/basic-auth/user/pw')
|
||||||
>>> type(r) == StrCLIResponse
|
>>> type(r) == StrCLIResponse
|
||||||
True
|
True
|
||||||
>>> r.exit_status
|
>>> r.exit_status
|
||||||
|
1
tox.ini
1
tox.ini
@ -13,6 +13,7 @@ envlist = py26, py27, py34, pypy
|
|||||||
deps =
|
deps =
|
||||||
pytest
|
pytest
|
||||||
pytest-xdist
|
pytest-xdist
|
||||||
|
pytest-httpbin
|
||||||
|
|
||||||
commands =
|
commands =
|
||||||
py.test -n 8 --doctest-modules --basetemp={envtmpdir} {posargs:./tests ./httpie}
|
py.test -n 8 --doctest-modules --basetemp={envtmpdir} {posargs:./tests ./httpie}
|
||||||
|
Loading…
Reference in New Issue
Block a user