Repository: httpie/httpie
File: tests/test_json.py (Python)

Code before:
    if sys.version_info >= (3, 8):
        r = http('--pretty', 'format', URL_EXAMPLE)
        assert JSON_WITH_DUPES_FORMATTED_SORTED in r

    # Ensure --unsorted also does a good job.
    r = http('--unsorted', '--pretty', 'format', URL_EXAMPLE)
    assert JSON_WITH_DUPES_FORMATTED_UNSORTED in r


def test_duplicate_keys_support_from_input_file(httpbin):
    """JSON file with duplicate keys should be handled correctly."""
    # JSON keys are sorted by default, but it will work only on Python 3.8+.
    # See `utils.JsonDictPreservingDuplicateKeys` class docstring for details.
    if sys.version_info >= (3, 8):
        r = http('--verbose', httpbin.url + '/post',
                 f'@{JSON_WITH_DUPE_KEYS_FILE_PATH}')
        # FIXME: count should be 2 (1 for the request, 1 for the response)
        #        but httpbin does not support duplicate keys.
        assert r.count(JSON_WITH_DUPES_FORMATTED_SORTED) == 1

    # Ensure --unsorted also does a good job.
    r = http('--verbose', '--unsorted', httpbin.url + '/post',
             f'@{JSON_WITH_DUPE_KEYS_FILE_PATH}')
    # FIXME: count should be 2 (1 for the request, 1 for the response)
    #        but httpbin does not support duplicate keys.
    assert r.count(JSON_WITH_DUPES_FORMATTED_UNSORTED) == 1


Review comment (suggestion):
You can just make an `--oflfine` request if involving httpbin is not required and only adds the need for the explanation.

Code after:
import json

import pytest
import responses

from httpie.cli.constants import PRETTY_MAP
from httpie.compat import is_windows
from httpie.output.formatters.colors import ColorFormatter
from httpie.utils import JsonDictPreservingDuplicateKeys

from .fixtures import JSON_WITH_DUPE_KEYS_FILE_PATH
from .utils import MockEnvironment, http, URL_EXAMPLE

TEST_JSON_XXSI_PREFIXES = (r")]}',\n", ")]}',", 'while(1);', 'for(;;)', ')', ']', '}')
TEST_JSON_VALUES = ({}, {'a': 0, 'b': 0}, [], ['a', 'b'], 'foo', True, False, None)  # FIX: missing int & float
TEST_PREFIX_TOKEN_COLOR = '\x1b[38;5;15m' if is_windows else '\x1b[04m\x1b[91m'

JSON_WITH_DUPES_RAW = '{"key": 15, "key": 15, "key": 3, "key": 7}'
JSON_WITH_DUPES_FORMATTED_SORTED = '''{
    "key": 3,
    "key": 7,
    "key": 15,
    "key": 15
}'''
JSON_WITH_DUPES_FORMATTED_UNSORTED = '''{
    "key": 15,
    "key": 15,
    "key": 3,
    "key": 7
}'''


@pytest.mark.parametrize('data_prefix', TEST_JSON_XXSI_PREFIXES)
@pytest.mark.parametrize('json_data', TEST_JSON_VALUES)
@pytest.mark.parametrize('pretty', PRETTY_MAP.keys())
@responses.activate
def test_json_formatter_with_body_preceded_by_non_json_data(data_prefix, json_data, pretty):
    """Test JSON bodies preceded by non-JSON data."""
    body = data_prefix + json.dumps(json_data)
    content_type = 'application/json'
    responses.add(responses.GET, URL_EXAMPLE, body=body,
                  content_type=content_type)

    colored_output = pretty in ('all', 'colors')
    env = MockEnvironment(colors=256) if colored_output else None
    r = http('--pretty=' + pretty, URL_EXAMPLE, env=env)

    indent = None if pretty in ('none', 'colors') else 4
    expected_body = data_prefix + json.dumps(json_data, indent=indent)
    if colored_output:
        fmt = ColorFormatter(env, format_options={'json': {'format': True, 'indent': 4}})
        expected_body = fmt.format_body(expected_body, content_type)
        # Check to ensure the non-JSON data prefix is colored only one time,
        # meaning it was correctly handled as a whole.
        assert TEST_PREFIX_TOKEN_COLOR + data_prefix in expected_body, expected_body
    assert expected_body in r


@responses.activate
def test_duplicate_keys_support_from_response():
    """JSON with duplicate keys should be handled correctly."""
    responses.add(responses.GET, URL_EXAMPLE, body=JSON_WITH_DUPES_RAW,
                  content_type='application/json')
    args = ('--pretty', 'format', URL_EXAMPLE)

    # Check implicit --sorted
    if JsonDictPreservingDuplicateKeys.SUPPORTS_SORTING:
        r = http(*args)
        assert JSON_WITH_DUPES_FORMATTED_SORTED in r

    # Check --unsorted
    r = http(*args, '--unsorted')
    assert JSON_WITH_DUPES_FORMATTED_UNSORTED in r


def test_duplicate_keys_support_from_input_file():
    """JSON file with duplicate keys should be handled correctly."""
    args = ('--verbose', '--offline', URL_EXAMPLE,
            f'@{JSON_WITH_DUPE_KEYS_FILE_PATH}')

    # Check implicit --sorted
    if JsonDictPreservingDuplicateKeys.SUPPORTS_SORTING:
        r = http(*args)
        assert JSON_WITH_DUPES_FORMATTED_SORTED in r

    # Check --unsorted
    r = http(*args, '--unsorted')
    assert JSON_WITH_DUPES_FORMATTED_UNSORTED in r