forked from extern/httpie-cli
Fix --offline --multipart
, add more tests
This commit is contained in:
parent
75f1e02215
commit
32d8b481e9
@ -283,7 +283,8 @@ def make_request_kwargs(
|
||||
body=data,
|
||||
body_read_callback=request_body_read_callback,
|
||||
chunked=args.chunked,
|
||||
content_length_header_value=headers.get('Content-Length')
|
||||
offline=args.offline,
|
||||
content_length_header_value=headers.get('Content-Length'),
|
||||
),
|
||||
'auth': args.auth,
|
||||
'params': args.params.items(),
|
||||
|
@ -201,7 +201,7 @@ def program(
|
||||
if is_request:
|
||||
if not initial_request:
|
||||
initial_request = message
|
||||
is_streamed_upload = not args.offline and not isinstance(
|
||||
is_streamed_upload = not isinstance(
|
||||
message.body, (str, bytes))
|
||||
if with_body:
|
||||
with_body = not is_streamed_upload
|
||||
|
@ -39,11 +39,20 @@ def prepare_request_body(
|
||||
body_read_callback: Callable[[bytes], bytes],
|
||||
content_length_header_value: int = None,
|
||||
chunked=False,
|
||||
offline=False,
|
||||
) -> Union[str, bytes, IO, MultipartEncoder, ChunkedUploadStream]:
|
||||
|
||||
is_file_like = hasattr(body, 'read')
|
||||
|
||||
if isinstance(body, RequestDataDict):
|
||||
body = urlencode(body, doseq=True)
|
||||
|
||||
if not hasattr(body, 'read'):
|
||||
if offline:
|
||||
if is_file_like:
|
||||
return body.read()
|
||||
return body
|
||||
|
||||
if not is_file_like:
|
||||
if chunked:
|
||||
body = ChunkedUploadStream(
|
||||
# Pass the entire body as one chunk.
|
||||
|
@ -10,7 +10,7 @@ from httpie.context import Environment
|
||||
from httpie.status import ExitStatus
|
||||
from httpie.cli.exceptions import ParseError
|
||||
from utils import MockEnvironment, StdinBytesIO, http, HTTP_OK
|
||||
from fixtures import FILE_PATH, FILE_CONTENT
|
||||
from fixtures import FILE_PATH, FILE_CONTENT, FILE_PATH_ARG
|
||||
|
||||
import httpie
|
||||
|
||||
@ -193,6 +193,48 @@ def test_offline():
|
||||
assert 'GET /foo' in r
|
||||
|
||||
|
||||
def test_offline_form():
|
||||
r = http(
|
||||
'--offline',
|
||||
'--form',
|
||||
'https://this-should.never-resolve/foo',
|
||||
'foo=bar'
|
||||
)
|
||||
assert 'POST /foo' in r
|
||||
assert 'foo=bar' in r
|
||||
|
||||
|
||||
def test_offline_json():
|
||||
r = http(
|
||||
'--offline',
|
||||
'https://this-should.never-resolve/foo',
|
||||
'foo=bar'
|
||||
)
|
||||
assert 'POST /foo' in r
|
||||
assert r.json == {'foo': 'bar'}
|
||||
|
||||
|
||||
def test_offline_multipart():
|
||||
r = http(
|
||||
'--offline',
|
||||
'--multipart',
|
||||
'https://this-should.never-resolve/foo',
|
||||
'foo=bar'
|
||||
)
|
||||
assert 'POST /foo' in r
|
||||
assert 'name="foo"' in r
|
||||
|
||||
|
||||
def test_offline_from_file():
|
||||
r = http(
|
||||
'--offline',
|
||||
'https://this-should.never-resolve/foo',
|
||||
f'@{FILE_PATH_ARG}'
|
||||
)
|
||||
assert 'POST /foo' in r
|
||||
assert FILE_CONTENT in r
|
||||
|
||||
|
||||
def test_offline_download():
|
||||
"""Absence of response should be handled gracefully with --download"""
|
||||
r = http(
|
||||
|
@ -170,7 +170,6 @@ class TestMultipartFormDataFileUpload:
|
||||
'--verbose',
|
||||
'--multipart',
|
||||
'--chunked',
|
||||
# '--offline',
|
||||
HTTPBIN_WITH_CHUNKED_SUPPORT + '/post',
|
||||
'AAA=AAA',
|
||||
)
|
||||
@ -179,6 +178,25 @@ class TestMultipartFormDataFileUpload:
|
||||
assert 'name="AAA"' in r # in request
|
||||
assert '"AAA": "AAA"', r # in response
|
||||
|
||||
def test_multipart_preserve_order(self, httpbin):
|
||||
r = http(
|
||||
'--form',
|
||||
'--offline',
|
||||
httpbin + '/post',
|
||||
'text_field=foo',
|
||||
f'file_field@{FILE_PATH_ARG}',
|
||||
)
|
||||
assert r.index('text_field') < r.index('file_field')
|
||||
|
||||
r = http(
|
||||
'--form',
|
||||
'--offline',
|
||||
httpbin + '/post',
|
||||
f'file_field@{FILE_PATH_ARG}',
|
||||
'text_field=foo',
|
||||
)
|
||||
assert r.index('text_field') > r.index('file_field')
|
||||
|
||||
|
||||
class TestRequestBodyFromFilePath:
|
||||
"""
|
||||
|
@ -144,10 +144,9 @@ class StrCLIResponse(str, BaseCLIResponse):
|
||||
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 whole JSON HTTP message,
|
||||
# try to extract its body.
|
||||
elif self.count('Content-Type:') == 1:
|
||||
# Looks like a HTTP message,
|
||||
# try to extract JSON from its body.
|
||||
try:
|
||||
j = self.strip()[self.strip().rindex('\r\n\r\n'):]
|
||||
except ValueError:
|
||||
|
Loading…
Reference in New Issue
Block a user