You've already forked httpie-cli
mirror of
https://github.com/httpie/cli.git
synced 2025-08-10 22:42:05 +02:00
Remove automatic config file creation to avoid concurrency issues.
Close #788 Close #812
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
from httpie import __version__
|
||||
from utils import MockEnvironment, http, HTTP_OK
|
||||
from httpie.context import Environment
|
||||
from httpie.config import Config
|
||||
from utils import HTTP_OK, MockEnvironment, http
|
||||
|
||||
|
||||
def test_default_options(httpbin):
|
||||
@@ -8,15 +7,33 @@ def test_default_options(httpbin):
|
||||
env.config['default_options'] = ['--form']
|
||||
env.config.save()
|
||||
r = http(httpbin.url + '/post', 'foo=bar', env=env)
|
||||
assert r.json['form'] == {"foo": "bar"}
|
||||
assert r.json['form'] == {
|
||||
"foo": "bar"
|
||||
}
|
||||
|
||||
|
||||
def test_config_dir_not_writeable(httpbin):
|
||||
r = http(httpbin + '/get', env=MockEnvironment(
|
||||
config_dir='/',
|
||||
create_temp_config_dir=False,
|
||||
))
|
||||
def test_config_file_not_valid(httpbin):
|
||||
env = MockEnvironment()
|
||||
env.create_temp_config_dir()
|
||||
with (env.config_dir / Config.FILENAME).open('w') as f:
|
||||
f.write('{invalid json}')
|
||||
r = http(httpbin + '/get', env=env)
|
||||
assert HTTP_OK in r
|
||||
assert 'http: warning' in r.stderr
|
||||
assert 'invalid config file' in r.stderr
|
||||
|
||||
|
||||
def test_config_file_not_inaccessible(httpbin):
|
||||
env = MockEnvironment()
|
||||
env.create_temp_config_dir()
|
||||
config_path = env.config_dir / Config.FILENAME
|
||||
assert not config_path.exists()
|
||||
config_path.touch(0o000)
|
||||
assert config_path.exists()
|
||||
r = http(httpbin + '/get', env=env)
|
||||
assert HTTP_OK in r
|
||||
assert 'http: warning' in r.stderr
|
||||
assert 'cannot read config file' in r.stderr
|
||||
|
||||
|
||||
def test_default_options_overwrite(httpbin):
|
||||
@@ -24,9 +41,6 @@ def test_default_options_overwrite(httpbin):
|
||||
env.config['default_options'] = ['--form']
|
||||
env.config.save()
|
||||
r = http('--json', httpbin.url + '/post', 'foo=bar', env=env)
|
||||
assert r.json['json'] == {"foo": "bar"}
|
||||
|
||||
|
||||
def test_current_version():
|
||||
version = MockEnvironment().config['__meta__']['httpie']
|
||||
assert version == __version__
|
||||
assert r.json['json'] == {
|
||||
"foo": "bar"
|
||||
}
|
||||
|
@@ -4,37 +4,30 @@ from requests import Request
|
||||
from requests.exceptions import ConnectionError
|
||||
|
||||
from httpie.status import ExitStatus
|
||||
from httpie.core import main
|
||||
from utils import HTTP_OK, http
|
||||
|
||||
|
||||
error_msg = None
|
||||
@mock.patch('httpie.core.program')
|
||||
def test_error(program):
|
||||
exc = ConnectionError('Connection aborted')
|
||||
exc.request = Request(method='GET', url='http://www.google.com')
|
||||
program.side_effect = exc
|
||||
r = http('www.google.com', tolerate_error_exit_status=True)
|
||||
assert r.exit_status == ExitStatus.ERROR
|
||||
assert (
|
||||
'ConnectionError: '
|
||||
'Connection aborted while doing a GET request to URL: '
|
||||
'http://www.google.com'
|
||||
) in r.stderr
|
||||
|
||||
|
||||
@mock.patch('httpie.core.program')
|
||||
def test_error(get_response):
|
||||
def error(msg, *args, **kwargs):
|
||||
global error_msg
|
||||
error_msg = msg % args
|
||||
|
||||
def test_error_traceback(program):
|
||||
exc = ConnectionError('Connection aborted')
|
||||
exc.request = Request(method='GET', url='http://www.google.com')
|
||||
get_response.side_effect = exc
|
||||
ret = main(['http', '--ignore-stdin', 'www.google.com'], custom_log_error=error)
|
||||
assert ret == ExitStatus.ERROR
|
||||
assert error_msg == (
|
||||
'ConnectionError: '
|
||||
'Connection aborted while doing a GET request to URL: '
|
||||
'http://www.google.com')
|
||||
|
||||
|
||||
@mock.patch('httpie.core.program')
|
||||
def test_error_traceback(get_response):
|
||||
exc = ConnectionError('Connection aborted')
|
||||
exc.request = Request(method='GET', url='http://www.google.com')
|
||||
get_response.side_effect = exc
|
||||
program.side_effect = exc
|
||||
with raises(ConnectionError):
|
||||
main(['http', '--ignore-stdin', '--traceback', 'www.google.com'])
|
||||
http('--traceback', 'www.google.com')
|
||||
|
||||
|
||||
def test_max_headers_limit(httpbin_both):
|
||||
|
@@ -6,7 +6,7 @@ import time
|
||||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
from typing import Optional, Union
|
||||
|
||||
from httpie.status import ExitStatus
|
||||
from httpie.config import Config
|
||||
@@ -18,6 +18,7 @@ TESTS_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
CRLF = '\r\n'
|
||||
COLOR = '\x1b['
|
||||
HTTP_OK = '200 OK'
|
||||
# noinspection GrazieInspection
|
||||
HTTP_OK_COLOR = (
|
||||
'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'
|
||||
@@ -62,10 +63,13 @@ class MockEnvironment(Environment):
|
||||
def config(self) -> Config:
|
||||
if (self._create_temp_config_dir
|
||||
and self._temp_dir not in self.config_dir.parents):
|
||||
self.config_dir = mk_config_dir()
|
||||
self._delete_config_dir = True
|
||||
self.create_temp_config_dir()
|
||||
return super().config
|
||||
|
||||
def create_temp_config_dir(self):
|
||||
self.config_dir = mk_config_dir()
|
||||
self._delete_config_dir = True
|
||||
|
||||
def cleanup(self):
|
||||
self.stdout.close()
|
||||
self.stderr.close()
|
||||
@@ -75,6 +79,7 @@ class MockEnvironment(Environment):
|
||||
rmtree(self.config_dir)
|
||||
|
||||
def __del__(self):
|
||||
# noinspection PyBroadException
|
||||
try:
|
||||
self.cleanup()
|
||||
except Exception:
|
||||
@@ -83,7 +88,7 @@ class MockEnvironment(Environment):
|
||||
|
||||
class BaseCLIResponse:
|
||||
"""
|
||||
Represents the result of simulated `$ http' invocation via `http()`.
|
||||
Represents the result of simulated `$ http' invocation via `http()`.
|
||||
|
||||
Holds and provides access to:
|
||||
|
||||
@@ -113,8 +118,8 @@ class StrCLIResponse(str, BaseCLIResponse):
|
||||
@property
|
||||
def json(self) -> Optional[dict]:
|
||||
"""
|
||||
Return deserialized JSON body, if one included in the output
|
||||
and is parsable.
|
||||
Return deserialized the request or response JSON body,
|
||||
if one (and only one) included in the output and is parsable.
|
||||
|
||||
"""
|
||||
if not hasattr(self, '_json'):
|
||||
@@ -147,7 +152,12 @@ class ExitStatusError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def http(*args, program_name='http', **kwargs):
|
||||
def http(
|
||||
*args,
|
||||
program_name='http',
|
||||
tolerate_error_exit_status=False,
|
||||
**kwargs,
|
||||
) -> Union[StrCLIResponse, BytesCLIResponse]:
|
||||
# noinspection PyUnresolvedReferences
|
||||
"""
|
||||
Run HTTPie and capture stderr/out and exit status.
|
||||
@@ -188,7 +198,6 @@ def http(*args, program_name='http', **kwargs):
|
||||
True
|
||||
|
||||
"""
|
||||
tolerate_error_exit_status = kwargs.pop('tolerate_error_exit_status', False)
|
||||
env = kwargs.get('env')
|
||||
if not env:
|
||||
env = kwargs['env'] = MockEnvironment()
|
||||
@@ -200,7 +209,8 @@ def http(*args, program_name='http', **kwargs):
|
||||
args_with_config_defaults = args + env.config.default_options
|
||||
add_to_args = []
|
||||
if '--debug' not in args_with_config_defaults:
|
||||
if not tolerate_error_exit_status and '--traceback' not in args_with_config_defaults:
|
||||
if (not tolerate_error_exit_status
|
||||
and '--traceback' not in args_with_config_defaults):
|
||||
add_to_args.append('--traceback')
|
||||
if not any('--timeout' in arg for arg in args_with_config_defaults):
|
||||
add_to_args.append('--timeout=3')
|
||||
@@ -228,7 +238,8 @@ def http(*args, program_name='http', **kwargs):
|
||||
sys.stderr.write(stderr.read())
|
||||
raise
|
||||
else:
|
||||
if not tolerate_error_exit_status and exit_status != ExitStatus.SUCCESS:
|
||||
if (not tolerate_error_exit_status
|
||||
and exit_status != ExitStatus.SUCCESS):
|
||||
dump_stderr()
|
||||
raise ExitStatusError(
|
||||
'httpie.core.main() unexpectedly returned'
|
||||
|
Reference in New Issue
Block a user