diff --git a/hc/accounts/forms.py b/hc/accounts/forms.py index 88720a17..a93f3fa4 100644 --- a/hc/accounts/forms.py +++ b/hc/accounts/forms.py @@ -8,7 +8,7 @@ from django.contrib.auth import authenticate from django.contrib.auth.models import User from hc.accounts.models import REPORT_CHOICES from hc.api.models import TokenBucket -from hc.front.validators import TimezoneValidator +import pytz class LowercaseEmailField(forms.EmailField): @@ -88,7 +88,7 @@ class PasswordLoginForm(forms.Form): class ReportSettingsForm(forms.Form): reports = forms.ChoiceField(choices=REPORT_CHOICES) nag_period = forms.IntegerField(min_value=0, max_value=86400) - tz = forms.CharField(max_length=36, validators=[TimezoneValidator()]) + tz = forms.CharField() def clean_nag_period(self): seconds = self.cleaned_data["nag_period"] @@ -98,6 +98,15 @@ class ReportSettingsForm(forms.Form): return td(seconds=seconds) + def clean_tz(self): + # Declare tz as "clean" only if we can find it in pytz.all_timezones + if self.cleaned_data["tz"] in pytz.all_timezones: + return self.cleaned_data["tz"] + + # Otherwise, return None, and *don't* throw a validation exception: + # If user's browser reports a timezone we don't recognize, we + # should ignore the timezone but still save the rest of the form. + class SetPasswordForm(forms.Form): password = forms.CharField(min_length=8) diff --git a/hc/accounts/tests/test_notifications.py b/hc/accounts/tests/test_notifications.py index 3fc0939a..1d2fa137 100644 --- a/hc/accounts/tests/test_notifications.py +++ b/hc/accounts/tests/test_notifications.py @@ -95,3 +95,25 @@ class NotificationsTestCase(BaseTestCase): self.profile.refresh_from_db() self.assertEqual(self.profile.nag_period.total_seconds(), 3600) + + def test_it_saves_tz(self): + self.client.login(username="alice@example.org", password="password") + + r = self.client.post(self.url, self._payload()) + self.assertEqual(r.status_code, 200) + + self.profile.refresh_from_db() + self.assertEqual(self.profile.tz, "Europe/Riga") + + def test_it_ignores_bad_tz(self): + self.profile.tz = "Europe/Riga" + self.profile.save() + + self.client.login(username="alice@example.org", password="password") + + r = self.client.post(self.url, self._payload(reports="weekly", tz="Foo/Bar")) + self.assertEqual(r.status_code, 200) + + self.profile.refresh_from_db() + self.assertEqual(self.profile.reports, "weekly") + self.assertEqual(self.profile.tz, "Europe/Riga") diff --git a/hc/accounts/views.py b/hc/accounts/views.py index af1d5a1e..09c12058 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -446,8 +446,9 @@ def notifications(request): if request.method == "POST": form = forms.ReportSettingsForm(request.POST) if form.is_valid(): + if form.cleaned_data["tz"]: + profile.tz = form.cleaned_data["tz"] profile.reports = form.cleaned_data["reports"] - profile.tz = form.cleaned_data["tz"] profile.next_report_date = profile.choose_next_report_date() profile.reports_allowed = profile.reports != "off"