new core.middleware sets cookie for scroll timestamp view to local browser time, w. new corresponding tests in core.tests.UTs.test_middleware; apps.lyric.templatetags.lyric_extras determines timestamp format based on duration elapsed since timestamp; apps.bill.tests.ITs.test_views renamed, now also asserts scroll renders event body and time in columns
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
29
src/core/middleware.py
Normal file
29
src/core/middleware.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import zoneinfo
|
||||
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
class TimezoneMiddleware:
|
||||
"""Activate the user's local timezone from the ``user_tz`` cookie.
|
||||
|
||||
The cookie is set client-side via ``Intl.DateTimeFormat().resolvedOptions().timeZone``
|
||||
on every page load, so it reflects the browser's OS timezone rather than
|
||||
the server's configured TIME_ZONE. Invalid or absent cookies fall back to
|
||||
Django's default (UTC).
|
||||
"""
|
||||
|
||||
def __init__(self, get_response):
|
||||
self.get_response = get_response
|
||||
|
||||
def __call__(self, request):
|
||||
tz_name = request.COOKIES.get("user_tz")
|
||||
if tz_name:
|
||||
try:
|
||||
timezone.activate(zoneinfo.ZoneInfo(tz_name))
|
||||
except (zoneinfo.ZoneInfoNotFoundError, KeyError):
|
||||
timezone.deactivate()
|
||||
else:
|
||||
timezone.deactivate()
|
||||
response = self.get_response(request)
|
||||
timezone.deactivate()
|
||||
return response
|
||||
@@ -79,6 +79,7 @@ MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'core.middleware.TimezoneMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.middleware.csrf.CsrfViewMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
|
||||
0
src/core/tests/__init__.py
Normal file
0
src/core/tests/__init__.py
Normal file
0
src/core/tests/unit/__init__.py
Normal file
0
src/core/tests/unit/__init__.py
Normal file
41
src/core/tests/unit/test_middleware.py
Normal file
41
src/core/tests/unit/test_middleware.py
Normal file
@@ -0,0 +1,41 @@
|
||||
from django.http import HttpResponse
|
||||
from django.test import RequestFactory, SimpleTestCase
|
||||
from django.utils import timezone
|
||||
|
||||
from core.middleware import TimezoneMiddleware
|
||||
|
||||
|
||||
class TimezoneMiddlewareTest(SimpleTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.factory = RequestFactory()
|
||||
self.middleware = TimezoneMiddleware(lambda r: HttpResponse())
|
||||
|
||||
def test_activates_valid_timezone_from_cookie(self):
|
||||
captured = {}
|
||||
|
||||
def get_response(request):
|
||||
captured["tz"] = str(timezone.get_current_timezone())
|
||||
return HttpResponse()
|
||||
|
||||
middleware = TimezoneMiddleware(get_response)
|
||||
request = self.factory.get("/")
|
||||
request.COOKIES["user_tz"] = "America/New_York"
|
||||
middleware(request)
|
||||
self.assertEqual(captured["tz"], "America/New_York")
|
||||
|
||||
def test_deactivates_after_response(self):
|
||||
# Timezone activation must not leak into subsequent requests
|
||||
request = self.factory.get("/")
|
||||
request.COOKIES["user_tz"] = "America/New_York"
|
||||
self.middleware(request)
|
||||
self.assertEqual(str(timezone.get_current_timezone()), "UTC")
|
||||
|
||||
def test_invalid_timezone_cookie_does_not_raise(self):
|
||||
request = self.factory.get("/")
|
||||
request.COOKIES["user_tz"] = "Not/ATimezone"
|
||||
self.middleware(request) # must not raise
|
||||
|
||||
def test_missing_cookie_does_not_raise(self):
|
||||
request = self.factory.get("/")
|
||||
self.middleware(request) # must not raise
|
||||
Reference in New Issue
Block a user