Mercurial > p > roundup > code
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;property=deadline&amp;form=itemSynopsis&date=2021-01-01.11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'issue?@template=calendar&property=deadline&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;property=test&amp;form=itemSynopsis&date=2021-01-01 11:22:10" data-height="200" data-width="300" href="javascript:help_window('test?@template=calendar&property=test&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;property=test&amp;form=itemSynopsis&date=2021-01-01 11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'test?@template=calendar&property=test&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;property=test&amp;form=itemSynopsis&date=2021-01-01 11:22:10" data-height="200" data-width="300" href="javascript:help_window(\'test?@template=calendar&property=test&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. |
