<commit_before>"""Test multipart MIME helpers."""

__all__ = []

from io import BytesIO
from os import urandom

from alburnum.maas.testing import (
    make_string,
    TestCase,
)
from django.conf import settings
from django.core.files.uploadhandler import MemoryFileUploadHandler
from django.http.multipartparser import MultiPartParser
from django.utils.datastructures import MultiValueDict
from testtools.matchers import (
    EndsWith,
    StartsWith,
)

from ..multipart import (
    encode_multipart_data,
    get_content_type,
)

# Django, sigh, needs this.
settings.configure()


ahem_django_ahem = (
    "If the mismatch appears to be because the parsed values "
    "are base64 encoded, then check you're using a >=1.4 release "
    "of Django.")


def parse_headers_and_body_with_django(headers, body):
    """Parse `headers` and `body` with Django's :class:`MultiPartParser`.

    `MultiPartParser` is a curiously ugly and RFC non-compliant concoction.

    Amongst other things, it coerces all field names, field data, and
    filenames into Unicode strings using the "replace" error strategy, so be
    warned that your data may be silently mangled.

    It also, in 1.3.1 at least, does not recognise any transfer encodings at
    *all* because its header parsing code was broken.

    I'm also fairly sure that it'll fall over on headers than span more than
    one line.

    In short, it's a piece of code that inspires little confidence, yet we
    must work with it, hence we need to round-trip test multipart handling
    with it.
    """
    handler = MemoryFileUploadHandler()
    meta = {
        "HTTP_CONTENT_TYPE": headers["Content-Type"],
        "HTTP_CONTENT_LENGTH": headers["Content-Length"],
        }
    parser = MultiPartParser(
        META=meta, input_data=BytesIO(body),
        upload_handlers=[handler])
    return parser.parse()


class TestMultiPart(TestCase):

    def test_get_content_type_guesses_type(self):
        guess = get_content_type('text.txt')
        self.assertEqual('text/plain', guess)
        self.assertIsInstance(guess, str)

    def test_encode_multipart_data_produces_bytes(self):
        data = {make_string(): make_string().encode('ascii')}
        files = {make_string(): BytesIO(make_string().encode('ascii'))}
        body, headers = encode_multipart_data(data, files)
        self.assertIsInstance(body, bytes)<commit_msg>Work with newer versions of Django's MultiPartParser.<commit_after>"""Test multipart MIME helpers."""

__all__ = []

from io import BytesIO
from os import urandom

from alburnum.maas.testing import (
    make_string,
    TestCase,
)
from django.conf import settings
from django.core.files.uploadhandler import MemoryFileUploadHandler
from django.http.multipartparser import MultiPartParser
from django.utils.datastructures import MultiValueDict
from testtools.matchers import (
    EndsWith,
    StartsWith,
)

from ..multipart import (
    encode_multipart_data,
    get_content_type,
)

# Django, sigh, needs this.
settings.configure()


ahem_django_ahem = (
    "If the mismatch appears to be because the parsed values "
    "are base64 encoded, then check you're using a >=1.4 release "
    "of Django.")


def parse_headers_and_body_with_django(headers, body):
    """Parse `headers` and `body` with Django's :class:`MultiPartParser`.

    `MultiPartParser` is a curiously ugly and RFC non-compliant concoction.

    Amongst other things, it coerces all field names, field data, and
    filenames into Unicode strings using the "replace" error strategy, so be
    warned that your data may be silently mangled.

    It also, in 1.3.1 at least, does not recognise any transfer encodings at
    *all* because its header parsing code was broken.

    I'm also fairly sure that it'll fall over on headers than span more than
    one line.

    In short, it's a piece of code that inspires little confidence, yet we
    must work with it, hence we need to round-trip test multipart handling
    with it.
    """
    handler = MemoryFileUploadHandler()
    meta = {
        "CONTENT_TYPE": headers["Content-Type"],
        "CONTENT_LENGTH": headers["Content-Length"],
    }
    parser = MultiPartParser(
        META=meta, input_data=BytesIO(body),
        upload_handlers=[handler])
    return parser.parse()


class TestMultiPart(TestCase):

    def test_get_content_type_guesses_type(self):
        guess = get_content_type('text.txt')
        self.assertEqual('text/plain', guess)
        self.assertIsInstance(guess, str)

    def test_encode_multipart_data_produces_bytes(self):
        data = {make_string(): make_string().encode('ascii')}
        files = {make_string(): BytesIO(make_string().encode('ascii'))}
        body, headers = encode_multipart_data(data, files)
        self.assertIsInstance(body, bytes)
{'fraction_non_alphanumeric': 0.08728179551122195, 'fraction_numerical': 0.0029093931837073984, 'mean_word_length': 3.7093933463796476, 'pattern_counts': {'":': 4, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4615775', 'n_tokens_mistral': 1440, 'n_tokens_neox': 1378, 'n_words': 451}