1. import os
    
  2. import unittest
    
  3. 
    
  4. from django.core.exceptions import ValidationError
    
  5. from django.core.files.uploadedfile import SimpleUploadedFile, TemporaryUploadedFile
    
  6. from django.forms import ClearableFileInput, FileInput, ImageField, Widget
    
  7. from django.test import SimpleTestCase
    
  8. 
    
  9. from . import FormFieldAssertionsMixin
    
  10. 
    
  11. try:
    
  12.     from PIL import Image
    
  13. except ImportError:
    
  14.     Image = None
    
  15. 
    
  16. 
    
  17. def get_img_path(path):
    
  18.     return os.path.join(
    
  19.         os.path.abspath(os.path.join(__file__, "..", "..")), "tests", path
    
  20.     )
    
  21. 
    
  22. 
    
  23. @unittest.skipUnless(Image, "Pillow is required to test ImageField")
    
  24. class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
    
  25.     def test_imagefield_annotate_with_image_after_clean(self):
    
  26.         f = ImageField()
    
  27. 
    
  28.         img_path = get_img_path("filepath_test_files/1x1.png")
    
  29.         with open(img_path, "rb") as img_file:
    
  30.             img_data = img_file.read()
    
  31. 
    
  32.         img_file = SimpleUploadedFile("1x1.png", img_data)
    
  33.         img_file.content_type = "text/plain"
    
  34. 
    
  35.         uploaded_file = f.clean(img_file)
    
  36. 
    
  37.         self.assertEqual("PNG", uploaded_file.image.format)
    
  38.         self.assertEqual("image/png", uploaded_file.content_type)
    
  39. 
    
  40.     def test_imagefield_annotate_with_bitmap_image_after_clean(self):
    
  41.         """
    
  42.         This also tests the situation when Pillow doesn't detect the MIME type
    
  43.         of the image (#24948).
    
  44.         """
    
  45.         from PIL.BmpImagePlugin import BmpImageFile
    
  46. 
    
  47.         try:
    
  48.             Image.register_mime(BmpImageFile.format, None)
    
  49.             f = ImageField()
    
  50.             img_path = get_img_path("filepath_test_files/1x1.bmp")
    
  51.             with open(img_path, "rb") as img_file:
    
  52.                 img_data = img_file.read()
    
  53. 
    
  54.             img_file = SimpleUploadedFile("1x1.bmp", img_data)
    
  55.             img_file.content_type = "text/plain"
    
  56. 
    
  57.             uploaded_file = f.clean(img_file)
    
  58. 
    
  59.             self.assertEqual("BMP", uploaded_file.image.format)
    
  60.             self.assertIsNone(uploaded_file.content_type)
    
  61.         finally:
    
  62.             Image.register_mime(BmpImageFile.format, "image/bmp")
    
  63. 
    
  64.     def test_file_extension_validation(self):
    
  65.         f = ImageField()
    
  66.         img_path = get_img_path("filepath_test_files/1x1.png")
    
  67.         with open(img_path, "rb") as img_file:
    
  68.             img_data = img_file.read()
    
  69.         img_file = SimpleUploadedFile("1x1.txt", img_data)
    
  70.         with self.assertRaisesMessage(
    
  71.             ValidationError, "File extension “txt” is not allowed."
    
  72.         ):
    
  73.             f.clean(img_file)
    
  74. 
    
  75.     def test_corrupted_image(self):
    
  76.         f = ImageField()
    
  77.         img_file = SimpleUploadedFile("not_an_image.jpg", b"not an image")
    
  78.         msg = (
    
  79.             "Upload a valid image. The file you uploaded was either not an "
    
  80.             "image or a corrupted image."
    
  81.         )
    
  82.         with self.assertRaisesMessage(ValidationError, msg):
    
  83.             f.clean(img_file)
    
  84.         with TemporaryUploadedFile(
    
  85.             "not_an_image_tmp.png", "text/plain", 1, "utf-8"
    
  86.         ) as tmp_file:
    
  87.             with self.assertRaisesMessage(ValidationError, msg):
    
  88.                 f.clean(tmp_file)
    
  89. 
    
  90.     def test_widget_attrs_default_accept(self):
    
  91.         f = ImageField()
    
  92.         # Nothing added for non-FileInput widgets.
    
  93.         self.assertEqual(f.widget_attrs(Widget()), {})
    
  94.         self.assertEqual(f.widget_attrs(FileInput()), {"accept": "image/*"})
    
  95.         self.assertEqual(f.widget_attrs(ClearableFileInput()), {"accept": "image/*"})
    
  96.         self.assertWidgetRendersTo(
    
  97.             f, '<input type="file" name="f" accept="image/*" required id="id_f" />'
    
  98.         )
    
  99. 
    
  100.     def test_widget_attrs_accept_specified(self):
    
  101.         f = ImageField(widget=FileInput(attrs={"accept": "image/png"}))
    
  102.         self.assertEqual(f.widget_attrs(f.widget), {})
    
  103.         self.assertWidgetRendersTo(
    
  104.             f, '<input type="file" name="f" accept="image/png" required id="id_f" />'
    
  105.         )
    
  106. 
    
  107.     def test_widget_attrs_accept_false(self):
    
  108.         f = ImageField(widget=FileInput(attrs={"accept": False}))
    
  109.         self.assertEqual(f.widget_attrs(f.widget), {})
    
  110.         self.assertWidgetRendersTo(
    
  111.             f, '<input type="file" name="f" required id="id_f" />'
    
  112.         )