Ticket #10115: 10115. test_mimetypes.diff

File 10115. test_mimetypes.diff, 9.6 KB (added by Julien Phalip, 15 years ago)

Patch contains test and doc

  • django/django/test/client.py

     
    22from urlparse import urlparse, urlunparse
    33import sys
    44import os
     5import mimetypes
    56try:
    67    from cStringIO import StringIO
    78except ImportError:
     
    8384    store.setdefault('template',[]).append(template)
    8485    store.setdefault('context',[]).append(context)
    8586
    86 def encode_multipart(boundary, data):
     87def encode_multipart(boundary, data, guess_mimetypes):
    8788    """
    8889    Encodes multipart POST data from a dictionary of form values.
    8990
     
    8889    Encodes multipart POST data from a dictionary of form values.
    8990
    9091    The key will be used as the form data name; the value will be transmitted
    91     as content. If the value is a file, the contents of the file will be sent
    92     as an application/octet-stream; otherwise, str(value) will be sent.
     92    as content. If the value is a file, its mimetype will be guessed if
     93    guess_mimetypes is True or will be set to application/octet-stream by
     94    default; otherwise, str(value) will be sent.
    9395    """
    9496    lines = []
    9597    to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
     
    102104    # names can be duplicated!
    103105    for (key, value) in data.items():
    104106        if is_file(value):
    105             lines.extend(encode_file(boundary, key, value))
     107            lines.extend(encode_file(boundary, key, value, guess_mimetypes))
    106108        elif not isinstance(value, basestring) and is_iterable(value):
    107109            for item in value:
    108110                if is_file(item):
    109                     lines.extend(encode_file(boundary, key, item))
     111                    lines.extend(encode_file(boundary, key, item, guess_mimetypes))
    110112                else:
    111113                    lines.extend([
    112114                        '--' + boundary,
     
    128130    ])
    129131    return '\r\n'.join(lines)
    130132
    131 def encode_file(boundary, key, file):
     133def encode_file(boundary, key, file, guess_mimetype):
    132134    to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
     135    filename = os.path.basename(file.name)
     136    if guess_mimetype:
     137        mimetype, encoding = mimetypes.guess_type(filename)
     138        if mimetype is None:
     139            mimetype = 'application/octet-stream'
     140    else:
     141        mimetype = 'application/octet-stream'
    133142    return [
    134143        '--' + boundary,
    135144        'Content-Disposition: form-data; name="%s"; filename="%s"' \
    136             % (to_str(key), to_str(os.path.basename(file.name))),
    137         'Content-Type: application/octet-stream',
     145            % (to_str(key), to_str(filename)),
     146        'Content-Type: %s' % mimetype,
    138147        '',
    139148        file.read()
    140149    ]
     
    276285
    277286        return self.request(**r)
    278287
    279     def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
     288    def post(self, path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False, **extra):
    280289        """
    281290        Requests a response from the server using POST.
    282291        """
     
    281290        Requests a response from the server using POST.
    282291        """
    283292        if content_type is MULTIPART_CONTENT:
    284             post_data = encode_multipart(BOUNDARY, data)
     293            post_data = encode_multipart(BOUNDARY, data, guess_mimetypes)
    285294        else:
    286295            post_data = data
    287296
     
    329338
    330339        return self.request(**r)
    331340
    332     def put(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
     341    def put(self, path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False, **extra):
    333342        """
    334343        Send a resource to the server using PUT.
    335344        """
     
    334343        Send a resource to the server using PUT.
    335344        """
    336345        if content_type is MULTIPART_CONTENT:
    337             post_data = encode_multipart(BOUNDARY, data)
     346            post_data = encode_multipart(BOUNDARY, data, guess_mimetypes)
    338347        else:
    339348            post_data = data
    340349
  • django/docs/topics/testing.txt

     
    505505        If you provide URL both an encoded GET data and a data argument,
    506506        the data argument will take precedence.
    507507
    508     .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT)
     508    .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False)
    509509
    510510        Makes a POST request on the provided ``path`` and returns a
    511511        ``Response`` object, which is documented below.
     
    553553        (The name ``attachment`` here is not relevant; use whatever name your
    554554        file-processing code expects.)
    555555
    556         Note that you should manually close the file after it has been provided
     556                Note that by default all files will be sent as application/octet-stream.
     557                If you want to let python guess the files' MIME types, simply set
     558                the ``guess_mimetypes`` parameter as True.
     559
     560        Also note that you should manually close the file after it has been provided
    557561        to ``post()``.
    558562
    559563        .. versionadded:: development
     
    583587        Makes an OPTIONS request on the provided ``path`` and returns a
    584588        ``Response`` object. Useful for testing RESTful interfaces.
    585589
    586     .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT)
     590    .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT, guess_mimetypes=False)
    587591
    588592        .. versionadded:: development
    589593
  • django/tests/regressiontests/test_client_regress/files/test2.txt

    Cannot display: file marked as a binary type.
    svn:mime-type = application/octet-stream
    
    Property changes on: E:\Software\workspace\django\tests\regressiontests\test_client_regress\files\test1.png
    ___________________________________________________________________
    Name: svn:mime-type
       + application/octet-stream
    
     
     1This is a text, doh.
     2 No newline at end of file
  • django/tests/regressiontests/test_client_regress/models.py

     
    472472        self.assertEqual(response.context['post-bar'], 'bang')
    473473        self.assertEqual(response.context['request-foo'], 'whiz')
    474474        self.assertEqual(response.context['request-bar'], 'bang')
     475
     476class MimetypesTests(TestCase):
     477    urls = 'regressiontests.test_client_regress.urls'
     478
     479    def test_mimetypes(self):
     480        f1 = open(os.path.join(os.path.dirname(__file__), 'files/test1.png'), 'rb')
     481        f2 = open(os.path.join(os.path.dirname(__file__), 'files/test2.txt'), 'rb')
     482        post_data = {
     483            'file_field1': f1,
     484            'file_field2': f2,
     485        }       
     486        # Guessed mimetypes
     487        response = self.client.post('/mimetypes/', post_data, guess_mimetypes=True)
     488        self.assertContains(response, 'test1.png:image/png', 1, 200)
     489        self.assertContains(response, 'test2.txt:text/plain', 1, 200)
     490       
     491        # Default mimetypes
     492        response = self.client.post('/mimetypes/', post_data, guess_mimetypes=False)
     493        self.assertContains(response, 'test1.png:application/octet-stream', 1, 200)
     494        self.assertContains(response, 'test2.txt:application/octet-stream', 1, 200)
     495       
     496        # Without 'guess_mimetypes' (default mimetypes)
     497        response = self.client.post('/mimetypes/', post_data)
     498        self.assertContains(response, 'test1.png:application/octet-stream', 1, 200)
     499        self.assertContains(response, 'test2.txt:application/octet-stream', 1, 200)
     500       
     501        f1.close()
     502        f2.close()
     503 No newline at end of file
  • django/tests/regressiontests/test_client_regress/urls.py

     
    1111    (r'^set_session/$', views.set_session_view),
    1212    (r'^check_session/$', views.check_session_view),
    1313    (r'^request_methods/$', views.request_methods_view),
     14    (r'^mimetypes/$', views.mimetypes_view),
    1415)
  • django/tests/regressiontests/test_client_regress/views.py

     
    5858
    5959def request_methods_view(request):
    6060    "A view that responds with the request method"
    61     return HttpResponse('request method: %s' % request.method)
    62  No newline at end of file
     61    return HttpResponse('request method: %s' % request.method)
     62
     63def mimetypes_view(request):
     64    "A view that checks uploaded files' mimtypes"
     65    content = ','.join(['%s:%s' % (v.name, v.content_type) for k, v in request.FILES.items()])
     66    return HttpResponse(str(content))
     67 No newline at end of file
Back to Top