From 8abb6d749e18dd203c716b439aeede2ac7def23d Mon Sep 17 00:00:00 2001 From: "Christopher C. Wells" Date: Sun, 4 Jun 2023 17:39:08 -0700 Subject: [PATCH] Enforce min and max nap start parameters Fixes #644 --- babybuddy/site_settings.py | 13 +++++++++++-- core/fields.py | 31 +++++++++++++++++++++++++++++++ core/tests/tests_forms.py | 18 ++++++------------ core/tests/tests_models.py | 18 +++++------------- 4 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 core/fields.py diff --git a/babybuddy/site_settings.py b/babybuddy/site_settings.py index 92a58bdf..1b37d76d 100644 --- a/babybuddy/site_settings.py +++ b/babybuddy/site_settings.py @@ -5,11 +5,20 @@ from django.utils.translation import gettext_lazy as _ import dbsettings +from core.fields import NapStartMaxTimeField, NapStartMinTimeField from .widgets import TimeInput +class NapStartMaxTimeValue(dbsettings.TimeValue): + field = NapStartMaxTimeField + + +class NapStartMinTimeValue(dbsettings.TimeValue): + field = NapStartMinTimeField + + class NapSettings(dbsettings.Group): - nap_start_min = dbsettings.TimeValue( + nap_start_min = NapStartMinTimeValue( default=time(6), description=_("Default minimum nap start time"), help_text=_( @@ -18,7 +27,7 @@ class NapSettings(dbsettings.Group): ), widget=TimeInput, ) - nap_start_max = dbsettings.TimeValue( + nap_start_max = NapStartMaxTimeValue( default=time(18), description=_("Default maximum nap start time"), help_text=_( diff --git a/core/fields.py b/core/fields.py new file mode 100644 index 00000000..2f28d513 --- /dev/null +++ b/core/fields.py @@ -0,0 +1,31 @@ +# -*- coding: utf-8 -*- +from django import forms +from django.utils.translation import gettext as _ + + +class NapStartMaxTimeField(forms.TimeField): + def validate(self, value): + from core.models import Sleep + + if value < Sleep.settings.nap_start_min: + raise forms.ValidationError( + _( + "Nap start max. value %(max)s must be greater than nap start min. value %(min)s." + ), + code="invalid_nap_start_max", + params={"max": value, "min": Sleep.settings.nap_start_min}, + ) + + +class NapStartMinTimeField(forms.TimeField): + def validate(self, value): + from core.models import Sleep + + if value > Sleep.settings.nap_start_max: + raise forms.ValidationError( + _( + "Nap start min. value %(min)s must be less than nap start min. value %(max)s." + ), + code="invalid_nap_start_min", + params={"min": value, "max": Sleep.settings.nap_start_max}, + ) diff --git a/core/tests/tests_forms.py b/core/tests/tests_forms.py index 4105494b..9545a8dd 100644 --- a/core/tests/tests_forms.py +++ b/core/tests/tests_forms.py @@ -1,4 +1,6 @@ # -*- coding: utf-8 -*- +import datetime + from django.contrib.auth import get_user_model from django.core.management import call_command from django.test import TestCase @@ -546,22 +548,14 @@ class SleepFormsTestCase(FormsTestCaseBase): self.assertContains(page, "Sleep entry deleted") def test_nap_default(self): - models.Sleep.settings.nap_start_min = ( - timezone.now() - timezone.timedelta(hours=1) - ).time() - models.Sleep.settings.nap_start_max = ( - timezone.now() + timezone.timedelta(hours=1) - ).time() + models.Sleep.settings.nap_start_min = datetime.time(0, 0, 0) + models.Sleep.settings.nap_start_max = datetime.time(23, 59, 59) response = self.c.get("/sleep/add/") self.assertTrue(response.context["form"].initial["nap"]) def test_not_nap_default(self): - models.Sleep.settings.nap_start_min = ( - timezone.now() + timezone.timedelta(hours=1) - ).time() - models.Sleep.settings.nap_start_max = ( - timezone.now() + timezone.timedelta(hours=2) - ).time() + models.Sleep.settings.nap_start_min = datetime.time(0, 0, 0) + models.Sleep.settings.nap_start_max = datetime.time(0, 0, 0) response = self.c.get("/sleep/add/") self.assertFalse(response.context["form"].initial["nap"]) diff --git a/core/tests/tests_models.py b/core/tests/tests_models.py index d4116c8c..16961a9f 100644 --- a/core/tests/tests_models.py +++ b/core/tests/tests_models.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from datetime import datetime +import datetime from django.contrib.auth import get_user_model from django.core.management import call_command @@ -213,12 +213,8 @@ class SleepTestCase(TestCase): self.assertEqual(sleep.duration, sleep.end - sleep.start) def test_sleep_nap(self): - models.Sleep.settings.nap_start_min = ( - timezone.now() - timezone.timedelta(hours=1) - ).time() - models.Sleep.settings.nap_start_max = ( - timezone.now() + timezone.timedelta(hours=1) - ).time() + models.Sleep.settings.nap_start_min = datetime.time(0, 0, 0) + models.Sleep.settings.nap_start_max = datetime.time(23, 59, 59) sleep = models.Sleep.objects.create( child=self.child, start=timezone.now(), @@ -227,12 +223,8 @@ class SleepTestCase(TestCase): self.assertTrue(sleep.nap) def test_sleep_not_nap(self): - models.Sleep.settings.nap_start_min = ( - timezone.now() + timezone.timedelta(hours=1) - ).time() - models.Sleep.settings.nap_start_max = ( - timezone.now() + timezone.timedelta(hours=2) - ).time() + models.Sleep.settings.nap_start_min = datetime.time(0, 0, 0) + models.Sleep.settings.nap_start_max = datetime.time(0, 0, 0) sleep = models.Sleep.objects.create( child=self.child, start=timezone.now(),