diff --git a/core/forms.py b/core/forms.py index 998d5ff0..a59445ca 100644 --- a/core/forms.py +++ b/core/forms.py @@ -59,7 +59,8 @@ class ChildDeleteForm(forms.ModelForm): def clean_confirm_name(self): confirm_name = self.cleaned_data['confirm_name'] if confirm_name != str(self.instance): - raise forms.ValidationError('Name does not match child name.') + raise forms.ValidationError( + 'Name does not match child name.', code='confirm_mismatch') return confirm_name def save(self, commit=True): @@ -83,31 +84,6 @@ class DiaperChangeForm(forms.ModelForm): kwargs = set_default_child(kwargs) super(DiaperChangeForm, self).__init__(*args, **kwargs) - def clean(self): - """Additional form validation/cleaning. - """ - errors = {} - - # One or both of Wet and Solid is required. - if not self.cleaned_data['wet'] and not self.cleaned_data['solid']: - errors['wet'] = forms.ValidationError( - 'Wet and/or solid is required.', - code='missing-wet-or-solid') - errors['solid'] = forms.ValidationError( - 'Wet and/or solid is required.', - code='missing-wet-or-solid') - - # Color is required when Solid is selected. - if self.cleaned_data['solid'] and not self.cleaned_data['color']: - errors['color'] = forms.ValidationError( - 'Color is required for solid changes.', - code='missing-color') - - if len(errors) > 0: - raise forms.ValidationError(errors) - - return self.cleaned_data - class FeedingForm(forms.ModelForm): class Meta: @@ -130,23 +106,6 @@ class FeedingForm(forms.ModelForm): kwargs = set_default_duration(kwargs) super(FeedingForm, self).__init__(*args, **kwargs) - def clean(self): - """Additional form validation/cleaning. - """ - errors = {} - - # "Formula" Type may only be associated with "Bottle" Method. - if (self.cleaned_data['type'] == 'formula' - and self.cleaned_data['method'] != 'bottle'): - errors['method'] = forms.ValidationError( - 'Only "Bottle" method is allowed with type "Formula".', - code='bottle-formula-mismatch') - - if len(errors) > 0: - raise forms.ValidationError(errors) - - return self.cleaned_data - def save(self, commit=True): instance = super(FeedingForm, self).save(commit=False) if self.timer_id: diff --git a/core/models.py b/core/models.py index fb4aa809..af691e17 100644 --- a/core/models.py +++ b/core/models.py @@ -19,10 +19,14 @@ def validate_duration(model, max_duration=timedelta(hours=24)): """ if model.start and model.end: if model.start > model.end: - raise ValidationError('Start time must come before end time') + raise ValidationError( + 'Start time must come before end time.', + code='end_before_start') if model.end - model.start > max_duration: - raise ValidationError('Duration too long (%(timesince)s)', params={ - 'timesince': timesince(model.start, model.end)}) + raise ValidationError( + 'Duration too long (%(timesince)s).', + params={'timesince': timesince(model.start, model.end)}, + code='max_duration') class Child(models.Model): @@ -85,6 +89,18 @@ class DiaperChange(models.Model): attributes.append(self.color) return attributes + def clean(self): + # One or both of Wet and Solid is required. + if not self.wet and not self.solid: + raise ValidationError( + 'Wet and/or solid is required.', code='wet_or_solid') + + # Color is required when Solid is selected. + if self.solid and not self.color: + raise ValidationError( + {'color': 'Color is required for solid diaper changes.'}, + code='solid_color_required') + class Feeding(models.Model): model_name = 'feeding' @@ -120,6 +136,13 @@ class Feeding(models.Model): def clean(self): validate_duration(self) + # "Formula" Type may only be associated with "Bottle" Method. + if self.type == 'formula'and self.method != 'bottle': + raise ValidationError( + {'method': + 'Only "Bottle" method is allowed with "Formula" type.'}, + code='bottle_formula_mismatch') + class Note(models.Model): model_name = 'note' diff --git a/core/tests/tests_forms.py b/core/tests/tests_forms.py index cdff19f4..309670d3 100644 --- a/core/tests/tests_forms.py +++ b/core/tests/tests_forms.py @@ -33,25 +33,54 @@ class FormsTestCase(TestCase): cls.c.login(**cls.credentials) def test_child_forms(self): - entry = models.Child.objects.first() - page = self.c.post('/children/{}/edit/'.format(entry.slug), { + params = { 'first_name': 'Child', 'last_name': 'One', 'birth_date': '2000-01-01' - }) + } + + entry = models.Child.objects.first() + page = self.c.post('/children/{}/edit/'.format(entry.slug), params) + self.assertEqual(page.status_code, 302) + entry.refresh_from_db() + + params = {'confirm_name': 'Incorrect'} + page = self.c.post('/children/{}/delete/'.format(entry.slug), params) + self.assertEqual(page.status_code, 200) + self.assertFormError(page, 'form', 'confirm_name', + 'Name does not match child name.') + + params['confirm_name'] = str(entry) + page = self.c.post('/children/{}/delete/'.format(entry.slug), params) self.assertEqual(page.status_code, 302) def test_diaperchange_forms(self): - entry = models.DiaperChange.objects.first() - page = self.c.post('/changes/{}/'.format(entry.id), { + params = { 'child': 1, 'time': '2000-01-01 1:01', 'wet': 1, 'solid': 1, 'color': 'black' - }) + } + + entry = models.DiaperChange.objects.first() + page = self.c.post('/changes/{}/'.format(entry.id), params) self.assertEqual(page.status_code, 302) + params['solid'] = 0 + params['color'] = '' + page = self.c.post('/changes/{}/'.format(entry.id), params) + self.assertEqual(page.status_code, 200) + self.assertFormError(page, 'form', 'color', + 'Color is required for solid diaper changes.') + + del params['solid'] + del params['wet'] + page = self.c.post('/changes/{}/'.format(entry.id), params) + self.assertEqual(page.status_code, 200) + self.assertFormError(page, 'form', None, + 'Wet and/or solid is required.') + def test_feeding_forms(self): entry = models.Feeding.objects.first() params = { @@ -75,7 +104,15 @@ class FormsTestCase(TestCase): 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') + 'Start time must come before end time.') + + params['start'] = '2000-01-01 1:01' + params['method'] = 'left breast' + page = self.c.post('/feedings/{}/'.format(entry.id), params) + self.assertEqual(page.status_code, 200) + self.assertFormError( + page, 'form', 'method', + 'Only "Bottle" method is allowed with "Formula" type.') def test_sleeping_forms(self): params = { @@ -97,7 +134,7 @@ class FormsTestCase(TestCase): 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') + 'Start time must come before end time.') def test_timer_forms(self): timer = models.Timer.objects.create(user=self.user) @@ -143,4 +180,4 @@ class FormsTestCase(TestCase): 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') + 'Start time must come before end time.')