1from unittest import mock
2
3from httpie.status import ExitStatus
4from .utils import MockEnvironment, http, HTTP_OK
5
6
7def test_keyboard_interrupt_during_arg_parsing_exit_status(httpbin):
8    with mock.patch('httpie.cli.definition.parser.parse_args',
9                    side_effect=KeyboardInterrupt()):
10        r = http('GET', httpbin.url + '/get', tolerate_error_exit_status=True)
11        assert r.exit_status == ExitStatus.ERROR_CTRL_C
12
13
14def test_keyboard_interrupt_in_program_exit_status(httpbin):
15    with mock.patch('httpie.core.program',
16                    side_effect=KeyboardInterrupt()):
17        r = http('GET', httpbin.url + '/get', tolerate_error_exit_status=True)
18        assert r.exit_status == ExitStatus.ERROR_CTRL_C
19
20
21def test_ok_response_exits_0(httpbin):
22    r = http('GET', httpbin.url + '/get')
23    assert HTTP_OK in r
24    assert r.exit_status == ExitStatus.SUCCESS
25
26
27def test_error_response_exits_0_without_check_status(httpbin):
28    r = http('GET', httpbin.url + '/status/500')
29    assert '500 INTERNAL SERVER ERROR' in r
30    assert r.exit_status == ExitStatus.SUCCESS
31    assert not r.stderr
32
33
34def test_timeout_exit_status(httpbin):
35
36    r = http('--timeout=0.01', 'GET', httpbin.url + '/delay/0.5',
37             tolerate_error_exit_status=True)
38    assert r.exit_status == ExitStatus.ERROR_TIMEOUT
39
40
41def test_3xx_check_status_exits_3_and_stderr_when_stdout_redirected(
42        httpbin):
43    env = MockEnvironment(stdout_isatty=False)
44    r = http('--check-status', '--headers',
45             'GET', httpbin.url + '/status/301',
46             env=env, tolerate_error_exit_status=True)
47    assert '301 MOVED PERMANENTLY' in r
48    assert r.exit_status == ExitStatus.ERROR_HTTP_3XX
49    assert '301 moved permanently' in r.stderr.lower()
50
51
52def test_3xx_check_status_redirects_allowed_exits_0(httpbin):
53    r = http('--check-status', '--follow',
54             'GET', httpbin.url + '/status/301',
55             tolerate_error_exit_status=True)
56    # The redirect will be followed so 200 is expected.
57    assert HTTP_OK in r
58    assert r.exit_status == ExitStatus.SUCCESS
59
60
61def test_4xx_check_status_exits_4(httpbin):
62    r = http('--check-status', 'GET', httpbin.url + '/status/401',
63             tolerate_error_exit_status=True)
64    assert '401 UNAUTHORIZED' in r
65    assert r.exit_status == ExitStatus.ERROR_HTTP_4XX
66    # Also stderr should be empty since stdout isn't redirected.
67    assert not r.stderr
68
69
70def test_5xx_check_status_exits_5(httpbin):
71    r = http('--check-status', 'GET', httpbin.url + '/status/500',
72             tolerate_error_exit_status=True)
73    assert '500 INTERNAL SERVER ERROR' in r
74    assert r.exit_status == ExitStatus.ERROR_HTTP_5XX
75