2022-01-14 00:08:38 +01:00
|
|
|
from django.forms import ChoiceField, Form, SelectMultiple
|
2015-08-31 04:13:42 +02:00
|
|
|
|
|
|
|
from .base import WidgetTest
|
|
|
|
|
|
|
|
|
|
|
|
class SelectMultipleTest(WidgetTest):
|
2016-01-25 05:15:42 +01:00
|
|
|
widget = SelectMultiple
|
2015-08-31 04:13:42 +02:00
|
|
|
numeric_choices = (("0", "0"), ("1", "1"), ("2", "2"), ("3", "3"), ("0", "extra"))
|
|
|
|
|
2017-02-21 13:27:29 +01:00
|
|
|
def test_format_value(self):
|
|
|
|
widget = self.widget(choices=self.numeric_choices)
|
2018-03-30 11:55:33 +02:00
|
|
|
self.assertEqual(widget.format_value(None), [])
|
2017-02-21 13:27:29 +01:00
|
|
|
self.assertEqual(widget.format_value(""), [""])
|
|
|
|
self.assertEqual(widget.format_value([3, 0, 1]), ["3", "0", "1"])
|
|
|
|
|
2015-08-31 04:13:42 +02:00
|
|
|
def test_render_selected(self):
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=self.beatles),
|
|
|
|
"beatles",
|
|
|
|
["J"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="beatles">
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="J" selected>John</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="P">Paul</option>
|
|
|
|
<option value="G">George</option>
|
|
|
|
<option value="R">Ringo</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_render_multiple_selected(self):
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=self.beatles),
|
|
|
|
"beatles",
|
|
|
|
["J", "P"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="beatles">
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="J" selected>John</option>
|
|
|
|
<option value="P" selected>Paul</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="G">George</option>
|
|
|
|
<option value="R">Ringo</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_render_none(self):
|
|
|
|
"""
|
2018-03-30 11:55:33 +02:00
|
|
|
If the value is None, none of the options are selected, even if the
|
|
|
|
choices have an empty option.
|
2015-08-31 04:13:42 +02:00
|
|
|
"""
|
2018-03-30 11:55:33 +02:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=(("", "Unknown"),) + self.beatles),
|
|
|
|
"beatles",
|
|
|
|
None,
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="beatles">
|
2018-03-30 11:55:33 +02:00
|
|
|
<option value="">Unknown</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="J">John</option>
|
|
|
|
<option value="P">Paul</option>
|
|
|
|
<option value="G">George</option>
|
|
|
|
<option value="R">Ringo</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_render_value_label(self):
|
|
|
|
"""
|
|
|
|
If the value corresponds to a label (but not to an option value), none
|
|
|
|
of the options are selected.
|
|
|
|
"""
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=self.beatles),
|
|
|
|
"beatles",
|
|
|
|
["John"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="beatles">
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="J">John</option>
|
|
|
|
<option value="P">Paul</option>
|
|
|
|
<option value="G">George</option>
|
|
|
|
<option value="R">Ringo</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_multiple_options_same_value(self):
|
|
|
|
"""
|
|
|
|
Multiple options with the same value can be selected (#8103).
|
|
|
|
"""
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=self.numeric_choices),
|
|
|
|
"choices",
|
|
|
|
["0"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="choices">
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="0" selected>0</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="1">1</option>
|
|
|
|
<option value="2">2</option>
|
|
|
|
<option value="3">3</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="0" selected>extra</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_multiple_values_invalid(self):
|
|
|
|
"""
|
|
|
|
If multiple values are given, but some of them are not valid, the valid
|
|
|
|
ones are selected.
|
|
|
|
"""
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=self.beatles),
|
|
|
|
"beatles",
|
|
|
|
["J", "G", "foo"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="beatles">
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="J" selected>John</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="P">Paul</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="G" selected>George</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="R">Ringo</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_compare_string(self):
|
|
|
|
choices = [("1", "1"), ("2", "2"), ("3", "3")]
|
2022-02-03 20:24:19 +01:00
|
|
|
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=choices),
|
|
|
|
"nums",
|
|
|
|
[2],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="nums">
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="1">1</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="2" selected>2</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="3">3</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
2022-02-03 20:24:19 +01:00
|
|
|
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=choices),
|
|
|
|
"nums",
|
|
|
|
["2"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="nums">
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="1">1</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="2" selected>2</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="3">3</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
2022-02-03 20:24:19 +01:00
|
|
|
|
2016-01-25 05:15:42 +01:00
|
|
|
self.check_html(
|
|
|
|
self.widget(choices=choices),
|
|
|
|
"nums",
|
|
|
|
[2],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="nums">
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="1">1</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="2" selected>2</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<option value="3">3</option>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_optgroup_select_multiple(self):
|
|
|
|
widget = SelectMultiple(
|
|
|
|
choices=(
|
|
|
|
("outer1", "Outer 1"),
|
|
|
|
('Group "1"', (("inner1", "Inner 1"), ("inner2", "Inner 2"))),
|
|
|
|
)
|
2022-02-03 20:24:19 +01:00
|
|
|
)
|
2015-08-31 04:13:42 +02:00
|
|
|
self.check_html(
|
|
|
|
widget,
|
|
|
|
"nestchoice",
|
|
|
|
["outer1", "inner2"],
|
|
|
|
html=(
|
2018-01-20 17:19:06 +01:00
|
|
|
"""<select multiple name="nestchoice">
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="outer1" selected>Outer 1</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
<optgroup label="Group "1"">
|
|
|
|
<option value="inner1">Inner 1</option>
|
2016-09-22 00:12:13 +02:00
|
|
|
<option value="inner2" selected>Inner 2</option>
|
2015-08-31 04:13:42 +02:00
|
|
|
</optgroup>
|
|
|
|
</select>"""
|
2022-02-03 20:24:19 +01:00
|
|
|
),
|
2015-08-31 04:13:42 +02:00
|
|
|
)
|
2017-03-31 16:10:08 +02:00
|
|
|
|
|
|
|
def test_value_omitted_from_data(self):
|
|
|
|
widget = self.widget(choices=self.beatles)
|
|
|
|
self.assertIs(widget.value_omitted_from_data({}, {}, "field"), False)
|
|
|
|
self.assertIs(
|
|
|
|
widget.value_omitted_from_data({"field": "value"}, {}, "field"), False
|
|
|
|
)
|
2022-01-14 00:08:38 +01:00
|
|
|
|
|
|
|
def test_fieldset(self):
|
|
|
|
class TestForm(Form):
|
|
|
|
template_name = "forms_tests/use_fieldset.html"
|
|
|
|
field = ChoiceField(
|
|
|
|
widget=self.widget, choices=self.beatles, required=False
|
|
|
|
)
|
|
|
|
|
|
|
|
form = TestForm()
|
|
|
|
self.assertIs(self.widget.use_fieldset, False)
|
|
|
|
self.assertHTMLEqual(
|
|
|
|
'<div><label for="id_field">Field:</label>'
|
|
|
|
'<select multiple name="field" id="id_field">'
|
|
|
|
'<option value="J">John</option> <option value="P">Paul</option>'
|
|
|
|
'<option value="G">George</option><option value="R">Ringo'
|
|
|
|
"</option></select></div>",
|
|
|
|
form.render(),
|
|
|
|
)
|