comparison test/test_templating.py @ 8285:2bf0c4e7795e

fix: issue2551390 - Replace text input/calendar popup with native date input Docs, code and test changes for the changeover to a native date element. See issue for details.
author John Rouillard <rouilj@ieee.org>
date Sat, 18 Jan 2025 12:23:23 -0500
parents 669dfccca898
children 6445e63bb423
comparison
equal deleted inserted replaced
8284:92dad05379f9 8285:2bf0c4e7795e
3 import time 3 import time
4 4
5 from roundup.anypy.cgi_ import FieldStorage, MiniFieldStorage 5 from roundup.anypy.cgi_ import FieldStorage, MiniFieldStorage
6 from roundup.cgi.templating import * 6 from roundup.cgi.templating import *
7 from roundup.cgi.ZTUtils.Iterator import Iterator 7 from roundup.cgi.ZTUtils.Iterator import Iterator
8 from roundup.test import memorydb
8 from .test_actions import MockNull, true 9 from .test_actions import MockNull, true
9 from .html_norm import NormalizingHtmlParser 10 from .html_norm import NormalizingHtmlParser
10 11
11 12
12 import pytest 13 import pytest
714 715
715 class HTMLPropertyTestClass(unittest.TestCase): 716 class HTMLPropertyTestClass(unittest.TestCase):
716 def setUp(self): 717 def setUp(self):
717 self.form = FieldStorage() 718 self.form = FieldStorage()
718 self.client = MockNull() 719 self.client = MockNull()
719 self.client.db = db = MockDatabase() 720 self.client.db = db = memorydb.create('admin')
721 db.tx_Source = "web"
722
723 db.issue.addprop(tx_Source=hyperdb.String())
724
720 db.security.hasPermission = lambda *args, **kw: True 725 db.security.hasPermission = lambda *args, **kw: True
721 self.client.form = self.form 726 self.client.form = self.form
722 727
723 self.client._props = MockNull() 728 self.client._props = MockNull()
724 # add client props for testing anti_csrf_nonce 729 # add client props for testing anti_csrf_nonce
725 self.client.session_api = MockNull(_sid="1234567890") 730 self.client.session_api = MockNull(_sid="1234567890")
726 self.client.db.getuid = lambda : 10 731 self.client.db.getuid = lambda : 10
727 732
733 @pytest.fixture(autouse=True)
734 def inject_fixtures(self, caplog):
735 self._caplog = caplog
736
728 class DateHTMLPropertyTestCase(HTMLPropertyTestClass): 737 class DateHTMLPropertyTestCase(HTMLPropertyTestClass):
738
739 def setUp(self):
740 super(DateHTMLPropertyTestCase, self).setUp()
741
742 db = self.client.db
743 db.issue.addprop(deadline=hyperdb.Date())
744
745 self.test_datestring = "2021-01-01.11:22:10"
746
747 self.client.db.issue.create(title="title",
748 deadline=date.Date(self.test_datestring))
749 self.client.db.getUserTimezone = lambda: "2"
750
751 def tearDown(self):
752 self.client.db.close()
753 memorydb.db_nuke('')
754
755 def test_DateHTMLWithDate(self):
756 """Test methods when DateHTMLProperty._value is a hyperdb.Date()
757 """
758 test_datestring = self.test_datestring
759 test_Date = self.client.db.issue.get("1", 'deadline')
760 test_hyperdbDate = self.client.db.issue.getprops("1")['deadline']
761
762 self.client.classname = "issue"
763 self.client.template = "item"
764
765 # client, classname, nodeid, prop, name, value,
766 # anonymous=0, offset=None
767 d = DateHTMLProperty(self.client, 'issue', '1', test_hyperdbDate,
768 'deadline', test_Date)
769 self.assertIsInstance(d._value, date.Date)
770 self.assertEqual(d.pretty(), " 1 January 2021")
771 self.assertEqual(d.pretty(format="%Y-%m"), "2021-01")
772 self.assertEqual(d.plain(), "2021-01-01.13:22:10")
773 self.assertEqual(d.local("-4").plain(), "2021-01-01.07:22:10")
774 input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="date" value="2021-01-01">"""
775 self.assertEqual(d.field(), input_expected)
776 self.assertEqual(d.field_time(type="date"), input_expected)
777
778 input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="datetime-local" value="2021-01-01T13:22:10">"""
779 self.assertEqual(d.field(type="datetime-local"), input_expected)
780 self.assertEqual(d.field_time(), input_expected)
781
782 input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01-01.13:22:10">"""
783 self.assertEqual(d.field(type="text"), input_expected)
784 self.assertEqual(d.field_time(type="text"), input_expected)
785
786 # test with format
787 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>"""
788
789 self._caplog.clear()
790 with self._caplog.at_level(logging.WARNING,
791 logger="roundup"):
792 input = d.field(format="%Y-%m")
793 self.assertEqual(input_expected, input)
794
795 # name used for logging
796 log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template issue.item. Using text input."""
797 self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
798 # severity ERROR = 40
799 self.assertEqual(self._caplog.record_tuples[0][1], 30,
800 msg="logging level != 30 (WARNING)")
801
802 # test with format and popcal=None
803 input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01">"""
804
805 self._caplog.clear()
806 with self._caplog.at_level(logging.WARNING,
807 logger="roundup"):
808 input = d.field(format="%Y-%m", popcal=False)
809 self.assertEqual(input_expected, input)
810
811 # name used for logging
812 log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template issue.item. Using text input."""
813 self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
814 # severity ERROR = 40
815 self.assertEqual(self._caplog.record_tuples[0][1], 30,
816 msg="logging level != 30 (WARNING)")
817
818 # test with format, type=text and popcal=None
819 input_expected = """<input id="issue1@deadline" name="issue1@deadline" size="30" type="text" value="2021-01">"""
820
821 self._caplog.clear()
822 with self._caplog.at_level(logging.WARNING,
823 logger="roundup"):
824 input = d.field(type="text", format="%Y-%m", popcal=False )
825 self.assertEqual(input_expected, input)
826
827 self.assertEqual(self._caplog.records, [])
729 828
730 def test_DateHTMLWithText(self): 829 def test_DateHTMLWithText(self):
731 """Test methods when DateHTMLProperty._value is a string 830 """Test methods when DateHTMLProperty._value is a string
732 rather than a hyperdb.Date() 831 rather than a hyperdb.Date()
733 """ 832 """
738 self.client._props=test_date 837 self.client._props=test_date
739 838
740 self.client.db.classes = dict \ 839 self.client.db.classes = dict \
741 ( test = MockNull(getprops = lambda : test_date) 840 ( test = MockNull(getprops = lambda : test_date)
742 ) 841 )
842
843 self.client.classname = "test"
844 self.client.template = "item"
743 845
744 # client, classname, nodeid, prop, name, value, 846 # client, classname, nodeid, prop, name, value,
745 # anonymous=0, offset=None 847 # anonymous=0, offset=None
746 d = DateHTMLProperty(self.client, 'test', '1', self.client._props, 848 d = DateHTMLProperty(self.client, 'test', '1', self.client._props,
747 'test', '') 849 'test', '')
748 self.assertIs(type(d._value), str) 850 self.assertIs(type(d._value), str)
749 self.assertEqual(d.pretty(), "2021-01-01 11:22:10") 851 self.assertEqual(d.pretty(), "2021-01-01 11:22:10")
750 self.assertEqual(d.plain(), "2021-01-01 11:22:10") 852 self.assertEqual(d.plain(), "2021-01-01 11:22:10")
751 input = """<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>""" 853 input = """<input id="test1@test" name="test1@test" size="30" type="date" value="2021-01-01 11:22:10">"""
752 self.assertEqual(d.field(), input) 854 self.assertEqual(d.field(), input)
855
856
857 input_expected = """<input id="test1@test" name="test1@test" size="40" type="date" value="2021-01-01 11:22:10">"""
858 self.assertEqual(d.field(size=40), input_expected)
859
860 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>"""
861 with self._caplog.at_level(logging.WARNING,
862 logger="roundup"):
863 input = d.field(format="%Y-%m")
864 self.assertEqual(input_expected, input)
865
866 # name used for logging
867 log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template test.item. Using text input."""
868 self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
869 # severity ERROR = 40
870 self.assertEqual(self._caplog.record_tuples[0][1], 30,
871 msg="logging level != 30 (WARNING)")
872
873 """with self.assertRaises(ValueError) as e:
874 d.field(format="%Y-%m")
875 self.assertIn("'%Y-%m'", e.exception.args[0])
876 self.assertIn("'date'", e.exception.args[0])"""
877
878
879 # format matches rfc format, so this should pass
880 result = d.field(format="%Y-%m-%d")
881 input_expected = """<input id="test1@test" name="test1@test" size="30" type="date" value="2021-01-01 11:22:10">"""
882 self.assertEqual(result, input_expected)
883
884 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>"""
885 with self._caplog.at_level(logging.WARNING,
886 logger="roundup"):
887 input = d.field(format="%Y-%m", type="datetime-local")
888 self.assertEqual(input_expected, input)
889
890 # name used for logging
891 log_expected = """Format '%Y-%m' prevents use of modern date input. Remove format from field() call in template test.item. Using text input."""
892 self.assertEqual(self._caplog.record_tuples[0][2], log_expected)
893 # severity ERROR = 40
894 self.assertEqual(self._caplog.record_tuples[0][1], 30,
895 msg="logging level != 30 (WARNING)")
896
897 """
898 with self.assertRaises(ValueError) as e:
899 d.field(format="%Y-%m", type="datetime-local")
900 self.assertIn("'%Y-%m'", e.exception.args[0])
901 self.assertIn("'datetime-local'", e.exception.args[0])
902 """
903
904 # format matches rfc, so this should pass
905 result = d.field(type="datetime-local", format="%Y-%m-%dT%H:%M:%S")
906 input_expected = """<input id="test1@test" name="test1@test" size="30" type="datetime-local" value="2021-01-01 11:22:10">"""
907 self.assertEqual(result, input_expected)
753 908
754 # common markdown test cases 909 # common markdown test cases
755 class MarkdownTests: 910 class MarkdownTests:
756 def mangleMarkdown2(self, s): 911 def mangleMarkdown2(self, s):
757 ''' markdown2's rel=nofollow support on 'a' tags isn't programmable. 912 ''' markdown2's rel=nofollow support on 'a' tags isn't programmable.

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