Refs #34986 -- Fixed mocking in utils_tests.test_http.HttpDateProcessingTests.test_parsing_rfc850.

Mocking in the `datetime` module can be tricky. In CPython the datetime
C module is used, but PyPy uses a pure Python implementation. This
caused issues with the prior approach to mocking `datetime.datetime`.

See https://docs.python.org/3/library/unittest.mock-examples.html#partial-mocking
This commit is contained in:
Nick Pope 2023-11-21 17:13:08 +00:00 committed by Mariusz Felisiak
parent 0fcd72bc48
commit 6089230d3e
2 changed files with 4 additions and 6 deletions

View File

@ -1,8 +1,8 @@
import base64 import base64
import datetime
import re import re
import unicodedata import unicodedata
from binascii import Error as BinasciiError from binascii import Error as BinasciiError
from datetime import datetime, timezone
from email.utils import formatdate from email.utils import formatdate
from urllib.parse import quote, unquote from urllib.parse import quote, unquote
from urllib.parse import urlencode as original_urlencode from urllib.parse import urlencode as original_urlencode
@ -113,10 +113,9 @@ def parse_http_date(date):
else: else:
raise ValueError("%r is not in a valid HTTP date format" % date) raise ValueError("%r is not in a valid HTTP date format" % date)
try: try:
tz = datetime.timezone.utc
year = int(m["year"]) year = int(m["year"])
if year < 100: if year < 100:
current_year = datetime.datetime.now(tz=tz).year current_year = datetime.now(tz=timezone.utc).year
current_century = current_year - (current_year % 100) current_century = current_year - (current_year % 100)
if year - (current_year % 100) > 50: if year - (current_year % 100) > 50:
# year that appears to be more than 50 years in the future are # year that appears to be more than 50 years in the future are
@ -129,7 +128,7 @@ def parse_http_date(date):
hour = int(m["hour"]) hour = int(m["hour"])
min = int(m["min"]) min = int(m["min"])
sec = int(m["sec"]) sec = int(m["sec"])
result = datetime.datetime(year, month, day, hour, min, sec, tzinfo=tz) result = datetime(year, month, day, hour, min, sec, tzinfo=timezone.utc)
return int(result.timestamp()) return int(result.timestamp())
except Exception as exc: except Exception as exc:
raise ValueError("%r is not a valid date" % date) from exc raise ValueError("%r is not a valid date" % date) from exc

View File

@ -334,10 +334,9 @@ class HttpDateProcessingTests(unittest.TestCase):
) )
@unittest.skipIf(platform.architecture()[0] == "32bit", "The Year 2038 problem.") @unittest.skipIf(platform.architecture()[0] == "32bit", "The Year 2038 problem.")
@mock.patch("django.utils.http.datetime.datetime") @mock.patch("django.utils.http.datetime")
def test_parsing_rfc850(self, mocked_datetime): def test_parsing_rfc850(self, mocked_datetime):
mocked_datetime.side_effect = datetime mocked_datetime.side_effect = datetime
mocked_datetime.now = mock.Mock()
now_1 = datetime(2019, 11, 6, 8, 49, 37, tzinfo=timezone.utc) now_1 = datetime(2019, 11, 6, 8, 49, 37, tzinfo=timezone.utc)
now_2 = datetime(2020, 11, 6, 8, 49, 37, tzinfo=timezone.utc) now_2 = datetime(2020, 11, 6, 8, 49, 37, tzinfo=timezone.utc)
now_3 = datetime(2048, 11, 6, 8, 49, 37, tzinfo=timezone.utc) now_3 = datetime(2048, 11, 6, 8, 49, 37, tzinfo=timezone.utc)