mirror of https://github.com/snachodog/mybuddy.git
Add validation for model durations
It was previously possible to accidentally enter obviously wrong values for start/end dates. Add some basic validation to catch input errors when creating or editing various models (when not using a timer).
This commit is contained in:
parent
40f8a511ba
commit
1eeba2398d
|
@ -1,9 +1,28 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.template.defaultfilters import slugify
|
from django.template.defaultfilters import slugify
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.timesince import timesince
|
||||||
|
|
||||||
|
|
||||||
|
def validate_duration(model, max_duration=timedelta(hours=24)):
|
||||||
|
"""
|
||||||
|
Basic sanity checks for models with a duration
|
||||||
|
:param model: a model instance with 'start' and 'end' attributes
|
||||||
|
:param max_duration: maximum allowed duration between start and end time
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if model.start and model.end:
|
||||||
|
if model.start > model.end:
|
||||||
|
raise ValidationError('Start time must come before end time')
|
||||||
|
if model.end - model.start > max_duration:
|
||||||
|
raise ValidationError('Duration too long (%(timesince)s)', params={
|
||||||
|
'timesince': timesince(model.start, model.end)})
|
||||||
|
|
||||||
|
|
||||||
class Child(models.Model):
|
class Child(models.Model):
|
||||||
|
@ -98,6 +117,9 @@ class Feeding(models.Model):
|
||||||
self.duration = self.end - self.start
|
self.duration = self.end - self.start
|
||||||
super(Feeding, self).save(*args, **kwargs)
|
super(Feeding, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
validate_duration(self)
|
||||||
|
|
||||||
|
|
||||||
class Note(models.Model):
|
class Note(models.Model):
|
||||||
model_name = 'note'
|
model_name = 'note'
|
||||||
|
@ -137,6 +159,9 @@ class Sleep(models.Model):
|
||||||
self.duration = self.end - self.start
|
self.duration = self.end - self.start
|
||||||
super(Sleep, self).save(*args, **kwargs)
|
super(Sleep, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
validate_duration(self)
|
||||||
|
|
||||||
|
|
||||||
class Timer(models.Model):
|
class Timer(models.Model):
|
||||||
model_name = 'timer'
|
model_name = 'timer'
|
||||||
|
@ -191,6 +216,9 @@ class Timer(models.Model):
|
||||||
self.duration = None
|
self.duration = None
|
||||||
super(Timer, self).save(*args, **kwargs)
|
super(Timer, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
validate_duration(self)
|
||||||
|
|
||||||
|
|
||||||
class TummyTime(models.Model):
|
class TummyTime(models.Model):
|
||||||
model_name = 'tummytime'
|
model_name = 'tummytime'
|
||||||
|
@ -213,3 +241,6 @@ class TummyTime(models.Model):
|
||||||
if self.start and self.end:
|
if self.start and self.end:
|
||||||
self.duration = self.end - self.start
|
self.duration = self.end - self.start
|
||||||
super(TummyTime, self).save(*args, **kwargs)
|
super(TummyTime, self).save(*args, **kwargs)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
validate_duration(self)
|
||||||
|
|
|
@ -71,6 +71,12 @@ class FormsTestCase(TestCase):
|
||||||
page = self.c.post('/feedings/{}/'.format(entry.id), params)
|
page = self.c.post('/feedings/{}/'.format(entry.id), params)
|
||||||
self.assertEqual(page.status_code, 302)
|
self.assertEqual(page.status_code, 302)
|
||||||
|
|
||||||
|
params['start'] = '2001-01-01 1:01'
|
||||||
|
page = self.c.post('/feedings/{}/'.format(entry.id), params)
|
||||||
|
self.assertEqual(page.status_code, 200)
|
||||||
|
self.assertFormError(page, 'form', None,
|
||||||
|
'Start time must come before end time')
|
||||||
|
|
||||||
def test_sleeping_forms(self):
|
def test_sleeping_forms(self):
|
||||||
params = {
|
params = {
|
||||||
'child': 1,
|
'child': 1,
|
||||||
|
@ -87,6 +93,12 @@ class FormsTestCase(TestCase):
|
||||||
page = self.c.post('/sleep/{}/'.format(entry.id), params)
|
page = self.c.post('/sleep/{}/'.format(entry.id), params)
|
||||||
self.assertEqual(page.status_code, 302)
|
self.assertEqual(page.status_code, 302)
|
||||||
|
|
||||||
|
params['start'] = '2001-01-01 1:01'
|
||||||
|
page = self.c.post('/sleep/{}/'.format(entry.id), params)
|
||||||
|
self.assertEqual(page.status_code, 200)
|
||||||
|
self.assertFormError(page, 'form', None,
|
||||||
|
'Start time must come before end time')
|
||||||
|
|
||||||
def test_timer_forms(self):
|
def test_timer_forms(self):
|
||||||
timer = models.Timer.objects.create(user=self.user)
|
timer = models.Timer.objects.create(user=self.user)
|
||||||
timer.save()
|
timer.save()
|
||||||
|
@ -126,3 +138,9 @@ class FormsTestCase(TestCase):
|
||||||
entry = models.TummyTime.objects.first()
|
entry = models.TummyTime.objects.first()
|
||||||
page = self.c.post('/tummy-time/{}/'.format(entry.id), params)
|
page = self.c.post('/tummy-time/{}/'.format(entry.id), params)
|
||||||
self.assertEqual(page.status_code, 302)
|
self.assertEqual(page.status_code, 302)
|
||||||
|
|
||||||
|
params['start'] = '2001-01-01 1:01'
|
||||||
|
page = self.c.post('/tummy-time/{}/'.format(entry.id), params)
|
||||||
|
self.assertEqual(page.status_code, 200)
|
||||||
|
self.assertFormError(page, 'form', None,
|
||||||
|
'Start time must come before end time')
|
||||||
|
|
Loading…
Reference in New Issue