From 03a538c5e233e73a8f684108706b44c99c31c00d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C4=93teris=20Caune?=
Date: Mon, 24 May 2021 11:20:28 +0300
Subject: [PATCH] Add Profile.reports field
This is in preparation of adding an option for weekly
reports (#407)
---
hc/accounts/admin.py | 4 +--
hc/accounts/forms.py | 3 ++-
.../migrations/0035_profile_reports.py | 18 +++++++++++++
.../migrations/0036_fill_profile_reports.py | 18 +++++++++++++
hc/accounts/models.py | 3 +++
hc/accounts/tests/test_notifications.py | 18 ++++++++-----
hc/accounts/tests/test_unsubscribe_reports.py | 1 +
hc/accounts/views.py | 6 +++--
templates/accounts/notifications.html | 27 ++++++++++++-------
9 files changed, 76 insertions(+), 22 deletions(-)
create mode 100644 hc/accounts/migrations/0035_profile_reports.py
create mode 100644 hc/accounts/migrations/0036_fill_profile_reports.py
diff --git a/hc/accounts/admin.py b/hc/accounts/admin.py
index ed082a41..02db5c7c 100644
--- a/hc/accounts/admin.py
+++ b/hc/accounts/admin.py
@@ -43,7 +43,7 @@ class ProfileFieldset(Fieldset):
name = "User Profile"
fields = (
"email",
- "reports_allowed",
+ "reports",
"next_report_date",
"nag_period",
"next_nag_date",
@@ -109,7 +109,7 @@ class ProfileAdmin(admin.ModelAdmin):
"projects",
"invited",
"sms",
- "reports_allowed",
+ "reports",
)
list_filter = (
"user__date_joined",
diff --git a/hc/accounts/forms.py b/hc/accounts/forms.py
index 4f7bb2b2..6f714c0b 100644
--- a/hc/accounts/forms.py
+++ b/hc/accounts/forms.py
@@ -6,6 +6,7 @@ from django import forms
from django.core.exceptions import ValidationError
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
@@ -84,7 +85,7 @@ class PasswordLoginForm(forms.Form):
class ReportSettingsForm(forms.Form):
- reports_allowed = forms.BooleanField(required=False)
+ reports = forms.ChoiceField(choices=REPORT_CHOICES)
nag_period = forms.IntegerField(min_value=0, max_value=86400)
def clean_nag_period(self):
diff --git a/hc/accounts/migrations/0035_profile_reports.py b/hc/accounts/migrations/0035_profile_reports.py
new file mode 100644
index 00000000..da5bc70a
--- /dev/null
+++ b/hc/accounts/migrations/0035_profile_reports.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.2 on 2021-05-24 07:38
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('accounts', '0034_credential'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='profile',
+ name='reports',
+ field=models.CharField(choices=[('off', 'Off'), ('weekly', 'Weekly'), ('monthly', 'Monthly')], default='monthly', max_length=10),
+ ),
+ ]
diff --git a/hc/accounts/migrations/0036_fill_profile_reports.py b/hc/accounts/migrations/0036_fill_profile_reports.py
new file mode 100644
index 00000000..adf081ae
--- /dev/null
+++ b/hc/accounts/migrations/0036_fill_profile_reports.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.2 on 2021-05-24 07:38
+
+from django.db import migrations
+
+
+def fill_reports_field(apps, schema_editor):
+ Profile = apps.get_model("accounts", "Profile")
+ Profile.objects.filter(reports_allowed=False).update(reports="off")
+ Profile.objects.filter(reports_allowed=True).update(reports="monthly")
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("accounts", "0035_profile_reports"),
+ ]
+
+ operations = [migrations.RunPython(fill_reports_field, migrations.RunPython.noop)]
diff --git a/hc/accounts/models.py b/hc/accounts/models.py
index cf84abf9..f3c36ee8 100644
--- a/hc/accounts/models.py
+++ b/hc/accounts/models.py
@@ -23,6 +23,8 @@ NAG_PERIODS = (
(timedelta(days=1), "Daily"),
)
+REPORT_CHOICES = (("off", "Off"), ("weekly", "Weekly"), ("monthly", "Monthly"))
+
def month(dt):
""" For a given datetime, return the matching first-day-of-month date. """
@@ -50,6 +52,7 @@ class Profile(models.Model):
user = models.OneToOneField(User, models.CASCADE, blank=True, null=True)
next_report_date = models.DateTimeField(null=True, blank=True)
reports_allowed = models.BooleanField(default=True)
+ reports = models.CharField(max_length=10, default="monthly", choices=REPORT_CHOICES)
nag_period = models.DurationField(default=NO_NAG, choices=NAG_PERIODS)
next_nag_date = models.DateTimeField(null=True, blank=True)
ping_log_limit = models.IntegerField(default=100)
diff --git a/hc/accounts/tests/test_notifications.py b/hc/accounts/tests/test_notifications.py
index 194ce51f..e68f89da 100644
--- a/hc/accounts/tests/test_notifications.py
+++ b/hc/accounts/tests/test_notifications.py
@@ -6,33 +6,37 @@ from hc.test import BaseTestCase
class NotificationsTestCase(BaseTestCase):
- def test_it_saves_reports_allowed_true(self):
+ def test_it_saves_reports_monthly(self):
+ self.profile.reports = "off"
self.profile.reports_allowed = False
self.profile.save()
self.client.login(username="alice@example.org", password="password")
- form = {"reports_allowed": "on", "nag_period": "0"}
+ form = {"reports": "monthly", "nag_period": "0"}
r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200)
self.profile.refresh_from_db()
self.assertTrue(self.profile.reports_allowed)
+ self.assertEqual(self.profile.reports, "monthly")
self.assertIsNotNone(self.profile.next_report_date)
- def test_it_saves_reports_allowed_false(self):
+ def test_it_saves_reports_off(self):
self.profile.reports_allowed = True
+ self.profile.reports = "monthly"
self.profile.next_report_date = now()
self.profile.save()
self.client.login(username="alice@example.org", password="password")
- form = {"nag_period": "0"}
+ form = {"reports": "off", "nag_period": "0"}
r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200)
self.profile.refresh_from_db()
self.assertFalse(self.profile.reports_allowed)
+ self.assertEqual(self.profile.reports, "off")
self.assertIsNone(self.profile.next_report_date)
def test_it_sets_next_nag_date_when_setting_hourly_nag_period(self):
@@ -40,7 +44,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="alice@example.org", password="password")
- form = {"nag_period": "3600"}
+ form = {"reports": "off", "nag_period": "3600"}
r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200)
@@ -54,7 +58,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="alice@example.org", password="password")
- form = {"nag_period": "3600"}
+ form = {"reports": "off", "nag_period": "3600"}
r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200)
@@ -68,7 +72,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="alice@example.org", password="password")
- form = {"nag_period": "1234"}
+ form = {"reports": "off", "nag_period": "1234"}
r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200)
diff --git a/hc/accounts/tests/test_unsubscribe_reports.py b/hc/accounts/tests/test_unsubscribe_reports.py
index 4b43de84..4e976109 100644
--- a/hc/accounts/tests/test_unsubscribe_reports.py
+++ b/hc/accounts/tests/test_unsubscribe_reports.py
@@ -22,6 +22,7 @@ class UnsubscribeReportsTestCase(BaseTestCase):
self.profile.refresh_from_db()
self.assertFalse(self.profile.reports_allowed)
+ self.assertEqual(self.profile.reports, "off")
self.assertIsNone(self.profile.next_report_date)
self.assertEqual(self.profile.nag_period.total_seconds(), 0)
diff --git a/hc/accounts/views.py b/hc/accounts/views.py
index b77a2ed9..d7b2daf6 100644
--- a/hc/accounts/views.py
+++ b/hc/accounts/views.py
@@ -447,8 +447,9 @@ def notifications(request):
if request.method == "POST":
form = forms.ReportSettingsForm(request.POST)
if form.is_valid():
- if profile.reports_allowed != form.cleaned_data["reports_allowed"]:
- profile.reports_allowed = form.cleaned_data["reports_allowed"]
+ if profile.reports != form.cleaned_data["reports"]:
+ profile.reports = form.cleaned_data["reports"]
+ profile.reports_allowed = profile.reports == "monthly"
if profile.reports_allowed:
profile.next_report_date = choose_next_report_date()
else:
@@ -542,6 +543,7 @@ def unsubscribe_reports(request, signed_username):
user = User.objects.get(username=username)
profile = Profile.objects.for_user(user)
+ profile.reports = "off"
profile.reports_allowed = False
profile.next_report_date = None
profile.nag_period = td()
diff --git a/templates/accounts/notifications.html b/templates/accounts/notifications.html
index e05b0f43..51a70228 100644
--- a/templates/accounts/notifications.html
+++ b/templates/accounts/notifications.html
@@ -31,14 +31,24 @@
{% csrf_token %}
Email Reports
- Send me monthly emails about:
-
-
-