test_selectmultiple.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. from django.forms import ChoiceField, Form, SelectMultiple
  2. from .base import WidgetTest
  3. class SelectMultipleTest(WidgetTest):
  4. widget = SelectMultiple
  5. numeric_choices = (("0", "0"), ("1", "1"), ("2", "2"), ("3", "3"), ("0", "extra"))
  6. def test_format_value(self):
  7. widget = self.widget(choices=self.numeric_choices)
  8. self.assertEqual(widget.format_value(None), [])
  9. self.assertEqual(widget.format_value(""), [""])
  10. self.assertEqual(widget.format_value([3, 0, 1]), ["3", "0", "1"])
  11. def test_render_selected(self):
  12. self.check_html(
  13. self.widget(choices=self.beatles),
  14. "beatles",
  15. ["J"],
  16. html=(
  17. """<select multiple name="beatles">
  18. <option value="J" selected>John</option>
  19. <option value="P">Paul</option>
  20. <option value="G">George</option>
  21. <option value="R">Ringo</option>
  22. </select>"""
  23. ),
  24. )
  25. def test_render_multiple_selected(self):
  26. self.check_html(
  27. self.widget(choices=self.beatles),
  28. "beatles",
  29. ["J", "P"],
  30. html=(
  31. """<select multiple name="beatles">
  32. <option value="J" selected>John</option>
  33. <option value="P" selected>Paul</option>
  34. <option value="G">George</option>
  35. <option value="R">Ringo</option>
  36. </select>"""
  37. ),
  38. )
  39. def test_render_none(self):
  40. """
  41. If the value is None, none of the options are selected, even if the
  42. choices have an empty option.
  43. """
  44. self.check_html(
  45. self.widget(choices=(("", "Unknown"),) + self.beatles),
  46. "beatles",
  47. None,
  48. html=(
  49. """<select multiple name="beatles">
  50. <option value="">Unknown</option>
  51. <option value="J">John</option>
  52. <option value="P">Paul</option>
  53. <option value="G">George</option>
  54. <option value="R">Ringo</option>
  55. </select>"""
  56. ),
  57. )
  58. def test_render_value_label(self):
  59. """
  60. If the value corresponds to a label (but not to an option value), none
  61. of the options are selected.
  62. """
  63. self.check_html(
  64. self.widget(choices=self.beatles),
  65. "beatles",
  66. ["John"],
  67. html=(
  68. """<select multiple name="beatles">
  69. <option value="J">John</option>
  70. <option value="P">Paul</option>
  71. <option value="G">George</option>
  72. <option value="R">Ringo</option>
  73. </select>"""
  74. ),
  75. )
  76. def test_multiple_options_same_value(self):
  77. """
  78. Multiple options with the same value can be selected (#8103).
  79. """
  80. self.check_html(
  81. self.widget(choices=self.numeric_choices),
  82. "choices",
  83. ["0"],
  84. html=(
  85. """<select multiple name="choices">
  86. <option value="0" selected>0</option>
  87. <option value="1">1</option>
  88. <option value="2">2</option>
  89. <option value="3">3</option>
  90. <option value="0" selected>extra</option>
  91. </select>"""
  92. ),
  93. )
  94. def test_multiple_values_invalid(self):
  95. """
  96. If multiple values are given, but some of them are not valid, the valid
  97. ones are selected.
  98. """
  99. self.check_html(
  100. self.widget(choices=self.beatles),
  101. "beatles",
  102. ["J", "G", "foo"],
  103. html=(
  104. """<select multiple name="beatles">
  105. <option value="J" selected>John</option>
  106. <option value="P">Paul</option>
  107. <option value="G" selected>George</option>
  108. <option value="R">Ringo</option>
  109. </select>"""
  110. ),
  111. )
  112. def test_compare_string(self):
  113. choices = [("1", "1"), ("2", "2"), ("3", "3")]
  114. self.check_html(
  115. self.widget(choices=choices),
  116. "nums",
  117. [2],
  118. html=(
  119. """<select multiple name="nums">
  120. <option value="1">1</option>
  121. <option value="2" selected>2</option>
  122. <option value="3">3</option>
  123. </select>"""
  124. ),
  125. )
  126. self.check_html(
  127. self.widget(choices=choices),
  128. "nums",
  129. ["2"],
  130. html=(
  131. """<select multiple name="nums">
  132. <option value="1">1</option>
  133. <option value="2" selected>2</option>
  134. <option value="3">3</option>
  135. </select>"""
  136. ),
  137. )
  138. self.check_html(
  139. self.widget(choices=choices),
  140. "nums",
  141. [2],
  142. html=(
  143. """<select multiple name="nums">
  144. <option value="1">1</option>
  145. <option value="2" selected>2</option>
  146. <option value="3">3</option>
  147. </select>"""
  148. ),
  149. )
  150. def test_optgroup_select_multiple(self):
  151. widget = SelectMultiple(
  152. choices=(
  153. ("outer1", "Outer 1"),
  154. ('Group "1"', (("inner1", "Inner 1"), ("inner2", "Inner 2"))),
  155. )
  156. )
  157. self.check_html(
  158. widget,
  159. "nestchoice",
  160. ["outer1", "inner2"],
  161. html=(
  162. """<select multiple name="nestchoice">
  163. <option value="outer1" selected>Outer 1</option>
  164. <optgroup label="Group &quot;1&quot;">
  165. <option value="inner1">Inner 1</option>
  166. <option value="inner2" selected>Inner 2</option>
  167. </optgroup>
  168. </select>"""
  169. ),
  170. )
  171. def test_value_omitted_from_data(self):
  172. widget = self.widget(choices=self.beatles)
  173. self.assertIs(widget.value_omitted_from_data({}, {}, "field"), False)
  174. self.assertIs(
  175. widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
  176. )
  177. def test_fieldset(self):
  178. class TestForm(Form):
  179. template_name = "forms_tests/use_fieldset.html"
  180. field = ChoiceField(
  181. widget=self.widget, choices=self.beatles, required=False
  182. )
  183. form = TestForm()
  184. self.assertIs(self.widget.use_fieldset, False)
  185. self.assertHTMLEqual(
  186. '<div><label for="id_field">Field:</label>'
  187. '<select multiple name="field" id="id_field">'
  188. '<option value="J">John</option> <option value="P">Paul</option>'
  189. '<option value="G">George</option><option value="R">Ringo'
  190. "</option></select></div>",
  191. form.render(),
  192. )