diff options
author | Matthew Lemon <lemon@matthewlemon.com> | 2020-10-12 14:50:16 +0100 |
---|---|---|
committer | Matthew Lemon <lemon@matthewlemon.com> | 2020-10-12 14:50:16 +0100 |
commit | 0bd4f8e84e4d1788d6119a78823881a96c039427 (patch) | |
tree | 9cda64f75df57406c88ab79f4d5306862af8c901 /ctrack | |
parent | 3f818f99669ab0b49f98b7e7da43c38dc119bfd5 (diff) |
more constraints added at form and model level
Diffstat (limited to 'ctrack')
-rw-r--r-- | ctrack/register/forms.py | 11 | ||||
-rw-r--r-- | ctrack/register/models.py | 16 | ||||
-rw-r--r-- | ctrack/register/tests/test_forms.py | 47 |
3 files changed, 72 insertions, 2 deletions
diff --git a/ctrack/register/forms.py b/ctrack/register/forms.py index 1d46c36..1c69bcd 100644 --- a/ctrack/register/forms.py +++ b/ctrack/register/forms.py @@ -1,6 +1,7 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Button, ButtonHolder, Layout, Submit, Hidden, Field from django import forms +from django.core.exceptions import ValidationError from django.shortcuts import get_object_or_404 from django.urls import reverse @@ -60,6 +61,16 @@ class CAFSingleDateEventForm(forms.ModelForm): class CAFTwinDateEventForm(forms.ModelForm): + # This constraint in the form prevents two such objects being created + # for the same CAF with the same start date, which does not make sense. + def clean_start_date(self): + data = self.cleaned_data["start_date"] + caf = self.cleaned_data["related_caf"] + existing_obj = CAFTwinDateEvent.objects.filter(start_date=data).filter(related_caf=caf).first() + if existing_obj: + raise ValidationError("You cannot have two CAF events starting on the same date.") + return data + class Meta: model = CAFTwinDateEvent fields = [ diff --git a/ctrack/register/models.py b/ctrack/register/models.py index 9e0516e..03a7d80 100644 --- a/ctrack/register/models.py +++ b/ctrack/register/models.py @@ -5,7 +5,7 @@ from typing import Optional, Dict from django.contrib.auth import get_user_model from django.db import models -from django.db.models import Q +from django.db.models import Q, F from ctrack.caf.models import CAF from ctrack.organisations.models import Person @@ -170,10 +170,22 @@ class CAFTwinDateEvent(EventBase, CAFMixin, TwinDateMixin): blank=False, max_length=50, choices=AVAILABLE_TYPES ) + def __repr__(self): + return "".join(["CAFTwinDateEvent(", self.type_descriptor, ")"]) -# OLD CODE BELOW + def __str__(self): + return f"CAFTwinDateEvent({self.type_descriptor}) starting {self.start_date}" + + class Meta: + constraints = [ + models.CheckConstraint( + name="end_date_cannot_precede_start_date", + check=~Q(end_date__lt=F("start_date")), + ) + ] +# OLD CODE BELOW class EngagementType(models.Model): """ Examples here are Phone, Email, Letter, Site visit, Meeting, Audit, Inspection, etc. diff --git a/ctrack/register/tests/test_forms.py b/ctrack/register/tests/test_forms.py index f1b8630..401ed2f 100644 --- a/ctrack/register/tests/test_forms.py +++ b/ctrack/register/tests/test_forms.py @@ -154,3 +154,50 @@ def test_caf_twin_date_event(user, caf): user=user, ) assert form.is_valid() + + +@pytest.mark.parametrize("allowed_type", ["CAF_PEER_REVIEW_PERIOD", "CAF_VALIDATION_PERIOD"]) +def test_cannot_create_twin_date_event_for_caf_whose_end_date_is_open(allowed_type, user, caf): + e1 = CAFTwinDateEventForm( + { + "type_descriptor": allowed_type, + "related_caf": caf, + "short_description": "caf peer review for x company", + "start_date": "2020-10-10", + "comments": "nice comments for this event", + }, + user=user, + ) + e2 = CAFTwinDateEventForm( + { + "type_descriptor": allowed_type, + "related_caf": caf, + "short_description": "caf peer review for x company", + "start_date": "2020-10-10", + "comments": "nice comments for this event", + }, + user=user, + ) + assert e1.is_valid() + e1.save() + assert e2.is_valid() is False + assert e2.errors == { + "start_date": ["You cannot have two CAF events starting on the same date."] + } + + +@pytest.mark.parametrize("allowed_type", ["CAF_PEER_REVIEW_PERIOD", "CAF_VALIDATION_PERIOD"]) +def test_cannot_create_twin_date_event_where_end_date_precedes_start(allowed_type, user, caf): + "This one is done with a database integrity check instead of a form validation" + with pytest.raises(IntegrityError): + CAFTwinDateEventForm( + { + "type_descriptor": allowed_type, + "related_caf": caf, + "short_description": "caf peer review for x company", + "start_date": "2020-10-10", + "end_date": "2020-10-09", + "comments": "nice comments for this event", + }, + user=user, + ).save() |