123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592 |
- from datetime import date
- from django.forms import DateField, Form, SelectDateWidget
- from django.test import override_settings
- from django.utils import translation
- from django.utils.dates import MONTHS_AP
- from .base import WidgetTest
- class SelectDateWidgetTest(WidgetTest):
- maxDiff = None
- widget = SelectDateWidget(
- years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016'),
- )
- def test_render_empty(self):
- self.check_html(self.widget, 'mydate', '', html=(
- """
- <select name="mydate_month" id="id_mydate_month">
- <option selected value="">---</option>
- <option value="1">January</option>
- <option value="2">February</option>
- <option value="3">March</option>
- <option value="4">April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">August</option>
- <option value="9">September</option>
- <option value="10">October</option>
- <option value="11">November</option>
- <option value="12">December</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option selected value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option selected value="">---</option>
- <option value="2007">2007</option>
- <option value="2008">2008</option>
- <option value="2009">2009</option>
- <option value="2010">2010</option>
- <option value="2011">2011</option>
- <option value="2012">2012</option>
- <option value="2013">2013</option>
- <option value="2014">2014</option>
- <option value="2015">2015</option>
- <option value="2016">2016</option>
- </select>
- """
- ))
- def test_render_none(self):
- """
- Rendering the None or '' values should yield the same output.
- """
- self.assertHTMLEqual(
- self.widget.render('mydate', None),
- self.widget.render('mydate', ''),
- )
- def test_render_string(self):
- self.check_html(self.widget, 'mydate', '2010-04-15', html=(
- """
- <select name="mydate_month" id="id_mydate_month">
- <option value="">---</option>
- <option value="1">January</option>
- <option value="2">February</option>
- <option value="3">March</option>
- <option value="4" selected>April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">August</option>
- <option value="9">September</option>
- <option value="10">October</option>
- <option value="11">November</option>
- <option value="12">December</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15" selected>15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option value="">---</option>
- <option value="2007">2007</option>
- <option value="2008">2008</option>
- <option value="2009">2009</option>
- <option value="2010" selected>2010</option>
- <option value="2011">2011</option>
- <option value="2012">2012</option>
- <option value="2013">2013</option>
- <option value="2014">2014</option>
- <option value="2015">2015</option>
- <option value="2016">2016</option>
- </select>
- """
- ))
- def test_render_datetime(self):
- self.assertHTMLEqual(
- self.widget.render('mydate', date(2010, 4, 15)),
- self.widget.render('mydate', '2010-04-15'),
- )
- def test_render_invalid_date(self):
- """
- Invalid dates should still render the failed date.
- """
- self.check_html(self.widget, 'mydate', '2010-02-31', html=(
- """
- <select name="mydate_month" id="id_mydate_month">
- <option value="">---</option>
- <option value="1">January</option>
- <option value="2" selected>February</option>
- <option value="3">March</option>
- <option value="4">April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">August</option>
- <option value="9">September</option>
- <option value="10">October</option>
- <option value="11">November</option>
- <option value="12">December</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31" selected>31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option value="">---</option>
- <option value="2007">2007</option>
- <option value="2008">2008</option>
- <option value="2009">2009</option>
- <option value="2010" selected>2010</option>
- <option value="2011">2011</option>
- <option value="2012">2012</option>
- <option value="2013">2013</option>
- <option value="2014">2014</option>
- <option value="2015">2015</option>
- <option value="2016">2016</option>
- </select>
- """
- ))
- def test_custom_months(self):
- widget = SelectDateWidget(months=MONTHS_AP, years=('2013',))
- self.check_html(widget, 'mydate', '', html=(
- """
- <select name="mydate_month" id="id_mydate_month">
- <option selected value="">---</option>
- <option value="1">Jan.</option>
- <option value="2">Feb.</option>
- <option value="3">March</option>
- <option value="4">April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">Aug.</option>
- <option value="9">Sept.</option>
- <option value="10">Oct.</option>
- <option value="11">Nov.</option>
- <option value="12">Dec.</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option selected value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option selected value="">---</option>
- <option value="2013">2013</option>
- </select>
- """
- ))
- def test_selectdate_required(self):
- class GetNotRequiredDate(Form):
- mydate = DateField(widget=SelectDateWidget, required=False)
- class GetRequiredDate(Form):
- mydate = DateField(widget=SelectDateWidget, required=True)
- self.assertFalse(GetNotRequiredDate().fields['mydate'].widget.is_required)
- self.assertTrue(GetRequiredDate().fields['mydate'].widget.is_required)
- def test_selectdate_empty_label(self):
- w = SelectDateWidget(years=('2014',), empty_label='empty_label')
- # Rendering the default state with empty_label set as string.
- self.assertInHTML('<option selected value="">empty_label</option>', w.render('mydate', ''), count=3)
- w = SelectDateWidget(years=('2014',), empty_label=('empty_year', 'empty_month', 'empty_day'))
- # Rendering the default state with empty_label tuple.
- self.assertHTMLEqual(
- w.render('mydate', ''),
- """
- <select name="mydate_month" id="id_mydate_month">
- <option selected value="">empty_month</option>
- <option value="1">January</option>
- <option value="2">February</option>
- <option value="3">March</option>
- <option value="4">April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">August</option>
- <option value="9">September</option>
- <option value="10">October</option>
- <option value="11">November</option>
- <option value="12">December</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option selected value="">empty_day</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option selected value="">empty_year</option>
- <option value="2014">2014</option>
- </select>
- """,
- )
- with self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.'):
- SelectDateWidget(years=('2014',), empty_label=('not enough', 'values'))
- @override_settings(USE_L10N=True)
- @translation.override('nl')
- def test_l10n(self):
- w = SelectDateWidget(
- years=('2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016')
- )
- self.assertEqual(
- w.value_from_datadict({'date_year': '2010', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-2010',
- )
- self.assertHTMLEqual(
- w.render('date', '13-08-2010'),
- """
- <select name="date_day" id="id_date_day">
- <option value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13" selected>13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="date_month" id="id_date_month">
- <option value="">---</option>
- <option value="1">januari</option>
- <option value="2">februari</option>
- <option value="3">maart</option>
- <option value="4">april</option>
- <option value="5">mei</option>
- <option value="6">juni</option>
- <option value="7">juli</option>
- <option value="8" selected>augustus</option>
- <option value="9">september</option>
- <option value="10">oktober</option>
- <option value="11">november</option>
- <option value="12">december</option>
- </select>
- <select name="date_year" id="id_date_year">
- <option value="">---</option>
- <option value="2007">2007</option>
- <option value="2008">2008</option>
- <option value="2009">2009</option>
- <option value="2010" selected>2010</option>
- <option value="2011">2011</option>
- <option value="2012">2012</option>
- <option value="2013">2013</option>
- <option value="2014">2014</option>
- <option value="2015">2015</option>
- <option value="2016">2016</option>
- </select>
- """,
- )
- # Even with an invalid date, the widget should reflect the entered value (#17401).
- self.assertEqual(w.render('mydate', '2010-02-30').count('selected'), 3)
- # Years before 1900 should work.
- w = SelectDateWidget(years=('1899',))
- self.assertEqual(
- w.value_from_datadict({'date_year': '1899', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-1899',
- )
- # And years before 1000 (demonstrating the need for datetime_safe).
- w = SelectDateWidget(years=('0001',))
- self.assertEqual(
- w.value_from_datadict({'date_year': '0001', 'date_month': '8', 'date_day': '13'}, {}, 'date'),
- '13-08-0001',
- )
- def test_format_value(self):
- valid_formats = [
- '2000-1-1', '2000-10-15', '2000-01-01',
- '2000-01-0', '2000-0-01', '2000-0-0',
- '0-01-01', '0-01-0', '0-0-01', '0-0-0',
- ]
- for value in valid_formats:
- year, month, day = (int(x) or '' for x in value.split('-'))
- with self.subTest(value=value):
- self.assertEqual(self.widget.format_value(value), {'day': day, 'month': month, 'year': year})
- invalid_formats = [
- '2000-01-001', '2000-001-01', '2-01-01', '20-01-01', '200-01-01',
- '20000-01-01',
- ]
- for value in invalid_formats:
- with self.subTest(value=value):
- self.assertEqual(self.widget.format_value(value), {'day': None, 'month': None, 'year': None})
- def test_value_from_datadict(self):
- tests = [
- (('2000', '12', '1'), '2000-12-1'),
- (('', '12', '1'), '0-12-1'),
- (('2000', '', '1'), '2000-0-1'),
- (('2000', '12', ''), '2000-12-0'),
- (('', '', '', ''), None),
- ((None, '12', '1'), None),
- (('2000', None, '1'), None),
- (('2000', '12', None), None),
- ]
- for values, expected in tests:
- with self.subTest(values=values):
- data = {}
- for field_name, value in zip(('year', 'month', 'day'), values):
- if value is not None:
- data['field_%s' % field_name] = value
- self.assertEqual(self.widget.value_from_datadict(data, {}, 'field'), expected)
- def test_value_omitted_from_data(self):
- self.assertIs(self.widget.value_omitted_from_data({}, {}, 'field'), True)
- self.assertIs(self.widget.value_omitted_from_data({'field_month': '12'}, {}, 'field'), False)
- self.assertIs(self.widget.value_omitted_from_data({'field_year': '2000'}, {}, 'field'), False)
- self.assertIs(self.widget.value_omitted_from_data({'field_day': '1'}, {}, 'field'), False)
- data = {'field_day': '1', 'field_month': '12', 'field_year': '2000'}
- self.assertIs(self.widget.value_omitted_from_data(data, {}, 'field'), False)
- @override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True)
- def test_years_rendered_without_separator(self):
- widget = SelectDateWidget(years=(2007,))
- self.check_html(widget, 'mydate', '', html=(
- """
- <select name="mydate_month" id="id_mydate_month">
- <option selected value="">---</option>
- <option value="1">January</option>
- <option value="2">February</option>
- <option value="3">March</option>
- <option value="4">April</option>
- <option value="5">May</option>
- <option value="6">June</option>
- <option value="7">July</option>
- <option value="8">August</option>
- <option value="9">September</option>
- <option value="10">October</option>
- <option value="11">November</option>
- <option value="12">December</option>
- </select>
- <select name="mydate_day" id="id_mydate_day">
- <option selected value="">---</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="10">10</option>
- <option value="11">11</option>
- <option value="12">12</option>
- <option value="13">13</option>
- <option value="14">14</option>
- <option value="15">15</option>
- <option value="16">16</option>
- <option value="17">17</option>
- <option value="18">18</option>
- <option value="19">19</option>
- <option value="20">20</option>
- <option value="21">21</option>
- <option value="22">22</option>
- <option value="23">23</option>
- <option value="24">24</option>
- <option value="25">25</option>
- <option value="26">26</option>
- <option value="27">27</option>
- <option value="28">28</option>
- <option value="29">29</option>
- <option value="30">30</option>
- <option value="31">31</option>
- </select>
- <select name="mydate_year" id="id_mydate_year">
- <option selected value="">---</option>
- <option value="2007">2007</option>
- </select>
- """
- ))
|