Testing HTTP Method Defaults and Header Management in HTTPie CLI
This test suite validates HTTP method defaults and header handling in HTTPie CLI, focusing on content type negotiation and automatic header assignment. It ensures proper behavior for different request types and data formats.
Test Coverage Overview
Implementation Analysis
Technical Details
Best Practices Demonstrated
httpie/cli
tests/test_defaults.py
"""
Tests for the provided defaults regarding HTTP method, and --json vs. --form.
"""
from io import BytesIO
from httpie.client import JSON_ACCEPT
from .utils import MockEnvironment, http, HTTP_OK
from .fixtures import FILE_PATH
def test_default_headers_case_insensitive(httpbin):
"""
<https://github.com/httpie/cli/issues/644>
"""
r = http(
'--debug',
'--print=H',
httpbin + '/post',
'CONTENT-TYPE:application/json-patch+json',
'a=b',
)
assert 'CONTENT-TYPE: application/json-patch+json' in r
assert 'Content-Type' not in r
# noinspection PyPep8Naming
class TestImplicitHTTPMethod:
def test_implicit_GET(self, httpbin):
r = http(httpbin + '/get')
assert HTTP_OK in r
def test_implicit_GET_with_headers(self, httpbin):
r = http(httpbin + '/headers', 'Foo:bar')
assert HTTP_OK in r
assert r.json['headers']['Foo'] == 'bar'
def test_implicit_POST_json(self, httpbin):
r = http(httpbin + '/post', 'hello=world')
assert HTTP_OK in r
assert r.json['json'] == {'hello': 'world'}
def test_implicit_POST_form(self, httpbin):
r = http('--form', httpbin + '/post', 'foo=bar')
assert HTTP_OK in r
assert r.json['form'] == {'foo': 'bar'}
def test_implicit_POST_raw(self, httpbin):
r = http('--raw', 'foo bar', httpbin + '/post')
assert HTTP_OK in r
assert r.json['data'] == 'foo bar'
def test_implicit_POST_stdin(self, httpbin):
env = MockEnvironment(
stdin_isatty=False,
stdin=BytesIO(FILE_PATH.read_bytes())
)
r = http('--form', httpbin + '/post', env=env)
assert HTTP_OK in r
class TestAutoContentTypeAndAcceptHeaders:
"""
Test that `Accept` and `Content-Type` correctly default to JSON,
but can still be overridden. The same with Content-Type when `--form`
`-f` is used.
"""
def test_GET_no_data_no_auto_headers(self, httpbin):
# https://github.com/httpie/cli/issues/62
r = http('GET', httpbin + '/headers')
assert HTTP_OK in r
assert r.json['headers']['Accept'] == '*/*'
assert 'Content-Type' not in r.json['headers']
def test_POST_no_data_no_auto_headers(self, httpbin):
# JSON headers shouldn't be automatically set for POST with no data.
r = http('POST', httpbin + '/post')
assert HTTP_OK in r
assert '"Accept": "*/*"' in r
assert '"Content-Type": "application/json' not in r
def test_POST_with_data_auto_JSON_headers(self, httpbin):
r = http('POST', httpbin + '/post', 'a=b')
assert HTTP_OK in r
assert r.json['headers']['Accept'] == JSON_ACCEPT
assert r.json['headers']['Content-Type'] == 'application/json'
def test_GET_with_data_auto_JSON_headers(self, httpbin):
# JSON headers should automatically be set also for GET with data.
r = http('POST', httpbin + '/post', 'a=b')
assert HTTP_OK in r
assert r.json['headers']['Accept'] == JSON_ACCEPT
assert r.json['headers']['Content-Type'] == 'application/json'
def test_POST_explicit_JSON_JSON_ACCEPT(self, httpbin):
r = http('--json', 'POST', httpbin + '/post')
assert HTTP_OK in r
assert r.json['headers']['Accept'] == JSON_ACCEPT
# Make sure Content-Type gets set even with no data.
# https://github.com/httpie/cli/issues/137
assert 'application/json' in r.json['headers']['Content-Type']
def test_GET_explicit_JSON_explicit_headers(self, httpbin):
r = http('--json', 'GET', httpbin + '/headers',
'Accept:application/xml',
'Content-Type:application/xml')
assert HTTP_OK in r
assert '"Accept": "application/xml"' in r
assert '"Content-Type": "application/xml"' in r
def test_POST_form_auto_Content_Type(self, httpbin):
r = http('--form', 'POST', httpbin + '/post')
assert HTTP_OK in r
assert '"Content-Type": "application/x-www-form-urlencoded' in r
def test_POST_form_Content_Type_override(self, httpbin):
r = http('--form', 'POST', httpbin + '/post',
'Content-Type:application/xml')
assert HTTP_OK in r
assert '"Content-Type": "application/xml"' in r
def test_print_only_body_when_stdout_redirected_by_default(self, httpbin):
env = MockEnvironment(stdin_isatty=True, stdout_isatty=False)
r = http('GET', httpbin + '/get', env=env)
assert 'HTTP/' not in r
def test_print_overridable_when_stdout_redirected(self, httpbin):
env = MockEnvironment(stdin_isatty=True, stdout_isatty=False)
r = http('--print=h', 'GET', httpbin + '/get', env=env)
assert HTTP_OK in r