From 6862bb572155c672ee9be5343b813c5c7cace185 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 29 Jun 2015 22:16:50 +0100 Subject: [PATCH 1/2] Added start/end date validation for events --- RIGS/models.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/RIGS/models.py b/RIGS/models.py index 6c4c9c9c..75e641ec 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -10,6 +10,7 @@ import reversion import string import random from django.core.urlresolvers import reverse_lazy +from django.core.exceptions import ValidationError from decimal import Decimal @@ -348,6 +349,20 @@ class Event(models.Model, RevisionMixin): def __str__(self): return str(self.pk) + ": " + self.name + def clean(self): + if self.end_date and self.start_date > self.end_date: + raise ValidationError('Unless you\'ve invented time travel, the event can\'t finish before it has started.') + + startEndSameDay = not self.end_date or self.end_date == self.start_date + hasStartAndEnd = self.has_start_time and self.has_end_time + if startEndSameDay and hasStartAndEnd and self.start_time > self.end_time: + raise ValidationError('Unless you\'ve invented time travel, the event can\'t finish before it has started.') + + def save(self, *args, **kwargs): + """Call :meth:`full_clean` before saving.""" + self.full_clean() + super(Event, self).save(*args, **kwargs) + class Meta: permissions = ( ('view_event', 'Can view Events'), From f08d7ed430884099abdc006b182dd625de09c401 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Mon, 20 Jul 2015 22:52:08 +0100 Subject: [PATCH 2/2] Added functional test for date validation --- RIGS/test_functional.py | 115 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/RIGS/test_functional.py b/RIGS/test_functional.py index c9b5c906..6ccb743f 100644 --- a/RIGS/test_functional.py +++ b/RIGS/test_functional.py @@ -412,6 +412,121 @@ class EventTest(LiveServerTestCase): event = models.Event.objects.get(name='Test Event Name') self.assertIn("N0000%d | Test Event Name"%event.pk, self.browser.find_element_by_xpath('//h1').text) + def testDateValidation(self): + self.browser.get(self.live_server_url + '/event/create/') + # Gets redirected to login and back + self.authenticate('/event/create/') + + wait = WebDriverWait(self.browser, 10) #setup WebDriverWait to use later (to wait for animations) + self.browser.implicitly_wait(3) #Set session-long wait (only works for non-existant DOM objects) + + wait.until(animation_is_finished()) + + # Click Rig button + self.browser.find_element_by_xpath('//button[.="Rig"]').click() + + form = self.browser.find_element_by_tag_name('form') + save = self.browser.find_element_by_xpath('(//button[@type="submit"])[3]') + + # Set title + e = self.browser.find_element_by_id('id_name') + e.send_keys('Test Event Name') + + # Both dates, no times, end before start + form.find_element_by_id('id_start_date').clear() + form.find_element_by_id('id_start_date').send_keys('3015-04-24') + + form.find_element_by_id('id_end_date').clear() + form.find_element_by_id('id_end_date').send_keys('3015-04-23') + + # Attempt to save - should fail + save.click() + error = self.browser.find_element_by_xpath('//div[contains(@class, "alert-danger")]') + self.assertTrue(error.is_displayed()) + self.assertIn("can't finish before it has started", error.find_element_by_xpath('//dd[1]/ul/li').text) + + + # Same date, end time before start time + form = self.browser.find_element_by_tag_name('form') + save = self.browser.find_element_by_xpath('(//button[@type="submit"])[3]') + form.find_element_by_id('id_start_date').clear() + form.find_element_by_id('id_start_date').send_keys('3015-04-24') + + form.find_element_by_id('id_end_date').clear() + form.find_element_by_id('id_end_date').send_keys('3015-04-23') + + form.find_element_by_id('id_start_time').clear() + form.find_element_by_id('id_start_time').send_keys('06:59') + + form.find_element_by_id('id_end_time').clear() + form.find_element_by_id('id_end_time').send_keys('06:00') + + # Attempt to save - should fail + save.click() + error = self.browser.find_element_by_xpath('//div[contains(@class, "alert-danger")]') + self.assertTrue(error.is_displayed()) + self.assertIn("can't finish before it has started", error.find_element_by_xpath('//dd[1]/ul/li').text) + + + # Same date, end time before start time + form = self.browser.find_element_by_tag_name('form') + save = self.browser.find_element_by_xpath('(//button[@type="submit"])[3]') + form.find_element_by_id('id_start_date').clear() + form.find_element_by_id('id_start_date').send_keys('3015-04-24') + + form.find_element_by_id('id_end_date').clear() + form.find_element_by_id('id_end_date').send_keys('3015-04-23') + + form.find_element_by_id('id_start_time').clear() + form.find_element_by_id('id_start_time').send_keys('06:59') + + form.find_element_by_id('id_end_time').clear() + form.find_element_by_id('id_end_time').send_keys('06:00') + + + # No end date, end time before start time + form = self.browser.find_element_by_tag_name('form') + save = self.browser.find_element_by_xpath('(//button[@type="submit"])[3]') + form.find_element_by_id('id_start_date').clear() + form.find_element_by_id('id_start_date').send_keys('3015-04-24') + + form.find_element_by_id('id_end_date').clear() + + form.find_element_by_id('id_start_time').clear() + form.find_element_by_id('id_start_time').send_keys('06:59') + + form.find_element_by_id('id_end_time').clear() + form.find_element_by_id('id_end_time').send_keys('06:00') + + # Attempt to save - should fail + save.click() + error = self.browser.find_element_by_xpath('//div[contains(@class, "alert-danger")]') + self.assertTrue(error.is_displayed()) + self.assertIn("can't finish before it has started", error.find_element_by_xpath('//dd[1]/ul/li').text) + + + # 2 dates, end after start + form = self.browser.find_element_by_tag_name('form') + save = self.browser.find_element_by_xpath('(//button[@type="submit"])[3]') + form.find_element_by_id('id_start_date').clear() + form.find_element_by_id('id_start_date').send_keys('3015-04-24') + + form.find_element_by_id('id_end_date').clear() + form.find_element_by_id('id_end_date').send_keys('3015-04-26') + + form.find_element_by_id('id_start_time').clear() + + form.find_element_by_id('id_end_time').clear() + + # Attempt to save - should succeed + save.click() + + # See redirected to success page + event = models.Event.objects.get(name='Test Event Name') + self.assertIn("N0000%d | Test Event Name"%event.pk, self.browser.find_element_by_xpath('//h1').text) + + + def testEventDetail(self): with transaction.atomic(), reversion.create_revision(): person = models.Person(name="Event Detail Person", email="eventdetail@person.tests.rigs", phone="123 123")