import os import unittest from django.core.exceptions import ValidationError from django.core.files.uploadedfile import ( SimpleUploadedFile, TemporaryUploadedFile, ) from django.forms import ClearableFileInput, FileInput, ImageField, Widget from django.test import SimpleTestCase from . import FormFieldAssertionsMixin try: from PIL import Image except ImportError: Image = None def get_img_path(path): return os.path.join(os.path.abspath(os.path.join(__file__, '..', '..')), 'tests', path) @unittest.skipUnless(Image, "Pillow is required to test ImageField") class ImageFieldTest(FormFieldAssertionsMixin, SimpleTestCase): def test_imagefield_annotate_with_image_after_clean(self): f = ImageField() img_path = get_img_path('filepath_test_files/1x1.png') with open(img_path, 'rb') as img_file: img_data = img_file.read() img_file = SimpleUploadedFile('1x1.png', img_data) img_file.content_type = 'text/plain' uploaded_file = f.clean(img_file) self.assertEqual('PNG', uploaded_file.image.format) self.assertEqual('image/png', uploaded_file.content_type) def test_imagefield_annotate_with_bitmap_image_after_clean(self): """ This also tests the situation when Pillow doesn't detect the MIME type of the image (#24948). """ from PIL.BmpImagePlugin import BmpImageFile try: Image.register_mime(BmpImageFile.format, None) f = ImageField() img_path = get_img_path('filepath_test_files/1x1.bmp') with open(img_path, 'rb') as img_file: img_data = img_file.read() img_file = SimpleUploadedFile('1x1.bmp', img_data) img_file.content_type = 'text/plain' uploaded_file = f.clean(img_file) self.assertEqual('BMP', uploaded_file.image.format) self.assertIsNone(uploaded_file.content_type) finally: Image.register_mime(BmpImageFile.format, 'image/bmp') def test_file_extension_validation(self): f = ImageField() img_path = get_img_path('filepath_test_files/1x1.png') with open(img_path, 'rb') as img_file: img_data = img_file.read() img_file = SimpleUploadedFile('1x1.txt', img_data) with self.assertRaisesMessage(ValidationError, 'File extension “txt” is not allowed.'): f.clean(img_file) def test_corrupted_image(self): f = ImageField() img_file = SimpleUploadedFile('not_an_image.jpg', b'not an image') msg = ( 'Upload a valid image. The file you uploaded was either not an ' 'image or a corrupted image.' ) with self.assertRaisesMessage(ValidationError, msg): f.clean(img_file) with TemporaryUploadedFile('not_an_image_tmp.png', 'text/plain', 1, 'utf-8') as tmp_file: with self.assertRaisesMessage(ValidationError, msg): f.clean(tmp_file) def test_widget_attrs_default_accept(self): f = ImageField() # Nothing added for non-FileInput widgets. self.assertEqual(f.widget_attrs(Widget()), {}) self.assertEqual(f.widget_attrs(FileInput()), {'accept': 'image/*'}) self.assertEqual(f.widget_attrs(ClearableFileInput()), {'accept': 'image/*'}) self.assertWidgetRendersTo(f, '') def test_widget_attrs_accept_specified(self): f = ImageField(widget=FileInput(attrs={'accept': 'image/png'})) self.assertEqual(f.widget_attrs(f.widget), {}) self.assertWidgetRendersTo(f, '') def test_widget_attrs_accept_false(self): f = ImageField(widget=FileInput(attrs={'accept': False})) self.assertEqual(f.widget_attrs(f.widget), {}) self.assertWidgetRendersTo(f, '')