diff options
Diffstat (limited to 'engagements/tests')
-rw-r--r-- | engagements/tests/conftest.py | 68 | ||||
-rw-r--r-- | engagements/tests/test_forms.py | 168 | ||||
-rw-r--r-- | engagements/tests/test_models.py | 65 | ||||
-rw-r--r-- | engagements/tests/test_views.py | 177 |
4 files changed, 330 insertions, 148 deletions
diff --git a/engagements/tests/conftest.py b/engagements/tests/conftest.py new file mode 100644 index 0000000..7ccb9ad --- /dev/null +++ b/engagements/tests/conftest.py @@ -0,0 +1,68 @@ +from datetime import date + +import pytest + +from engagements.models import Engagement, EngagementStrategy, EngagementType, Organisation, RegulatoryCycle +from myuser.models import TeamUser + + +@pytest.fixture +def regulatory_cycles(): + RegulatoryCycle.objects.create(start_date="2024-01-01", end_date="2024-12-31") + RegulatoryCycle.objects.create(start_date="2023-01-01", end_date="2023-12-31") + RegulatoryCycle.objects.create(start_date="2022-01-01", end_date="2022-12-31") + + +@pytest.fixture +def org(): + return Organisation.objects.create(name="MOD", is_regulated_entity=False) + + +@pytest.fixture +def engagement_strategy(regulatory_cycles, org, user): + es = EngagementStrategy.objects.create( + description="ES1 description", + start_year=RegulatoryCycle.objects.get(start_date="2022-01-01"), + end_year=RegulatoryCycle.objects.get(start_date="2024-01-01"), + organisation=org, + owned_by=user, + reviewed_by=user, + management_sign_off="2022-02-10", + inspector_sign_off="2022-01-10", + status="DRAFT", + ) + + +@pytest.fixture +def engagement(): + data = { + "proposed_start_date": "2022-10-01", + "engagement_type": EngagementType.objects.create(name="ET1"), + "external_party": Organisation.objects.create(name="O1"), + } + return Engagement.objects.create(**data) + + +@pytest.fixture +def user(): + return TeamUser.objects.create_user(email="ming@ming.com") + + +@pytest.fixture +def engagement_type(): + return EngagementType.objects.create(name="ET2") + + +@pytest.fixture +def external_party(): + return Organisation.objects.create(name="O2") + + +@pytest.fixture +def user1(): + return TeamUser.objects.create_user(email="user1@example.com") + + +@pytest.fixture +def user2(): + return TeamUser.objects.create_user(email="user2@example.com") diff --git a/engagements/tests/test_forms.py b/engagements/tests/test_forms.py index b6aab9a..851f986 100644 --- a/engagements/tests/test_forms.py +++ b/engagements/tests/test_forms.py @@ -1,45 +1,131 @@ -from django.test import TestCase +import pytest +from django.forms import DateInput, Select, SelectMultiple -from engagements.forms import EngagementEffortCreateForm -from engagements.models import Engagement, EngagementType, Organisation -from myuser.models import TeamUser +from engagements.forms import EngagementCreateForm, EngagementEffortCreateForm, EngagementStrategyCreateForm +from engagements.models import EngagementType, RegulatoryCycle +pytestmark = pytest.mark.django_db -class EngagementEffortCreate(TestCase): - def setUp(self): - data = { - "proposed_start_date": "2022-10-01", - "engagement_type": EngagementType.objects.create(name="ET1"), - "external_party": Organisation.objects.create(name="O1"), + +def test_basic_validation(engagement, user): + form = EngagementEffortCreateForm( + data={ + "is_planned": True, + "proposed_start_date": "2022-10-10 10:00", + "proposed_end_date": "2022-10-10 12:00", + "engagement": engagement, + "effort_type": "PLANNING", + "officers": [user], + } + ) + assert not form.errors + + +def test_basic_validation_on_bad_entry(engagement, user): + form = EngagementEffortCreateForm( + data={ + "is_planned": True, + "proposed_start_date": "20240-10-10 10:00", + "proposed_end_date": "2022-10-10 12:00", + "engagement": engagement, + "effort_type": "bobbins", + "officers": [user], + "sub_instruments": [""], } - self.e = Engagement.objects.create(**data) - self.user = TeamUser.objects.create_user(email="ming@ming.com") - - def test_basic_validation(self): - form = EngagementEffortCreateForm( - data={ - "is_planned": True, - "proposed_start_date": "2022-10-10 10:00", - "proposed_end_date": "2022-10-10 12:00", - "engagement": self.e, - "effort_type": "PLANNING", - "officers": [self.user], - } - ) - self.assertFalse(form.errors) - - def test_basic_validation_on_bad_entry(self): - form = EngagementEffortCreateForm( - data={ - "is_planned": True, - "proposed_start_date": "20240-10-10 10:00", - "proposed_end_date": "2022-10-10 12:00", - "engagement": self.e, - "effort_type": "bobbins", - "officers": [self.user], - "sub_instruments": [""], - } - ) - self.assertTrue(form.errors["effort_type"]) - self.assertTrue(form.errors["proposed_start_date"]) - self.assertTrue(form.errors["sub_instruments"]) + ) + assert "effort_type" in form.errors + assert "proposed_start_date" in form.errors + + +def test_form_fields(): + form = EngagementCreateForm() + expected_fields = [ + "proposed_start_date", + "proposed_end_date", + "engagement_type", + "external_party", + "officers", + ] + assert list(form.fields.keys()) == expected_fields + + +def test_form_labels(): + form = EngagementCreateForm() + assert form.fields["officers"].label == "Inspectors" + + +def test_form_help_texts(): + form = EngagementCreateForm() + assert form.fields["proposed_start_date"].help_text == "<small><em>YYYY-MM-DD</em></small>" + assert form.fields["proposed_end_date"].help_text == "<small><em>YYYY-MM-DD</em></small>" + + +def test_form_widgets(): + form = EngagementCreateForm() + assert isinstance(form.fields["proposed_start_date"].widget, DateInput) + assert isinstance(form.fields["proposed_end_date"].widget, DateInput) + assert isinstance(form.fields["engagement_type"].widget, Select) + assert isinstance(form.fields["officers"].widget, SelectMultiple) + + +def test_form_valid_data(engagement_type, external_party, user1, user2): + form_data = { + "proposed_start_date": "2023-01-01", + "proposed_end_date": "2023-01-31", + "engagement_type": engagement_type.id, + "external_party": external_party.id, + "officers": [user1.id, user2.id], + } + form = EngagementCreateForm(data=form_data) + assert form.is_valid() + + +def test_form_invalid_dates(engagement_type, external_party, user1): + form_data = { + "proposed_start_date": "2023-01-31", + "proposed_end_date": "2023-01-01", + "engagement_type": engagement_type.id, + "external_party": external_party.id, + "officers": [user1.id], + } + form = EngagementCreateForm(data=form_data) + assert not form.is_valid() + + +def test_form_missing_required_fields(): + form_data = { + "proposed_start_date": "2023-01-01", + } + form = EngagementCreateForm(data=form_data) + assert not form.is_valid() + assert "engagement_type" in form.errors + assert "external_party" in form.errors + + +def test_form_engagement_type_queryset(engagement_type): + initial_data = {"engagement_type": EngagementType.objects.all()} + form = EngagementCreateForm(initial=initial_data) + assert form.fields["engagement_type"].queryset.first().name == initial_data["engagement_type"].first().name + + +def test_form_engagement_type_queryset_without_initial(): + form = EngagementCreateForm() + assert list(form.fields["engagement_type"].queryset) == list(EngagementType.objects.all()) + + +def test_create_engagement_strategy_form(org, user, regulatory_cycles): + sy = RegulatoryCycle.objects.get(start_date="2022-01-01") + ey = RegulatoryCycle.objects.get(start_date="2024-01-01") + form_data = { + "organisation": org, + "start_year": sy, + "end_year": ey, + "description": "Example description", + "inspector_sign_off": "2022-01-10", + "owned_by": user, + "reviewed_by": user, + "management_sign_off": "2022-02-10", + "status": "DRAFT", + } + form = EngagementStrategyCreateForm(data=form_data) + assert form.is_valid() diff --git a/engagements/tests/test_models.py b/engagements/tests/test_models.py index 08c5169..70ae31a 100644 --- a/engagements/tests/test_models.py +++ b/engagements/tests/test_models.py @@ -1,30 +1,45 @@ import pytest -from django.test import TestCase +from engagements.models import EngagementStrategy, RegulatoryCycle from engagements.utils import populate_database +pytestmark = pytest.mark.django_db -class TestModels(TestCase): - @classmethod - def setUpTestData(cls): - cls.data = populate_database() - - @pytest.mark.django_db - def test_check_all_dcs(self): - dscs = self.data.get("sub_instruments") - self.assertEqual(dscs[0].title, "DSC 1 - Title 1") - - @pytest.mark.django_db - def test_effort_by_type(self): - e = self.data["engagements"][0] - total_planning = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="PLANNING")]) - total_travel = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="TRAVEL")]) - total_regulation = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="REGULATION")]) - assert total_planning == 4.25 - assert total_regulation == 0 - assert total_travel == 1 - - # TODO finish this test! - def test_total_effort_for_engagement(self): - e = self.data["engagements"][0] - assert e.total_effort() == 5.25 + +@pytest.fixture +def data(): + return populate_database() + + +def test_check_all_dcs(data): + dscs = data.get("sub_instruments") + assert dscs[0].title == "DSC 1 - Title 1" + + +def test_effort_by_type(data): + e = data["engagements"][0] + total_planning = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="PLANNING")]) + total_travel = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="TRAVEL")]) + total_regulation = sum([x.effort_total_planned_hours() for x in e.effort.filter(effort_type="REGULATION")]) + assert total_planning == 4.25 + assert total_regulation == 0 + assert total_travel == 1 + + +@pytest.mark.skip(reason="Not implemented until I get my head round effort calculations") +def test_total_effort_for_engagement(data): + e = data["engagements"][0] + assert e.total_effort() == 5.25 + + +def test_regulatory_cycle_model(regulatory_cycles): + rc = RegulatoryCycle.objects.first() + rc2023 = RegulatoryCycle.objects.get(start_date="2023-01-01") + assert str(rc) == "Regulatory Cycle: 2024" + assert str(rc2023) == "Regulatory Cycle: 2023" + + +def test_engagement_strategy_model(engagement_strategy): + es1 = EngagementStrategy.objects.first() + assert es1.organisation.name == "MOD" + assert str(es1) == "Engagement Strategy (2022-2024) - MOD" diff --git a/engagements/tests/test_views.py b/engagements/tests/test_views.py index f25eb3a..017b96f 100644 --- a/engagements/tests/test_views.py +++ b/engagements/tests/test_views.py @@ -1,91 +1,104 @@ import datetime from http import HTTPStatus -from django.test import RequestFactory, TestCase +import pytest +from django.test import RequestFactory from django.urls import reverse from engagements import models, views +from engagements.models import EngagementStrategy, RegulatoryCycle, Organisation from engagements.utils import populate_database +pytestmark = pytest.mark.django_db -class TestModels(TestCase): - @classmethod - def setUpTestData(cls): - cls.request = RequestFactory() # for use in _ep_request_factory test - cls.data = populate_database() - - def test_dscs_for_ep(self): - org = self.data["orgs"][0] - # we set up an engagement and effort for this org - et = models.EngagementType.objects.get(name="INSPECTION") - si = self.data["sub_instruments"][0] - si2 = self.data["sub_instruments"][2] - si3 = self.data["sub_instruments"][3] - # si_not = self.data["sub_instruments"][1] - engagement = models.Engagement.objects.create( - proposed_start_date=datetime.date(2022, 10, 10), - proposed_end_date=datetime.date(2022, 10, 10), - engagement_type=et, - external_party=org, - ) - ef1 = models.EngagementEffort.objects.create( - is_planned=True, - effort_type="REGULATION", - proposed_start_date=datetime.date(2022, 10, 10), - proposed_end_date=datetime.date(2022, 10, 10), - engagement=engagement, - ) - ef1.sub_instruments.add(si) # DSC 1 - ef1.sub_instruments.add(si2) # DSC 3 - ef1.sub_instruments.add(si3) # DSC 4 - ef1.save() - url = reverse("engagements:plan_for_org", kwargs={"orgslug": org.slug}) - self.client.force_login(self.data["superuser"]) - response = self.client.get(url) - self.assertEqual(response.status_code, HTTPStatus.OK) - self.assertTrue(response.context["entity"]) - self.assertEqual(response.context["entity"].name, org.name) - self.assertIn(si, response.context["dscs"]) - self.assertIn(si2, response.context["dscs"]) - self.assertIn(si3, response.context["dscs"]) - self.assertEqual(response.context["dscs"].count(), 3) - # self.assertNotIn(si_not, response.context["dscs"]) - - def test_dscs_for_ep_request_factory(self): - """ - On the EP page, we expect to see a list of all DSCs related to effort - for this organisation. - - Included this here for reference - """ - org = self.data["orgs"][0] - url = reverse("engagements:plan_for_org", kwargs={"orgslug": org.slug}) - request = self.request.get(url) - request.user = self.data["superuser"] - response = views.engagement_plan_for(request, org.slug) - self.assertEqual(response.status_code, HTTPStatus.OK) - - -class TestEngagementEffortView(TestCase): - @classmethod - def setUpTestData(cls): - cls.request = RequestFactory() # for use in _ep_request_factory test - cls.data = populate_database() - - def test_get_blank_form(self): - url = reverse("engagements:effort_create", kwargs={"eid": 1, "etype": "PLANNING"}) - self.client.force_login(self.data["superuser"]) - request = self.request.get(url) - request.user = self.data["superuser"] - response = views.engagement_effort_create(request, eid=1, etype="PLANNING") - self.assertEqual(response.status_code, HTTPStatus.OK) - - # def test_post_data(self): - # url = reverse( - # "engagements:effort_create", kwargs={"eid": 1, "etype": "PLANNING"} - # ) - # self.client.force_login(self.data["superuser"]) - # request = self.request.post(url, {"proposed_start_date": "toss"}) - # request.user = self.data["superuser"] - # response = views.engagement_effort_create(request, eid=1, etype="PLANNING") - # self.assertEqual(response.status_code, HTTPStatus.OK) + +@pytest.fixture +def test_data(): + return populate_database() + + +@pytest.fixture +def request_factory(): + return RequestFactory() + + +def test_dscs_for_ep(client, test_data, request_factory): + org = test_data["orgs"][0] + et = models.EngagementType.objects.get(name="INSPECTION") + si = test_data["sub_instruments"][0] + si2 = test_data["sub_instruments"][2] + si3 = test_data["sub_instruments"][3] + + engagement = models.Engagement.objects.create( + proposed_start_date=datetime.date(2022, 10, 10), + proposed_end_date=datetime.date(2022, 10, 10), + engagement_type=et, + external_party=org, + ) + ef1 = models.EngagementEffort.objects.create( + is_planned=True, + effort_type="REGULATION", + proposed_start_date=datetime.date(2022, 10, 10), + proposed_end_date=datetime.date(2022, 10, 10), + engagement=engagement, + ) + ef1.sub_instruments.add(si, si2, si3) + + url = reverse("engagements:plan_for_org", kwargs={"orgslug": org.slug}) + client.force_login(test_data["superuser"]) + response = client.get(url) + + assert response.status_code == HTTPStatus.OK + assert response.context["entity"] + assert response.context["entity"].name == org.name + assert si in response.context["dscs"] + assert si2 in response.context["dscs"] + assert si3 in response.context["dscs"] + + +def test_get_blank_form(client, test_data, request_factory): + url = reverse("engagements:effort_create", kwargs={"eid": 1, "etype": "PLANNING"}) + client.force_login(test_data["superuser"]) + request = request_factory.get(url) + request.user = test_data["superuser"] + response = views.engagement_effort_create(request, eid=1, etype="PLANNING") + assert response.status_code == HTTPStatus.OK + + +# def test_get_form_to_create_engagement_strategy(client, request_factory): +# url = reverse("engagements:es-create") +# client.force_login(test_data["superuser"]) +# request = request_factory.get(url) +# request.user = test_data["superuser"] +# response = views.CreateEngagementStrategy() +# assert response.status_code == HTTPStatus.OK + + +def test_create_engagement_strategy(client, user, org, regulatory_cycles): + # Define the URL for the create view + url = reverse("engagements:es-create") + client.force_login(user) + mod = Organisation.objects.create(name="MOD", is_regulated_entity=False) + + sy = RegulatoryCycle.objects.get(start_date__year="2022") + ey = RegulatoryCycle.objects.get(start_date__year="2024") + + # Define sample data for the form + data = { + "organisation": mod.pk, + "start_year": sy.pk, # Use the pk of the regulatory cycle instead of the object itself + "end_year": ey.pk, + "description": "Example description", + "inspector_sign_off": "2022-01-10", + "owned_by": user.pk, # Same here + "reviewed_by": user.pk, + "management_sign_off": "2022-02-10", + "status": "DRAFT", + } + + # Send a POST request to the view + response = client.post(url, data) + + # Check that the response redirects (status code 302) after successful creation + assert response.status_code == 302 + assert EngagementStrategy.objects.count() == 1 |