From 60dc60234dc49f3df3edde2b5b2be33693d7b919 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Wed, 5 Jul 2023 10:23:37 -0300 Subject: [PATCH] fix: Better match xml2rfc date parsing (#5914) * refactor: Split up get_creation_date to ease testing * test: Add tests of parse_creation_date() Note change in expected output when date_elt is None: instead of returning None, this expects today's date. * fix: Return today instead of None when date is absent * fix: Handle empty string for day attribute * test: Check a couple more parse_creation_date cases * fix: Revert to returning None when date elt is absent * style: black --- ietf/utils/tests.py | 50 ++++++++++++++++++++++++++++++++++++++++++ ietf/utils/xmldraft.py | 37 +++++++++++++++++-------------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/ietf/utils/tests.py b/ietf/utils/tests.py index fe715b14d..499b87488 100644 --- a/ietf/utils/tests.py +++ b/ietf/utils/tests.py @@ -400,6 +400,56 @@ class XMLDraftTests(TestCase): } ) + def test_parse_creation_date(self): + # override date_today to avoid skew when test runs around midnight + today = datetime.date.today() + with patch("ietf.utils.xmldraft.date_today", return_value=today): + # Note: using a dict as a stand-in for XML elements, which rely on the get() method + self.assertEqual( + XMLDraft.parse_creation_date({"year": "2022", "month": "11", "day": "24"}), + datetime.date(2022, 11, 24), + "Fully specified date should be parsed", + ) + self.assertEqual( + XMLDraft.parse_creation_date(None), None, "return None if input is None" + ) + # Cases where the date is empty - missing fields or fields filled in with blank strings. + self.assertEqual(XMLDraft.parse_creation_date({}), today) + self.assertEqual(XMLDraft.parse_creation_date({"day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"month": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": "", "month": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"year": "", "day": ""}), today) + self.assertEqual(XMLDraft.parse_creation_date({"month": "", "day": ""}), today) + self.assertEqual( + XMLDraft.parse_creation_date({"year": "", "month": "", "day": ""}), today + ) + self.assertEqual( + XMLDraft.parse_creation_date( + {"year": str(today.year), "month": str(today.month), "day": ""} + ), + today, + ) + # When year/month do not match, day should be 15th of the month + self.assertEqual( + XMLDraft.parse_creation_date( + {"year": str(today.year - 1), "month": str(today.month), "day": ""} + ), + datetime.date(today.year - 1, today.month, 15), + ) + self.assertEqual( + XMLDraft.parse_creation_date( + { + "year": str(today.year), + "month": "1" if today.month != 1 else "2", + "day": "", + } + ), + datetime.date(today.year, 1 if today.month != 1 else 2, 15), + ) + class NameTests(TestCase): diff --git a/ietf/utils/xmldraft.py b/ietf/utils/xmldraft.py index bdd10f813..fab2a89b5 100644 --- a/ietf/utils/xmldraft.py +++ b/ietf/utils/xmldraft.py @@ -136,24 +136,27 @@ class XMLDraft(Draft): def get_title(self): return self.xmlroot.findtext('front/title').strip() + @staticmethod + def parse_creation_date(date_elt): + if date_elt is None: + return None + today = date_today() + # ths mimics handling of date elements in the xml2rfc text/html writers + year, month, day = extract_date(date_elt, today) + year, month, day = augment_date(year, month, day, today) + if not day: + # Must choose a day for a datetime.date. Per RFC 7991 sect 2.17, we use + # today's date if it is consistent with the rest of the date. Otherwise, + # arbitrariy (and consistent with the text parser) assume the 15th. + if year == today.year and month == today.month: + day = today.day + else: + day = 15 + return datetime.date(year, month, day) + def get_creation_date(self): - date_elt = self.xmlroot.find("front/date") - if date_elt is not None: - # ths mimics handling of date elements in the xml2rfc text/html writers - today = date_today() - year, month, day = extract_date(date_elt, today) - year, month, day = augment_date(year, month, day, today) - if day is None: - # Must choose a day for a datetime.date. Per RFC 7991 sect 2.17, we use - # today's date if it is consistent with the rest of the date. Otherwise, - # arbitrariy (and consistent with the text parser) assume the 15th. - if year == today.year and month == today.month: - day = today.day - else: - day = 15 - return datetime.date(year, month, day) - return None - + return self.parse_creation_date(self.xmlroot.find("front/date")) + # todo fix the implementation of XMLDraft.get_abstract() # # This code was pulled from ietf.submit.forms where it existed for some time.