Browse Source

Add Profile.reports field

This is in preparation of adding an option for weekly
reports (#407)
pull/522/head
Pēteris Caune 4 years ago
parent
commit
03a538c5e2
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
9 changed files with 76 additions and 22 deletions
  1. +2
    -2
      hc/accounts/admin.py
  2. +2
    -1
      hc/accounts/forms.py
  3. +18
    -0
      hc/accounts/migrations/0035_profile_reports.py
  4. +18
    -0
      hc/accounts/migrations/0036_fill_profile_reports.py
  5. +3
    -0
      hc/accounts/models.py
  6. +11
    -7
      hc/accounts/tests/test_notifications.py
  7. +1
    -0
      hc/accounts/tests/test_unsubscribe_reports.py
  8. +4
    -2
      hc/accounts/views.py
  9. +17
    -10
      templates/accounts/notifications.html

+ 2
- 2
hc/accounts/admin.py View File

@ -43,7 +43,7 @@ class ProfileFieldset(Fieldset):
name = "User Profile" name = "User Profile"
fields = ( fields = (
"email", "email",
"reports_allowed",
"reports",
"next_report_date", "next_report_date",
"nag_period", "nag_period",
"next_nag_date", "next_nag_date",
@ -109,7 +109,7 @@ class ProfileAdmin(admin.ModelAdmin):
"projects", "projects",
"invited", "invited",
"sms", "sms",
"reports_allowed",
"reports",
) )
list_filter = ( list_filter = (
"user__date_joined", "user__date_joined",


+ 2
- 1
hc/accounts/forms.py View File

@ -6,6 +6,7 @@ from django import forms
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.contrib.auth.models import User from django.contrib.auth.models import User
from hc.accounts.models import REPORT_CHOICES
from hc.api.models import TokenBucket from hc.api.models import TokenBucket
@ -84,7 +85,7 @@ class PasswordLoginForm(forms.Form):
class ReportSettingsForm(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) nag_period = forms.IntegerField(min_value=0, max_value=86400)
def clean_nag_period(self): def clean_nag_period(self):


+ 18
- 0
hc/accounts/migrations/0035_profile_reports.py View File

@ -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),
),
]

+ 18
- 0
hc/accounts/migrations/0036_fill_profile_reports.py View File

@ -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)]

+ 3
- 0
hc/accounts/models.py View File

@ -23,6 +23,8 @@ NAG_PERIODS = (
(timedelta(days=1), "Daily"), (timedelta(days=1), "Daily"),
) )
REPORT_CHOICES = (("off", "Off"), ("weekly", "Weekly"), ("monthly", "Monthly"))
def month(dt): def month(dt):
""" For a given datetime, return the matching first-day-of-month date. """ """ 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) user = models.OneToOneField(User, models.CASCADE, blank=True, null=True)
next_report_date = models.DateTimeField(null=True, blank=True) next_report_date = models.DateTimeField(null=True, blank=True)
reports_allowed = models.BooleanField(default=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) nag_period = models.DurationField(default=NO_NAG, choices=NAG_PERIODS)
next_nag_date = models.DateTimeField(null=True, blank=True) next_nag_date = models.DateTimeField(null=True, blank=True)
ping_log_limit = models.IntegerField(default=100) ping_log_limit = models.IntegerField(default=100)


+ 11
- 7
hc/accounts/tests/test_notifications.py View File

@ -6,33 +6,37 @@ from hc.test import BaseTestCase
class NotificationsTestCase(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.reports_allowed = False
self.profile.save() self.profile.save()
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
form = {"reports_allowed": "on", "nag_period": "0"}
form = {"reports": "monthly", "nag_period": "0"}
r = self.client.post("/accounts/profile/notifications/", form) r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
self.profile.refresh_from_db() self.profile.refresh_from_db()
self.assertTrue(self.profile.reports_allowed) self.assertTrue(self.profile.reports_allowed)
self.assertEqual(self.profile.reports, "monthly")
self.assertIsNotNone(self.profile.next_report_date) 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_allowed = True
self.profile.reports = "monthly"
self.profile.next_report_date = now() self.profile.next_report_date = now()
self.profile.save() self.profile.save()
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
form = {"nag_period": "0"}
form = {"reports": "off", "nag_period": "0"}
r = self.client.post("/accounts/profile/notifications/", form) r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
self.profile.refresh_from_db() self.profile.refresh_from_db()
self.assertFalse(self.profile.reports_allowed) self.assertFalse(self.profile.reports_allowed)
self.assertEqual(self.profile.reports, "off")
self.assertIsNone(self.profile.next_report_date) self.assertIsNone(self.profile.next_report_date)
def test_it_sets_next_nag_date_when_setting_hourly_nag_period(self): def test_it_sets_next_nag_date_when_setting_hourly_nag_period(self):
@ -40,7 +44,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
form = {"nag_period": "3600"}
form = {"reports": "off", "nag_period": "3600"}
r = self.client.post("/accounts/profile/notifications/", form) r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
@ -54,7 +58,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
form = {"nag_period": "3600"}
form = {"reports": "off", "nag_period": "3600"}
r = self.client.post("/accounts/profile/notifications/", form) r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)
@ -68,7 +72,7 @@ class NotificationsTestCase(BaseTestCase):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
form = {"nag_period": "1234"}
form = {"reports": "off", "nag_period": "1234"}
r = self.client.post("/accounts/profile/notifications/", form) r = self.client.post("/accounts/profile/notifications/", form)
self.assertEqual(r.status_code, 200) self.assertEqual(r.status_code, 200)


+ 1
- 0
hc/accounts/tests/test_unsubscribe_reports.py View File

@ -22,6 +22,7 @@ class UnsubscribeReportsTestCase(BaseTestCase):
self.profile.refresh_from_db() self.profile.refresh_from_db()
self.assertFalse(self.profile.reports_allowed) self.assertFalse(self.profile.reports_allowed)
self.assertEqual(self.profile.reports, "off")
self.assertIsNone(self.profile.next_report_date) self.assertIsNone(self.profile.next_report_date)
self.assertEqual(self.profile.nag_period.total_seconds(), 0) self.assertEqual(self.profile.nag_period.total_seconds(), 0)


+ 4
- 2
hc/accounts/views.py View File

@ -447,8 +447,9 @@ def notifications(request):
if request.method == "POST": if request.method == "POST":
form = forms.ReportSettingsForm(request.POST) form = forms.ReportSettingsForm(request.POST)
if form.is_valid(): 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: if profile.reports_allowed:
profile.next_report_date = choose_next_report_date() profile.next_report_date = choose_next_report_date()
else: else:
@ -542,6 +543,7 @@ def unsubscribe_reports(request, signed_username):
user = User.objects.get(username=username) user = User.objects.get(username=username)
profile = Profile.objects.for_user(user) profile = Profile.objects.for_user(user)
profile.reports = "off"
profile.reports_allowed = False profile.reports_allowed = False
profile.next_report_date = None profile.next_report_date = None
profile.nag_period = td() profile.nag_period = td()


+ 17
- 10
templates/accounts/notifications.html View File

@ -31,14 +31,24 @@
{% csrf_token %} {% csrf_token %}
<h2>Email Reports</h2> <h2>Email Reports</h2>
<p>Send me monthly emails about:</p>
<label class="checkbox-container">
<p>Send me periodic emails reports:</p>
<label class="radio-container">
<input
type="radio"
name="reports"
value="off"
{% if profile.reports == "off" %} checked {% endif %}>
<span class="radiomark"></span>
Do not send me email reports
</label>
<label class="radio-container">
<input <input
name="reports_allowed"
type="checkbox"
{% if profile.reports_allowed %} checked {% endif %}>
<span class="checkmark"></span>
The status of checks in all teams I belong to
type="radio"
name="reports"
value="monthly"
{% if profile.reports == "monthly" %} checked {% endif %}>
<span class="radiomark"></span>
Monthly on 1st of every month
</label> </label>
<br> <br>
@ -81,10 +91,7 @@
{% endif %} {% endif %}
</p> </p>
<br /> <br />
<button <button
name="update_reports_allowed"
type="submit" type="submit"
class="btn btn-default pull-right">Save Changes</button> class="btn btn-default pull-right">Save Changes</button>
</form> </form>


Loading…
Cancel
Save