Merge pull request #10 from youngbob/duration-sanity-check

Add validation for model durations
This commit is contained in:
Christopher Charbonneau Wells 2017-11-01 13:08:47 -04:00 committed by GitHub
commit d6c6c8a271
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 0 deletions

View File

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

View File

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