1. from django.core.files.uploadedfile import SimpleUploadedFile
    
  2. from django.forms import FileField, FileInput, Form
    
  3. from django.utils.datastructures import MultiValueDict
    
  4. 
    
  5. from .base import WidgetTest
    
  6. 
    
  7. 
    
  8. class FileInputTest(WidgetTest):
    
  9.     widget = FileInput()
    
  10. 
    
  11.     def test_render(self):
    
  12.         """
    
  13.         FileInput widgets never render the value attribute. The old value
    
  14.         isn't useful if a form is updated or an error occurred.
    
  15.         """
    
  16.         self.check_html(
    
  17.             self.widget,
    
  18.             "email",
    
  19.             "[email protected]",
    
  20.             html='<input type="file" name="email">',
    
  21.         )
    
  22.         self.check_html(
    
  23.             self.widget, "email", "", html='<input type="file" name="email">'
    
  24.         )
    
  25.         self.check_html(
    
  26.             self.widget, "email", None, html='<input type="file" name="email">'
    
  27.         )
    
  28. 
    
  29.     def test_value_omitted_from_data(self):
    
  30.         self.assertIs(self.widget.value_omitted_from_data({}, {}, "field"), True)
    
  31.         self.assertIs(
    
  32.             self.widget.value_omitted_from_data({}, {"field": "value"}, "field"), False
    
  33.         )
    
  34. 
    
  35.     def test_use_required_attribute(self):
    
  36.         # False when initial data exists. The file input is left blank by the
    
  37.         # user to keep the existing, initial value.
    
  38.         self.assertIs(self.widget.use_required_attribute(None), True)
    
  39.         self.assertIs(self.widget.use_required_attribute("resume.txt"), False)
    
  40. 
    
  41.     def test_fieldset(self):
    
  42.         class TestForm(Form):
    
  43.             template_name = "forms_tests/use_fieldset.html"
    
  44.             field = FileField(widget=self.widget)
    
  45. 
    
  46.         form = TestForm()
    
  47.         self.assertIs(self.widget.use_fieldset, False)
    
  48.         self.assertHTMLEqual(
    
  49.             '<div><label for="id_field">Field:</label><input id="id_field" '
    
  50.             'name="field" required type="file"></div>',
    
  51.             form.render(),
    
  52.         )
    
  53. 
    
  54.     def test_multiple_error(self):
    
  55.         msg = "FileInput doesn't support uploading multiple files."
    
  56.         with self.assertRaisesMessage(ValueError, msg):
    
  57.             FileInput(attrs={"multiple": True})
    
  58. 
    
  59.     def test_value_from_datadict_multiple(self):
    
  60.         class MultipleFileInput(FileInput):
    
  61.             allow_multiple_selected = True
    
  62. 
    
  63.         file_1 = SimpleUploadedFile("something1.txt", b"content 1")
    
  64.         file_2 = SimpleUploadedFile("something2.txt", b"content 2")
    
  65.         # Uploading multiple files is allowed.
    
  66.         widget = MultipleFileInput(attrs={"multiple": True})
    
  67.         value = widget.value_from_datadict(
    
  68.             data={"name": "Test name"},
    
  69.             files=MultiValueDict({"myfile": [file_1, file_2]}),
    
  70.             name="myfile",
    
  71.         )
    
  72.         self.assertEqual(value, [file_1, file_2])
    
  73.         # Uploading multiple files is not allowed.
    
  74.         widget = FileInput()
    
  75.         value = widget.value_from_datadict(
    
  76.             data={"name": "Test name"},
    
  77.             files=MultiValueDict({"myfile": [file_1, file_2]}),
    
  78.             name="myfile",
    
  79.         )
    
  80.         self.assertEqual(value, file_2)
    
  81. 
    
  82.     def test_multiple_default(self):
    
  83.         class MultipleFileInput(FileInput):
    
  84.             allow_multiple_selected = True
    
  85. 
    
  86.         tests = [
    
  87.             (None, True),
    
  88.             ({"class": "myclass"}, True),
    
  89.             ({"multiple": False}, False),
    
  90.         ]
    
  91.         for attrs, expected in tests:
    
  92.             with self.subTest(attrs=attrs):
    
  93.                 widget = MultipleFileInput(attrs=attrs)
    
  94.                 self.assertIs(widget.attrs["multiple"], expected)