diff test/test_templating.py @ 8300:b99e76e76496

Make native date and number elements configurable Now for Number() and Integer() properties the browser-native number format can be configured with the use_browser_number_input config item in seciont [web]. The default is 'yes'. For Date() properties the config item is use_browser_date_input (also in section [web]) but the default is 'no'. In addition when defining Date() properties, these now have a parameter 'display_time' which defaults to 'yes' and a 'format' parameter which defaults to None. These set defaults for the field() method of the DateHTMLProperty which have the same parameters (but the display_time parameter of field() takes a boolean, not 'yes'/'no').
author Ralf Schlatterbeck <rsc@runtux.com>
date Wed, 19 Feb 2025 12:38:06 +0100
parents 46886073c665
children a81a3cd067fa
line wrap: on
line diff
--- a/test/test_templating.py	Wed Jan 22 10:10:39 2025 -0500
+++ b/test/test_templating.py	Wed Feb 19 12:38:06 2025 +0100
@@ -47,6 +47,13 @@
 
 from roundup.backends.sessions_common import SessionCommon
 
+class MockConfig(dict):
+    def __getattr__(self, name):
+        try:
+            return self[name]
+        except KeyError as err:
+            raise AttributeError(err)
+
 class MockDatabase(MockNull, SessionCommon):
     def getclass(self, name):
         # limit class names
@@ -95,7 +102,9 @@
         # add client props for testing anti_csrf_nonce
         self.client.session_api = MockNull(_sid="1234567890")
         self.client.db.getuid = lambda : 10
-        self.client.db.config = {'WEB_CSRF_TOKEN_LIFETIME': 10, 'MARKDOWN_BREAK_ON_NEWLINE': False }
+        self.client.db.config = MockConfig (
+            {'WEB_CSRF_TOKEN_LIFETIME': 10,
+             'MARKDOWN_BREAK_ON_NEWLINE': False })
 
 class HTMLDatabaseTestCase(TemplatingTestCase):
     def test_HTMLDatabase___getitem__(self):
@@ -350,12 +359,17 @@
         # test with number
         p = NumberHTMLProperty(self.client, 'testnum', '1', None, 'test',
                                2345678.2345678)
+        self.client.db.config['WEB_USE_BROWSER_NUMBER_INPUT'] = False
         self.assertEqual(p.field(),
-                         ('<input id="testnum1@test" name="testnum1@test" size="30" type="number" '
-                         'value="%s">')%expected_val)
+                         ('<input id="testnum1@test" name="testnum1@test" '
+                         'size="30" type="text" value="%s">')%expected_val)
+        self.client.db.config['WEB_USE_BROWSER_NUMBER_INPUT'] = True
+        self.assertEqual(p.field(),
+                         ('<input id="testnum1@test" name="testnum1@test" '
+                         'size="30" type="number" value="%s">')%expected_val)
         self.assertEqual(p.field(size=10),
-                         ('<input id="testnum1@test" name="testnum1@test" size="10" type="number" '
-                         'value="%s">')%expected_val)
+                         ('<input id="testnum1@test" name="testnum1@test" '
+                         'size="10" type="number" value="%s">')%expected_val)
         self.assertEqual(p.field(size=10, dataprop="foo", dataprop2=5),
                          ('<input dataprop="foo" dataprop2="5" '
                           'id="testnum1@test" name="testnum1@test" '
@@ -880,9 +894,20 @@
         self.client.db.close()
         memorydb.db_nuke('')
 
+    def exp_classhelp(self, cls='issue', prop='deadline', dlm='.'):
+        value = dlm.join (('2021-01-01', '11:22:10'))
+        return ('<a class="classhelp" data-calurl="%(cls)s?'
+        '@template=calendar&amp;amp;property=%(prop)s&amp;amp;'
+        'form=itemSynopsis&amp;date=%(value)s" '
+        'data-height="200" data-width="300" href="javascript:help_window'
+        '(\'%(cls)s?@template=calendar&amp;property=%(prop)s&amp;'
+        'form=itemSynopsis&date=%(value)s\', 300, 200)">(cal)</a>'
+        ) % {'cls': cls, 'prop': prop, 'value': value}
+
     def test_DateHTMLWithDate(self):
         """Test methods when DateHTMLProperty._value is a hyperdb.Date()
         """
+        self.client.db.config['WEB_USE_BROWSER_DATE_INPUT'] = True
         test_datestring = self.test_datestring
         test_Date = self.client.db.issue.get("1", 'deadline')
         test_hyperdbDate = self.client.db.issue.getprops("1")['deadline']
@@ -901,59 +926,28 @@
         self.assertEqual(d.plain(), "2021-01-01.13:22:10")
         self.assertEqual(d.local("-4").plain(), "2021-01-01.07:22:10")
         input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="date" value="2021-01-01">"""
-        self.assertEqual(d.field(), input_expected)
-        self.assertEqual(d.field_time(type="date"), input_expected)
+        self.assertEqual(d.field(display_time=False), input_expected)
 
-        input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="datetime-local" value="2021-01-01T13:22:10">"""
-        self.assertEqual(d.field(type="datetime-local"), input_expected)
-        self.assertEqual(d.field_time(), input_expected)
+        input_expected = '<input id="issue1@deadline" name="issue1@deadline" '\
+            'size="30" type="datetime-local" value="2021-01-01T13:22:10">'
+        self.assertEqual(d.field(), input_expected)
 
-        input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01-01.13:22:10">"""
-        self.assertEqual(d.field(type="text"), input_expected)
-        self.assertEqual(d.field_time(type="text"), input_expected)
+        input_expected = '<input id="issue1@deadline" name="issue1@deadline" '\
+            'size="30" type="text" value="2021-01-01.13:22:10">'
+        field = d.field(format='%Y-%m-%d.%H:%M:%S', popcal=False)
+        self.assertEqual(field, input_expected)
 
         # test with format
-        input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01"><a class="classhelp" data-calurl="issue?@template=calendar&amp;amp;property=deadline&amp;amp;form=itemSynopsis&amp;date=2021-01-01.11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'issue?@template=calendar&amp;property=deadline&amp;form=itemSynopsis&date=2021-01-01.11:22:10\', 300, 200)">(cal)</a>"""
-
-        self._caplog.clear()
-        with self._caplog.at_level(logging.WARNING,
-                                   logger="roundup"):
-            input = d.field(format="%Y-%m")
-        self.assertEqual(input_expected, input)
+        input_expected = '<input id="issue1@deadline" name="issue1@deadline" '\
+            'size="30" type="text" value="2021-01">' + self.exp_classhelp()
 
-        # name used for logging
-        log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template issue.item. Using text input."""
-        self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
-        # severity ERROR = 40
-        self.assertEqual(self._caplog.record_tuples[0][1], 30,
-                        msg="logging level != 30 (WARNING)")
-
-        # test with format and popcal=None
-        input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01">"""
+        self.assertEqual(d.field(format="%Y-%m"), input_expected)
 
-        self._caplog.clear()
-        with self._caplog.at_level(logging.WARNING,
-                                   logger="roundup"):
-            input = d.field(format="%Y-%m", popcal=False)
-        self.assertEqual(input_expected, input)
+        input_expected = '<input id="issue1@deadline" name="issue1@deadline" '\
+            'size="30" type="text" value="2021-01">'
 
-        # name used for logging
-        log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template issue.item. Using text input."""
-        self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
-        # severity ERROR = 40
-        self.assertEqual(self._caplog.record_tuples[0][1], 30,
-                        msg="logging level != 30 (WARNING)")
-
-        # test with format, type=text and popcal=None
-        input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01">"""
-
-        self._caplog.clear()
-        with self._caplog.at_level(logging.WARNING,
-                                   logger="roundup"):
-            input = d.field(type="text", format="%Y-%m", popcal=False )
-        self.assertEqual(input_expected, input)
-
-        self.assertEqual(self._caplog.records, [])
+        input = d.field(format="%Y-%m", popcal=False)
+        self.assertEqual(input, input_expected)
 
     def test_DateHTMLWithText(self):
         """Test methods when DateHTMLProperty._value is a string
@@ -964,6 +958,7 @@
 
         self.form.list.append(MiniFieldStorage("test1@test", test_datestring))
         self.client._props=test_date
+        self.client.db.config['WEB_USE_BROWSER_DATE_INPUT'] = False
 
         self.client.db.classes = dict \
             ( test = MockNull(getprops = lambda : test_date)
@@ -979,60 +974,40 @@
         self.assertIs(type(d._value), str)
         self.assertEqual(d.pretty(), "2021-01-01 11:22:10")
         self.assertEqual(d.plain(), "2021-01-01 11:22:10")
-        input = """<input id="test1@test" name="test1@test" size="30" type="date" value="2021-01-01 11:22:10">"""
-        self.assertEqual(d.field(), input)
-
-
-        input_expected = """<input id="test1@test" name="test1@test" size="40" type="date" value="2021-01-01 11:22:10">"""
-        self.assertEqual(d.field(size=40), input_expected)
-
-        input_expected = """<input id="test1@test" name="test1@test" size="30" type="text" value="2021-01-01 11:22:10"><a class="classhelp" data-calurl="test?@template=calendar&amp;amp;property=test&amp;amp;form=itemSynopsis&amp;date=2021-01-01 11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'test?@template=calendar&amp;property=test&amp;form=itemSynopsis&date=2021-01-01 11:22:10\', 300, 200)">(cal)</a>"""
-        with self._caplog.at_level(logging.WARNING,
-                                   logger="roundup"):
-            input = d.field(format="%Y-%m")
-        self.assertEqual(input_expected, input)
+        input_expected = '<input id="test1@test" name="test1@test" size="30" '\
+            'type="text" value="2021-01-01 11:22:10">'
+        self.assertEqual(d.field(popcal=False), input_expected)
+        self.client.db.config['WEB_USE_BROWSER_DATE_INPUT'] = True
+        input_expected = '<input id="test1@test" name="test1@test" size="30" '\
+            'type="datetime-local" value="2021-01-01 11:22:10">'
+        self.assertEqual(d.field(), input_expected)
+        self.client.db.config['WEB_USE_BROWSER_DATE_INPUT'] = False
 
-        # name used for logging
-        log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template test.item. Using text input."""
-        self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
-        # severity ERROR = 40
-        self.assertEqual(self._caplog.record_tuples[0][1], 30,
-                        msg="logging level != 30 (WARNING)")
+        input_expected = '<input id="test1@test" name="test1@test" size="40" '\
+            'type="text" value="2021-01-01 11:22:10">'
+        self.assertEqual(d.field(size=40, popcal=False), input_expected)
 
-        """with self.assertRaises(ValueError) as e:
-            d.field(format="%Y-%m")
-        self.assertIn("'%Y-%m'", e.exception.args[0])
-        self.assertIn("'date'", e.exception.args[0])"""
+        input_expected = ('<input id="test1@test" name="test1@test" size="30" '
+            'type="text" value="2021-01-01 11:22:10">'
+            + self.exp_classhelp(cls='test', prop='test', dlm=' '))
+        self.maxDiff=None
+        self.assertEqual(d.field(format="%Y-%m"), input_expected)
 
-
-        # format matches rfc format, so this should pass
-        result = d.field(format="%Y-%m-%d")
-        input_expected = """<input id="test1@test" name="test1@test" size="30" type="date" value="2021-01-01 11:22:10">"""
+        # format always uses type="text" even when date input is set
+        self.client.db.config['WEB_USE_BROWSER_DATE_INPUT'] = True
+        result = d.field(format="%Y-%m-%d", popcal=False)
+        input_expected = '<input id="test1@test" name="test1@test" size="30" '\
+            'type="text" value="2021-01-01 11:22:10">'
         self.assertEqual(result, input_expected)
 
-        input_expected = """<input id="test1@test" name="test1@test" size="30" type="text" value="2021-01-01 11:22:10"><a class="classhelp" data-calurl="test?@template=calendar&amp;amp;property=test&amp;amp;form=itemSynopsis&amp;date=2021-01-01 11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'test?@template=calendar&amp;property=test&amp;form=itemSynopsis&date=2021-01-01 11:22:10\', 300, 200)">(cal)</a>"""
-        with self._caplog.at_level(logging.WARNING,
-                                   logger="roundup"):
-            input = d.field(format="%Y-%m", type="datetime-local")
-        self.assertEqual(input_expected, input)
+        input_expected = ('<input id="test1@test" name="test1@test" size="30" '
+            'type="text" value="2021-01-01 11:22:10">'
+            + self.exp_classhelp(cls='test', prop='test', dlm=' '))
+        self.assertEqual(d.field(format="%Y-%m"), input_expected)
 
-        # name used for logging
-        log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template test.item. Using text input."""
-        self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
-        # severity ERROR = 40
-        self.assertEqual(self._caplog.record_tuples[0][1], 30,
-                        msg="logging level != 30 (WARNING)")
-
-        """
-        with self.assertRaises(ValueError) as e:
-            d.field(format="%Y-%m", type="datetime-local")
-        self.assertIn("'%Y-%m'", e.exception.args[0])
-        self.assertIn("'datetime-local'", e.exception.args[0])
-        """
-
-        # format matches rfc, so this should pass
-        result = d.field(type="datetime-local", format="%Y-%m-%dT%H:%M:%S")
-        input_expected = """<input id="test1@test" name="test1@test" size="30" type="datetime-local" value="2021-01-01 11:22:10">"""
+        result = d.field(format="%Y-%m-%dT%H:%M:%S", popcal=False)
+        input_expected = '<input id="test1@test" name="test1@test" size="30" '\
+            'type="text" value="2021-01-01 11:22:10">'
         self.assertEqual(result, input_expected)
 
 # common markdown test cases

Roundup Issue Tracker: http://roundup-tracker.org/