1. from django.forms import Form, HiddenInput, NullBooleanField, RadioSelect
    
  2. from django.test import SimpleTestCase
    
  3. 
    
  4. from . import FormFieldAssertionsMixin
    
  5. 
    
  6. 
    
  7. class NullBooleanFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
    
  8.     def test_nullbooleanfield_clean(self):
    
  9.         f = NullBooleanField()
    
  10.         self.assertIsNone(f.clean(""))
    
  11.         self.assertTrue(f.clean(True))
    
  12.         self.assertFalse(f.clean(False))
    
  13.         self.assertIsNone(f.clean(None))
    
  14.         self.assertFalse(f.clean("0"))
    
  15.         self.assertTrue(f.clean("1"))
    
  16.         self.assertIsNone(f.clean("2"))
    
  17.         self.assertIsNone(f.clean("3"))
    
  18.         self.assertIsNone(f.clean("hello"))
    
  19.         self.assertTrue(f.clean("true"))
    
  20.         self.assertFalse(f.clean("false"))
    
  21. 
    
  22.     def test_nullbooleanfield_2(self):
    
  23.         # The internal value is preserved if using HiddenInput (#7753).
    
  24.         class HiddenNullBooleanForm(Form):
    
  25.             hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
    
  26.             hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
    
  27. 
    
  28.         f = HiddenNullBooleanForm()
    
  29.         self.assertHTMLEqual(
    
  30.             str(f),
    
  31.             '<input type="hidden" name="hidden_nullbool1" value="True" '
    
  32.             'id="id_hidden_nullbool1">'
    
  33.             '<input type="hidden" name="hidden_nullbool2" value="False" '
    
  34.             'id="id_hidden_nullbool2">',
    
  35.         )
    
  36. 
    
  37.     def test_nullbooleanfield_3(self):
    
  38.         class HiddenNullBooleanForm(Form):
    
  39.             hidden_nullbool1 = NullBooleanField(widget=HiddenInput, initial=True)
    
  40.             hidden_nullbool2 = NullBooleanField(widget=HiddenInput, initial=False)
    
  41. 
    
  42.         f = HiddenNullBooleanForm(
    
  43.             {"hidden_nullbool1": "True", "hidden_nullbool2": "False"}
    
  44.         )
    
  45.         self.assertIsNone(f.full_clean())
    
  46.         self.assertTrue(f.cleaned_data["hidden_nullbool1"])
    
  47.         self.assertFalse(f.cleaned_data["hidden_nullbool2"])
    
  48. 
    
  49.     def test_nullbooleanfield_4(self):
    
  50.         # Make sure we're compatible with MySQL, which uses 0 and 1 for its
    
  51.         # boolean values (#9609).
    
  52.         NULLBOOL_CHOICES = (("1", "Yes"), ("0", "No"), ("", "Unknown"))
    
  53. 
    
  54.         class MySQLNullBooleanForm(Form):
    
  55.             nullbool0 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
    
  56.             nullbool1 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
    
  57.             nullbool2 = NullBooleanField(widget=RadioSelect(choices=NULLBOOL_CHOICES))
    
  58. 
    
  59.         f = MySQLNullBooleanForm({"nullbool0": "1", "nullbool1": "0", "nullbool2": ""})
    
  60.         self.assertIsNone(f.full_clean())
    
  61.         self.assertTrue(f.cleaned_data["nullbool0"])
    
  62.         self.assertFalse(f.cleaned_data["nullbool1"])
    
  63.         self.assertIsNone(f.cleaned_data["nullbool2"])
    
  64. 
    
  65.     def test_nullbooleanfield_changed(self):
    
  66.         f = NullBooleanField()
    
  67.         self.assertTrue(f.has_changed(False, None))
    
  68.         self.assertTrue(f.has_changed(None, False))
    
  69.         self.assertFalse(f.has_changed(None, None))
    
  70.         self.assertFalse(f.has_changed(False, False))
    
  71.         self.assertTrue(f.has_changed(True, False))
    
  72.         self.assertTrue(f.has_changed(True, None))
    
  73.         self.assertTrue(f.has_changed(True, False))
    
  74.         # HiddenInput widget sends string values for boolean but doesn't clean
    
  75.         # them in value_from_datadict.
    
  76.         self.assertFalse(f.has_changed(False, "False"))
    
  77.         self.assertFalse(f.has_changed(True, "True"))
    
  78.         self.assertFalse(f.has_changed(None, ""))
    
  79.         self.assertTrue(f.has_changed(False, "True"))
    
  80.         self.assertTrue(f.has_changed(True, "False"))
    
  81.         self.assertTrue(f.has_changed(None, "False"))