diff --git a/RIGS/hs.py b/RIGS/hs.py index 31343c6e..e3eff98d 100644 --- a/RIGS/hs.py +++ b/RIGS/hs.py @@ -176,7 +176,7 @@ class EventChecklistList(generic.ListView): class EventChecklistReview(generic.View): def get(self, *args, **kwargs): rpk = kwargs.get('pk') - ec = models.RiskAssessment.objects.get(pk=rpk) + ec = models.EventChecklist.objects.get(pk=rpk) with reversion.create_revision(): reversion.set_user(self.request.user) ec.reviewed_by = self.request.user diff --git a/RIGS/models.py b/RIGS/models.py index 89ac54e9..fa984276 100644 --- a/RIGS/models.py +++ b/RIGS/models.py @@ -640,14 +640,14 @@ class RiskAssessment(models.Model, RevisionMixin): ('review_riskassessment', 'Can review Risk Assessments') ] - def clean(self): + """def clean(self): errdict = {} for field in RiskAssessment._meta.fields: if field.__class__ == forms.BooleanField and self.field is None: errdict[field.name] = ["This field is required"] if errdict != {}: # If there was an error when validation - raise ValidationError(errdict) + raise ValidationError(errdict)""" @property def activity_feed_string(self): diff --git a/RIGS/tests/pages.py b/RIGS/tests/pages.py index 39593ef0..e9fc39aa 100644 --- a/RIGS/tests/pages.py +++ b/RIGS/tests/pages.py @@ -250,11 +250,31 @@ class CreateEventChecklist(FormPage): 'supply_test': (regions.CheckBox, (By.ID, 'id_supply_test')), 'earthing': (regions.CheckBox, (By.ID, 'id_earthing')), 'pat': (regions.CheckBox, (By.ID, 'id_pat')), + 'earthing_m': (regions.CheckBox, (By.XPATH, '(//*[@id="id_earthing"])[2]')), + 'pat_m': (regions.CheckBox, (By.XPATH, '(//*[@id="id_pat"])[2]')), + 'source_rcd': (regions.CheckBox, (By.ID, 'id_source_rcd')), + 'labelling': (regions.CheckBox, (By.ID, 'id_labelling')), + 'fd_voltage_l1': (regions.TextBox, (By.ID, 'id_fd_voltage_l1')), + 'fd_voltage_l2': (regions.TextBox, (By.ID, 'id_fd_voltage_l2')), + 'fd_voltage_l3': (regions.TextBox, (By.ID, 'id_fd_voltage_l3')), + 'fd_phase_rotation': (regions.CheckBox, (By.ID, 'id_fd_phase_rotation')), + 'fd_earth_fault': (regions.TextBox, (By.ID, 'id_fd_earth_fault')), + 'fd_pssc': (regions.TextBox, (By.ID, 'id_fd_pssc')), + 'w1_description': (regions.TextBox, (By.ID, 'id_w1_description')), + 'w1_polarity': (regions.CheckBox, (By.ID, 'id_w1_polarity')), + 'w1_voltage': (regions.TextBox, (By.ID, 'id_w1_voltage')), + 'w1_earth_fault': (regions.TextBox, (By.ID, 'id_w1_earth_fault')), } def select_size(self, size): self.find_element(By.XPATH, '//button[.="{}"]'.format(size)).click() + def add_vehicle(self): + self.find_element(*self._add_vehicle_locator).click() + + def add_crew(self): + self.find_element(*self._add_crew_locator).click() + @property def power_mic(self): return regions.BootstrapSelectElement(self, self.find_element(*self._power_mic_selector)) diff --git a/RIGS/tests/test_functional.py b/RIGS/tests/test_functional.py index f083d762..c2cad4cc 100644 --- a/RIGS/tests/test_functional.py +++ b/RIGS/tests/test_functional.py @@ -13,6 +13,7 @@ from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import WebDriverWait from PyRIGS.tests.base import animation_is_finished from PyRIGS.tests import base +from PyRIGS.tests import regions as base_regions from RIGS.tests import regions import datetime from datetime import date, time, timedelta @@ -974,6 +975,8 @@ class TestHealthAndSafety(BaseRigboardTest): self.page.select_size('Small') self.wait.until(animation_is_finished()) + self.assertFalse(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[2]').is_displayed()) + self.assertTrue(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[1]').is_displayed()) self.page.earthing = True self.page.rcds = True self.page.supply_test = True @@ -981,3 +984,97 @@ class TestHealthAndSafety(BaseRigboardTest): self.page.submit() self.assertTrue(self.page.success) + + def test_ec_create_medium(self): + self.page = pages.CreateEventChecklist(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + + self.page.safe_parking = True + self.page.safe_packing = True + self.page.exits = True + self.page.trip_hazard = True + self.page.warning_signs = True + self.page.ear_plugs = True + self.page.hs_location = "Death Valley" + self.page.extinguishers_location = "With the rest of the fire" + # If we do this first the search fails, for ... reasons + self.page.power_mic.search(self.profile.name) + self.page.power_mic.toggle() + self.assertFalse(self.page.power_mic.is_open) + + self.page.select_size('Medium') + self.wait.until(animation_is_finished()) + self.assertFalse(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[1]').is_displayed()) + self.assertTrue(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[2]').is_displayed()) + self.page.earthing_m = True + self.page.pat_m = True + self.page.source_rcd = True + self.page.labelling = True + self.page.fd_voltage_l1 = 240 + self.page.fd_voltage_l2 = 235 + self.page.fd_voltage_l3 = 0 + self.page.fd_phase_rotation = True + self.page.fd_earth_fault = 666 + self.page.fd_pssc = 1984 + self.page.w1_description = "In the carpark, by the bins" + self.page.w1_polarity = True + self.page.w1_voltage = 240 + self.page.w1_earth_fault = 333 + + self.page.submit() + self.assertTrue(self.page.success) + + def test_ec_create_extras(self): + self.page = pages.CreateEventChecklist(self.driver, self.live_server_url, event_id=self.testEvent.pk).open() + self.page.add_vehicle() + self.page.add_crew() + + self.page.safe_parking = True + self.page.safe_packing = True + self.page.exits = True + self.page.trip_hazard = True + self.page.warning_signs = True + self.page.ear_plugs = True + self.page.hs_location = "The Moon" + self.page.extinguishers_location = "With the rest of the fire" + # If we do this first the search fails, for ... reasons + self.page.power_mic.search(self.profile.name) + self.page.power_mic.toggle() + self.assertFalse(self.page.power_mic.is_open) + + vehicle_name = 'Brian' + self.driver.find_element(By.XPATH, '//*[@name="vehicle_-1"]').send_keys(vehicle_name) + driver = base_regions.BootstrapSelectElement(self.page, self.driver.find_element(By.XPATH, '(//*[contains(@class,"bootstrap-select")])[2]')) + driver.search(self.profile.name) + driver.toggle() + + crew = self.profile + role = "MIC" + crew_select = base_regions.BootstrapSelectElement(self.page, self.driver.find_element(By.XPATH, '(//*[contains(@class,"bootstrap-select")])[3]')) + start_time = base_regions.DateTimePicker(self.page, self.driver.find_element(By.XPATH, '//*[@name="start_-1"]')) + end_time = base_regions.DateTimePicker(self.page, self.driver.find_element(By.XPATH, '//*[@name="end_-1"]')) + + start_time.set_value(datetime.datetime(2015, 1, 1, 9, 0)) + # TODO Validation of end before start + end_time.set_value(datetime.datetime(2015, 1, 1, 10, 30)) + crew_select.search(crew.name) + crew_select.toggle() + self.driver.find_element(By.XPATH, '//*[@name="role_-1"]').send_keys(role) + + self.page.select_size('Small') + self.wait.until(animation_is_finished()) + self.assertFalse(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[2]').is_displayed()) + self.assertTrue(self.driver.find_element(By.XPATH, '(//*[@id="id_earthing"])[1]').is_displayed()) + self.page.earthing = True + self.page.rcds = True + self.page.supply_test = True + self.page.pat = True + + self.page.submit() + self.assertTrue(self.page.success) + + checklist = models.EventChecklist.objects.get(event=self.testEvent.pk) + vehicle = models.EventChecklistVehicle.objects.get(checklist=checklist.pk) + self.assertEqual(vehicle_name, vehicle.vehicle) + crew_obj = models.EventChecklistCrew.objects.get(checklist=checklist.pk) + self.assertEqual(crew.pk, crew_obj.crewmember.pk) + self.assertEqual(role, crew_obj.role) diff --git a/RIGS/tests/test_unit.py b/RIGS/tests/test_unit.py index 5049ed38..5204aaa1 100644 --- a/RIGS/tests/test_unit.py +++ b/RIGS/tests/test_unit.py @@ -5,6 +5,7 @@ from django.core.management import call_command from django.urls import reverse from django.test import TestCase from django.test.utils import override_settings +from django.utils import timezone from RIGS import models from reversion import revisions as reversion @@ -455,3 +456,105 @@ class TestSearchLogic(TestCase): response = self.client.get(request_url, follow=True) self.assertContains(response, self.venues[1].address) self.assertNotContains(response, self.venues[2].address) + + +class TestHSLogic(TestCase): + @classmethod + def setUpTestData(cls): + cls.profile = models.Profile.objects.create(username="testuser1", email="1@test.com", is_superuser=True, + is_active=True, is_staff=True) + + cls.vatrate = models.VatRate.objects.create(start_at='2014-03-05', rate=0.20, comment='test1') + + cls.events = { + 1: models.Event.objects.create(name="TE E1", start_date=date.today(), + description="This is an event description\nthat for a very specific reason spans two lines."), + 2: models.Event.objects.create(name="TE E2", start_date=date.today()), + } + + cls.ras = { + 1: models.RiskAssessment.objects.create(event=cls.events[1], + nonstandard_equipment=False, + nonstandard_use=False, + contractors=False, + other_companies=False, + crew_fatigue=False, + big_power=False, + power_mic=cls.profile, + generators=False, + other_companies_power=False, + nonstandard_equipment_power=False, + multiple_electrical_environments=False, + noise_monitoring=False, + known_venue=True, + safe_loading=True, + safe_storage=True, + area_outside_of_control=True, + barrier_required=True, + nonstandard_emergency_procedure=True, + special_structures=False, + suspended_structures=False), + } + + cls.checklists = { + 1: models.EventChecklist.objects.create(event=cls.events[1], + power_mic=cls.profile, + safe_parking=False, + safe_packing=False, + exits=False, + trip_hazard=False, + warning_signs=False, + ear_plugs=False, + hs_location="Locked away safely", + extinguishers_location="Somewhere, I forgot", + earthing=False, + pat=False, + medium_event=False + ), + } + + def setUp(self): + self.profile.set_password('testuser') + self.profile.save() + self.assertTrue(self.client.login(username=self.profile.username, password='testuser')) + + def test_list(self): + request_url = reverse('hs_list') + response = self.client.get(request_url, follow=True) + self.assertContains(response, self.events[1].name) + self.assertContains(response, self.events[2].name) + self.assertContains(response, 'Create') + + def test_ra_review(self): + request_url = reverse('ra_review', kwargs={'pk': self.ras[1].pk}) + response = self.client.get(request_url, follow=True) + self.assertContains(response, 'Reviewed by') + self.assertContains(response, self.profile.name) + ra = models.RiskAssessment.objects.get(event=self.events[1]) + self.assertEqual(timezone.now().date(), ra.reviewed_at.date()) + self.assertEqual(timezone.now().hour, ra.reviewed_at.hour) + self.assertEqual(timezone.now().minute, ra.reviewed_at.minute) + + def test_checklist_review(self): + request_url = reverse('ec_review', kwargs={'pk': self.checklists[1].pk}) + response = self.client.get(request_url, follow=True) + self.assertContains(response, 'Reviewed by') + self.assertContains(response, self.profile.name) + checklist = models.EventChecklist.objects.get(event=self.events[1]) + self.assertEqual(timezone.now().date(), checklist.reviewed_at.date()) + self.assertEqual(timezone.now().hour, checklist.reviewed_at.hour) + self.assertEqual(timezone.now().minute, checklist.reviewed_at.minute) + + def test_ra_redirect(self): + request_url = reverse('event_ra', kwargs={'pk': self.events[1].pk}) + expected_url = reverse('ra_edit', kwargs={'pk': self.ras[1].pk}) + + response = self.client.get(request_url, follow=True) + self.assertRedirects(response, expected_url, status_code=302, target_status_code=200) + + def test_checklist_redirect(self): + request_url = reverse('event_ec', kwargs={'pk': self.events[1].pk}) + expected_url = reverse('ec_edit', kwargs={'pk': self.checklists[1].pk}) + + response = self.client.get(request_url, follow=True) + self.assertRedirects(response, expected_url, status_code=302, target_status_code=200) diff --git a/RIGS/urls.py b/RIGS/urls.py index a03425a6..e86dc56a 100644 --- a/RIGS/urls.py +++ b/RIGS/urls.py @@ -81,7 +81,8 @@ urlpatterns = [ name='ra_edit'), path('event/ra/list', permission_required_with_403('RIGS.view_riskassessment')(hs.EventRiskAssessmentList.as_view()), name='ra_list'), - path('event/ra//review/', permission_required_with_403('RIGS.review_riskassessment')(hs.EventRiskAssessmentReview.as_view()), name='ra_review'), + path('event/ra//review/', permission_required_with_403('RIGS.review_riskassessment')(hs.EventRiskAssessmentReview.as_view()), + name='ra_review'), path('event//checklist/', permission_required_with_403('RIGS.add_eventchecklist')(hs.EventChecklistCreate.as_view()), name='event_ec'), @@ -91,7 +92,8 @@ urlpatterns = [ name='ec_edit'), path('event/checklist/list', permission_required_with_403('RIGS.view_eventchecklist')(hs.EventChecklistList.as_view()), name='ec_list'), - path('event/checklist//review/', permission_required_with_403('RIGS.review_eventchecklist')(hs.EventChecklistReview.as_view()), name='ec_review'), + path('event/checklist//review/', permission_required_with_403('RIGS.review_eventchecklist')(hs.EventChecklistReview.as_view()), + name='ec_review'), # Finance path('invoice/', permission_required_with_403('RIGS.view_invoice')(finance.InvoiceIndex.as_view()),