aboutsummaryrefslogtreecommitdiffstats
path: root/ctrack
diff options
context:
space:
mode:
authorMatthew Lemon <lemon@matthewlemon.com>2020-10-12 14:50:16 +0100
committerMatthew Lemon <lemon@matthewlemon.com>2020-10-12 14:50:16 +0100
commit0bd4f8e84e4d1788d6119a78823881a96c039427 (patch)
tree9cda64f75df57406c88ab79f4d5306862af8c901 /ctrack
parent3f818f99669ab0b49f98b7e7da43c38dc119bfd5 (diff)
more constraints added at form and model level
Diffstat (limited to 'ctrack')
-rw-r--r--ctrack/register/forms.py11
-rw-r--r--ctrack/register/models.py16
-rw-r--r--ctrack/register/tests/test_forms.py47
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()