From ccf6d8b50e8530646e0170c866be976ce41fb2d9 Mon Sep 17 00:00:00 2001 From: Kevin Carrogan Date: Thu, 12 Sep 2024 14:18:54 +0100 Subject: [PATCH 01/13] Add parallelism to migration tests --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 67c9f96a1..568d769f0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -280,6 +280,7 @@ jobs: environment: <<: *common_env_vars LITE_API_ENABLE_ES: True + parallelism: 5 steps: - setup - run: @@ -299,6 +300,7 @@ jobs: environment: <<: *common_env_vars LITE_API_ENABLE_ES: True + parallelism: 5 steps: - setup - run: From 3ca84cab60fcfdcd71f9b7b87831bc70b1c1b817 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 17:08:22 +0100 Subject: [PATCH 02/13] Add deprecated field to ControlListEntry --- .../0006_controllistentry_deprecated.py | 18 ++++++++++++++++++ api/staticdata/control_list_entries/models.py | 1 + 2 files changed, 19 insertions(+) create mode 100644 api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py diff --git a/api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py b/api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py new file mode 100644 index 000000000..e254c6daf --- /dev/null +++ b/api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.15 on 2024-08-21 16:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("control_list_entries", "0005_adds_5D001e"), + ] + + operations = [ + migrations.AddField( + model_name="controllistentry", + name="deprecated", + field=models.BooleanField(default=False), + ), + ] diff --git a/api/staticdata/control_list_entries/models.py b/api/staticdata/control_list_entries/models.py index f05325d91..497c5a515 100755 --- a/api/staticdata/control_list_entries/models.py +++ b/api/staticdata/control_list_entries/models.py @@ -10,6 +10,7 @@ class ControlListEntry(models.Model): parent = models.ForeignKey("self", related_name="children", default=None, null=True, on_delete=models.CASCADE) category = models.CharField(max_length=100, default="") controlled = models.BooleanField(default=True) + deprecated = models.BooleanField(default=False) class Meta: db_table = "control_list_entry" From c9db997d27de114d212dfcd761673e29d751f0f0 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 17:11:44 +0100 Subject: [PATCH 03/13] Update CLE queryset to ignore deprecated CLEs --- api/staticdata/control_list_entries/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/staticdata/control_list_entries/views.py b/api/staticdata/control_list_entries/views.py index b19d86171..992c7b5f6 100755 --- a/api/staticdata/control_list_entries/views.py +++ b/api/staticdata/control_list_entries/views.py @@ -14,7 +14,7 @@ class ControlListEntriesList(APIView): authentication_classes = (SharedAuthentication,) def get_queryset(self): - return ControlListEntry.objects.filter(controlled=True) + return ControlListEntry.objects.filter(controlled=True, deprecated=False) def get(self, request): """ From fa864c8266beabbbbf29c69b94d7152947b690b3 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 17:41:34 +0100 Subject: [PATCH 04/13] Add view test for ignored deprecated CLEs --- .../control_list_entries/tests/test_views.py | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 api/staticdata/control_list_entries/tests/test_views.py diff --git a/api/staticdata/control_list_entries/tests/test_views.py b/api/staticdata/control_list_entries/tests/test_views.py new file mode 100644 index 000000000..a664e294b --- /dev/null +++ b/api/staticdata/control_list_entries/tests/test_views.py @@ -0,0 +1,46 @@ +from rest_framework.reverse import reverse + +from api.staticdata.control_list_entries.models import ControlListEntry +from test_helpers.clients import DataTestClient + + +class ControlListEntriesListTests(DataTestClient): + """ + Most other view tests are in api/staticdata/control_list_entries/test.py + """ + + def setUp(self): + super().setUp() + self.url = reverse("staticdata:control_list_entries:control_list_entries") + + def test_control_list_entries_list_ignores_deprecated_cles(self): + cles_count_model = ControlListEntry.objects.all().count() + + # Assert that we have at least 1 CLE returned by the db manager + self.assertTrue(cles_count_model > 0) + + response = self.client.get(self.url, **self.exporter_headers) + cles_data = response.json().get("control_list_entries") + cles_count_data = len(cles_data) + + # Assert that we have at least 1 CLE returned by the view + self.assertTrue(cles_count_data > 0) + + # Create a CLE with deprecated=True + deprecated_cle = ControlListEntry.objects.create(rating="rating123", text="text", deprecated=True) + + # Assert that the object was created successfully + self.assertTrue(deprecated_cle.deprecated) + self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + + updated_cles_count_model = ControlListEntry.objects.all().count() + + # Assert that the count returned by the db manager has increased by 1 + self.assertTrue(updated_cles_count_model == cles_count_model + 1) + + response = self.client.get(self.url, **self.exporter_headers) + updated_cles_data = response.json().get("control_list_entries") + updated_cles_count_data = len(updated_cles_data) + + # Assert that the count returned by the view is unchanged + self.assertTrue(updated_cles_count_data == cles_count_data) From 923ea17aff19bf6b0dd3e312b1488d789bf6befa Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 18:43:53 +0100 Subject: [PATCH 05/13] Update tests --- .../control_list_entries/factories.py | 1 + .../control_list_entries/tests/test_views.py | 70 ++++++++++++++++++- api/staticdata/control_list_entries/views.py | 9 ++- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/api/staticdata/control_list_entries/factories.py b/api/staticdata/control_list_entries/factories.py index ff4325ac8..29cb3224e 100644 --- a/api/staticdata/control_list_entries/factories.py +++ b/api/staticdata/control_list_entries/factories.py @@ -8,6 +8,7 @@ class ControlListEntriesFactory(factory.django.DjangoModelFactory): parent = None category = "test-list" controlled = True + deprecated = False class Meta: model = models.ControlListEntry diff --git a/api/staticdata/control_list_entries/tests/test_views.py b/api/staticdata/control_list_entries/tests/test_views.py index a664e294b..58ed25908 100644 --- a/api/staticdata/control_list_entries/tests/test_views.py +++ b/api/staticdata/control_list_entries/tests/test_views.py @@ -1,6 +1,7 @@ from rest_framework.reverse import reverse from api.staticdata.control_list_entries.models import ControlListEntry +from api.staticdata.control_list_entries.factories import ControlListEntriesFactory from test_helpers.clients import DataTestClient @@ -13,7 +14,72 @@ def setUp(self): super().setUp() self.url = reverse("staticdata:control_list_entries:control_list_entries") - def test_control_list_entries_list_ignores_deprecated_cles(self): + def test_gov_user_control_list_entries_list_ignores_deprecated_cles(self): + cles_count_model = ControlListEntry.objects.all().count() + + # Assert that we have at least 1 CLE returned by the db manager + self.assertTrue(cles_count_model > 0) + + response = self.client.get(self.url, **self.gov_headers) + cles_data = response.json().get("control_list_entries") + cles_count_data = len(cles_data) + + # Assert that we have at least 1 CLE returned by the view + self.assertTrue(cles_count_data > 0) + + # Create a CLE with deprecated=True + deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + + # Assert that the object was created successfully + self.assertTrue(deprecated_cle.deprecated) + self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + + updated_cles_count_model = ControlListEntry.objects.all().count() + + # Assert that the count returned by the db manager has increased by 1 + self.assertTrue(updated_cles_count_model == cles_count_model + 1) + + response = self.client.get(self.url, **self.gov_headers) + updated_cles_data = response.json().get("control_list_entries") + updated_cles_count_data = len(updated_cles_data) + + # Assert that the count returned by the view is unchanged + self.assertTrue(updated_cles_count_data == cles_count_data) + + def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_deprecated_is_true(self): + url = reverse("staticdata:control_list_entries:control_list_entries") + "?include_deprecated=True" + cles_count_model = ControlListEntry.objects.all().count() + + # Assert that we have at least 1 CLE returned by the db manager + self.assertTrue(cles_count_model > 0) + + response = self.client.get(url, **self.gov_headers) + cles_data = response.json().get("control_list_entries") + cles_count_data = len(cles_data) + + # Assert that we have at least 1 CLE returned by the view + self.assertTrue(cles_count_data > 0) + + # Create a CLE with deprecated=True + deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + + # Assert that the object was created successfully + self.assertTrue(deprecated_cle.deprecated) + self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + + updated_cles_count_model = ControlListEntry.objects.all().count() + + # Assert that the count returned by the db manager has increased by 1 + self.assertTrue(updated_cles_count_model == cles_count_model + 1) + + response = self.client.get(url, **self.gov_headers) + updated_cles_data = response.json().get("control_list_entries") + updated_cles_count_data = len(updated_cles_data) + + # Assert that the count returned by the view has increased by 1 + self.assertTrue(updated_cles_count_data == cles_count_data + 1) + + def test_exporter_user_control_list_entries_list_ignores_deprecated_cles(self): cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -27,7 +93,7 @@ def test_control_list_entries_list_ignores_deprecated_cles(self): self.assertTrue(cles_count_data > 0) # Create a CLE with deprecated=True - deprecated_cle = ControlListEntry.objects.create(rating="rating123", text="text", deprecated=True) + deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) # Assert that the object was created successfully self.assertTrue(deprecated_cle.deprecated) diff --git a/api/staticdata/control_list_entries/views.py b/api/staticdata/control_list_entries/views.py index 992c7b5f6..0d9f9b9d5 100755 --- a/api/staticdata/control_list_entries/views.py +++ b/api/staticdata/control_list_entries/views.py @@ -13,7 +13,10 @@ class ControlListEntriesList(APIView): authentication_classes = (SharedAuthentication,) - def get_queryset(self): + def get_queryset(self, include_deprecated=False): + if include_deprecated: + return ControlListEntry.objects.filter(controlled=True) + return ControlListEntry.objects.filter(controlled=True, deprecated=False) def get(self, request): @@ -21,7 +24,9 @@ def get(self, request): Returns list of all Control List Entries """ - queryset = self.get_queryset() + include_deprecated = request.GET.get("include_deprecated", False) + + queryset = self.get_queryset(include_deprecated=include_deprecated) if request.GET.get("group", False): return JsonResponse(data={"control_list_entries": convert_control_list_entries_to_tree(queryset.values())}) From 523c151b0f44b18f69a9d540652cad4e56e93653 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 18:46:28 +0100 Subject: [PATCH 06/13] Update DW expected fields test --- api/data_workspace/v1/tests/test_staticdata_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/data_workspace/v1/tests/test_staticdata_views.py b/api/data_workspace/v1/tests/test_staticdata_views.py index 241efa020..2e6243b35 100644 --- a/api/data_workspace/v1/tests/test_staticdata_views.py +++ b/api/data_workspace/v1/tests/test_staticdata_views.py @@ -7,7 +7,7 @@ class DataWorkspaceTests(DataTestClient): def test_control_list_entries(self): url = reverse("data_workspace:v1:dw-control-list-entries-list") - expected_fields = ("id", "rating", "text", "category", "controlled", "parent") + expected_fields = ("id", "rating", "text", "category", "controlled", "parent", "deprecated") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) From b3f67d5e1d6b6643d7e023ea9833e4ff27efeb5c Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 18:56:07 +0100 Subject: [PATCH 07/13] Add stricter test assertions --- api/staticdata/control_list_entries/tests/test_views.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/staticdata/control_list_entries/tests/test_views.py b/api/staticdata/control_list_entries/tests/test_views.py index 58ed25908..7ba790b7a 100644 --- a/api/staticdata/control_list_entries/tests/test_views.py +++ b/api/staticdata/control_list_entries/tests/test_views.py @@ -46,6 +46,9 @@ def test_gov_user_control_list_entries_list_ignores_deprecated_cles(self): # Assert that the count returned by the view is unchanged self.assertTrue(updated_cles_count_data == cles_count_data) + # Assert that the data returned by the view does not contain the deprecated CLE + self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) + def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_deprecated_is_true(self): url = reverse("staticdata:control_list_entries:control_list_entries") + "?include_deprecated=True" cles_count_model = ControlListEntry.objects.all().count() @@ -79,6 +82,9 @@ def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_ # Assert that the count returned by the view has increased by 1 self.assertTrue(updated_cles_count_data == cles_count_data + 1) + # Assert that the data returned by the view contains the deprecated CLE + self.assertIn("rating123", [cle["rating"] for cle in updated_cles_data]) + def test_exporter_user_control_list_entries_list_ignores_deprecated_cles(self): cles_count_model = ControlListEntry.objects.all().count() @@ -110,3 +116,6 @@ def test_exporter_user_control_list_entries_list_ignores_deprecated_cles(self): # Assert that the count returned by the view is unchanged self.assertTrue(updated_cles_count_data == cles_count_data) + + # Assert that the data returned by the view does not contain the deprecated CLE + self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) From 9aba9f0b1345199ee78ab9e79116f0b618af6a95 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Wed, 21 Aug 2024 19:18:44 +0100 Subject: [PATCH 08/13] Fix DW test --- api/data_workspace/v1/tests/test_staticdata_views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/data_workspace/v1/tests/test_staticdata_views.py b/api/data_workspace/v1/tests/test_staticdata_views.py index 2e6243b35..08ffbdd85 100644 --- a/api/data_workspace/v1/tests/test_staticdata_views.py +++ b/api/data_workspace/v1/tests/test_staticdata_views.py @@ -7,7 +7,7 @@ class DataWorkspaceTests(DataTestClient): def test_control_list_entries(self): url = reverse("data_workspace:v1:dw-control-list-entries-list") - expected_fields = ("id", "rating", "text", "category", "controlled", "parent", "deprecated") + expected_fields = ("id", "rating", "text", "category", "controlled", "deprecated", "parent") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) From 08b7b5f9304ea7da1b70a1d11ceb03d14afeeaf2 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Thu, 5 Sep 2024 15:43:06 +0100 Subject: [PATCH 09/13] Update CLEs endpoint to use GovAuthentication --- .../control_list_entries/tests/test_views.py | 35 ------------------- api/staticdata/control_list_entries/views.py | 4 +-- .../control_list_entries/tests/test_views.py | 35 +++++++++++++++++++ .../exporter/control_list_entries/views.py | 2 +- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/api/staticdata/control_list_entries/tests/test_views.py b/api/staticdata/control_list_entries/tests/test_views.py index 7ba790b7a..1a4ae1c69 100644 --- a/api/staticdata/control_list_entries/tests/test_views.py +++ b/api/staticdata/control_list_entries/tests/test_views.py @@ -84,38 +84,3 @@ def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_ # Assert that the data returned by the view contains the deprecated CLE self.assertIn("rating123", [cle["rating"] for cle in updated_cles_data]) - - def test_exporter_user_control_list_entries_list_ignores_deprecated_cles(self): - cles_count_model = ControlListEntry.objects.all().count() - - # Assert that we have at least 1 CLE returned by the db manager - self.assertTrue(cles_count_model > 0) - - response = self.client.get(self.url, **self.exporter_headers) - cles_data = response.json().get("control_list_entries") - cles_count_data = len(cles_data) - - # Assert that we have at least 1 CLE returned by the view - self.assertTrue(cles_count_data > 0) - - # Create a CLE with deprecated=True - deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) - - # Assert that the object was created successfully - self.assertTrue(deprecated_cle.deprecated) - self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) - - updated_cles_count_model = ControlListEntry.objects.all().count() - - # Assert that the count returned by the db manager has increased by 1 - self.assertTrue(updated_cles_count_model == cles_count_model + 1) - - response = self.client.get(self.url, **self.exporter_headers) - updated_cles_data = response.json().get("control_list_entries") - updated_cles_count_data = len(updated_cles_data) - - # Assert that the count returned by the view is unchanged - self.assertTrue(updated_cles_count_data == cles_count_data) - - # Assert that the data returned by the view does not contain the deprecated CLE - self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) diff --git a/api/staticdata/control_list_entries/views.py b/api/staticdata/control_list_entries/views.py index 0d9f9b9d5..946888de4 100755 --- a/api/staticdata/control_list_entries/views.py +++ b/api/staticdata/control_list_entries/views.py @@ -3,7 +3,7 @@ from rest_framework.decorators import permission_classes from rest_framework.views import APIView -from api.core.authentication import SharedAuthentication +from api.core.authentication import GovAuthentication, SharedAuthentication from api.staticdata.control_list_entries.helpers import get_control_list_entry, convert_control_list_entries_to_tree from api.staticdata.control_list_entries.models import ControlListEntry from api.staticdata.control_list_entries.serializers import ControlListEntrySerializerWithLinks @@ -11,7 +11,7 @@ @permission_classes((permissions.AllowAny,)) class ControlListEntriesList(APIView): - authentication_classes = (SharedAuthentication,) + authentication_classes = (GovAuthentication,) def get_queryset(self, include_deprecated=False): if include_deprecated: diff --git a/api/staticdata/exporter/control_list_entries/tests/test_views.py b/api/staticdata/exporter/control_list_entries/tests/test_views.py index ef7770e18..a4dc3eac9 100644 --- a/api/staticdata/exporter/control_list_entries/tests/test_views.py +++ b/api/staticdata/exporter/control_list_entries/tests/test_views.py @@ -46,3 +46,38 @@ def test_list_view_success_exact_response(self): {"rating": cle_3.rating, "text": cle_3.text}, ], ) + + def test_list_view_ignores_deprecated_cles(self): + cles_count_model = ControlListEntry.objects.all().count() + + # Assert that we have at least 1 CLE returned by the db manager + self.assertTrue(cles_count_model > 0) + + response = self.client.get(self.url, **self.exporter_headers) + cles_data = response.json() + cles_count_data = len(cles_data) + + # Assert that we have at least 1 CLE returned by the view + self.assertTrue(cles_count_data > 0) + + # Create a CLE with deprecated=True + deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + + # Assert that the object was created successfully + self.assertTrue(deprecated_cle.deprecated) + self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + + updated_cles_count_model = ControlListEntry.objects.all().count() + + # Assert that the count returned by the db manager has increased by 1 + self.assertTrue(updated_cles_count_model == cles_count_model + 1) + + response = self.client.get(self.url, **self.exporter_headers) + updated_cles_data = response.json() + updated_cles_count_data = len(updated_cles_data) + + # Assert that the count returned by the view is unchanged + self.assertTrue(updated_cles_count_data == cles_count_data) + + # Assert that the data returned by the view does not contain the deprecated CLE + self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) diff --git a/api/staticdata/exporter/control_list_entries/views.py b/api/staticdata/exporter/control_list_entries/views.py index d3097850a..3ef768ec7 100644 --- a/api/staticdata/exporter/control_list_entries/views.py +++ b/api/staticdata/exporter/control_list_entries/views.py @@ -9,4 +9,4 @@ class ControlListEntriesList(generics.ListAPIView): authentication_classes = (ExporterAuthentication,) pagination_class = None serializer_class = ControlListEntriesListSerializer - queryset = ControlListEntry.objects.filter(controlled=True) + queryset = ControlListEntry.objects.filter(controlled=True, deprecated=False) From cc19813c94053b5851b171790e466de3a2f110f5 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Thu, 5 Sep 2024 16:16:23 +0100 Subject: [PATCH 10/13] Add deprecated functionality to exporter CLEs list view --- .../control_list_entries/tests/test_views.py | 38 ++++++++++++++++++- .../exporter/control_list_entries/views.py | 8 +++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/api/staticdata/exporter/control_list_entries/tests/test_views.py b/api/staticdata/exporter/control_list_entries/tests/test_views.py index a4dc3eac9..299a7e88a 100644 --- a/api/staticdata/exporter/control_list_entries/tests/test_views.py +++ b/api/staticdata/exporter/control_list_entries/tests/test_views.py @@ -47,7 +47,7 @@ def test_list_view_success_exact_response(self): ], ) - def test_list_view_ignores_deprecated_cles(self): + def test_list_view_ignores_deprecated_cles_by_default(self): cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -81,3 +81,39 @@ def test_list_view_ignores_deprecated_cles(self): # Assert that the data returned by the view does not contain the deprecated CLE self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) + + def test_list_view_includes_deprecated_cles_if_include_deprecated_is_true(self): + url = reverse("exporter_staticdata:control_list_entries:control_list_entries") + "?include_deprecated=True" + cles_count_model = ControlListEntry.objects.all().count() + + # Assert that we have at least 1 CLE returned by the db manager + self.assertTrue(cles_count_model > 0) + + response = self.client.get(url, **self.exporter_headers) + cles_data = response.json() + cles_count_data = len(cles_data) + + # Assert that we have at least 1 CLE returned by the view + self.assertTrue(cles_count_data > 0) + + # Create a CLE with deprecated=True + deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + + # Assert that the object was created successfully + self.assertTrue(deprecated_cle.deprecated) + self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + + updated_cles_count_model = ControlListEntry.objects.all().count() + + # Assert that the count returned by the db manager has increased by 1 + self.assertTrue(updated_cles_count_model == cles_count_model + 1) + + response = self.client.get(url, **self.exporter_headers) + updated_cles_data = response.json() + updated_cles_count_data = len(updated_cles_data) + + # Assert that the count returned by the view has increased by 1 + self.assertTrue(updated_cles_count_data == cles_count_data + 1) + + # Assert that the data returned by the view contains the deprecated CLE + self.assertIn("rating123", [cle["rating"] for cle in updated_cles_data]) diff --git a/api/staticdata/exporter/control_list_entries/views.py b/api/staticdata/exporter/control_list_entries/views.py index 3ef768ec7..dbd9cdd94 100644 --- a/api/staticdata/exporter/control_list_entries/views.py +++ b/api/staticdata/exporter/control_list_entries/views.py @@ -9,4 +9,10 @@ class ControlListEntriesList(generics.ListAPIView): authentication_classes = (ExporterAuthentication,) pagination_class = None serializer_class = ControlListEntriesListSerializer - queryset = ControlListEntry.objects.filter(controlled=True, deprecated=False) + + def get_queryset(self): + include_deprecated = self.request.GET.get("include_deprecated", False) + if include_deprecated: + return ControlListEntry.objects.filter(controlled=True) + + return ControlListEntry.objects.filter(controlled=True, deprecated=False) From 94295e5838ca6105d74f68fa98b515e4ef1e872c Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Tue, 10 Sep 2024 11:36:20 +0100 Subject: [PATCH 11/13] Add init files so tests work --- api/staticdata/control_list_entries/tests/__init__.py | 0 api/staticdata/exporter/__init__.py | 0 api/staticdata/exporter/control_list_entries/__init__.py | 0 api/staticdata/exporter/control_list_entries/tests/__init__.py | 0 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 api/staticdata/control_list_entries/tests/__init__.py create mode 100644 api/staticdata/exporter/__init__.py create mode 100644 api/staticdata/exporter/control_list_entries/__init__.py create mode 100644 api/staticdata/exporter/control_list_entries/tests/__init__.py diff --git a/api/staticdata/control_list_entries/tests/__init__.py b/api/staticdata/control_list_entries/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/staticdata/exporter/__init__.py b/api/staticdata/exporter/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/staticdata/exporter/control_list_entries/__init__.py b/api/staticdata/exporter/control_list_entries/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/api/staticdata/exporter/control_list_entries/tests/__init__.py b/api/staticdata/exporter/control_list_entries/tests/__init__.py new file mode 100644 index 000000000..e69de29bb From 19c93d6e4318b3bf681c62d22b367866d2efae48 Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Fri, 13 Sep 2024 14:12:30 +0100 Subject: [PATCH 12/13] Change default deprecated False to selectable_for_assessment True --- ...y => 0006_controllistentry_selectable_for_assessment.py} | 6 +++--- api/staticdata/control_list_entries/models.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename api/staticdata/control_list_entries/migrations/{0006_controllistentry_deprecated.py => 0006_controllistentry_selectable_for_assessment.py} (64%) diff --git a/api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py b/api/staticdata/control_list_entries/migrations/0006_controllistentry_selectable_for_assessment.py similarity index 64% rename from api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py rename to api/staticdata/control_list_entries/migrations/0006_controllistentry_selectable_for_assessment.py index e254c6daf..6c73d3ee6 100644 --- a/api/staticdata/control_list_entries/migrations/0006_controllistentry_deprecated.py +++ b/api/staticdata/control_list_entries/migrations/0006_controllistentry_selectable_for_assessment.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.15 on 2024-08-21 16:08 +# Generated by Django 4.2.15 on 2024-09-13 13:08 from django.db import migrations, models @@ -12,7 +12,7 @@ class Migration(migrations.Migration): operations = [ migrations.AddField( model_name="controllistentry", - name="deprecated", - field=models.BooleanField(default=False), + name="selectable_for_assessment", + field=models.BooleanField(default=True), ), ] diff --git a/api/staticdata/control_list_entries/models.py b/api/staticdata/control_list_entries/models.py index 497c5a515..e22a99944 100755 --- a/api/staticdata/control_list_entries/models.py +++ b/api/staticdata/control_list_entries/models.py @@ -10,7 +10,7 @@ class ControlListEntry(models.Model): parent = models.ForeignKey("self", related_name="children", default=None, null=True, on_delete=models.CASCADE) category = models.CharField(max_length=100, default="") controlled = models.BooleanField(default=True) - deprecated = models.BooleanField(default=False) + selectable_for_assessment = models.BooleanField(default=True) class Meta: db_table = "control_list_entry" From 91fcefb4817e6feae4a99701521a48aa7c466aac Mon Sep 17 00:00:00 2001 From: Henry Cooksley Date: Fri, 13 Sep 2024 14:27:40 +0100 Subject: [PATCH 13/13] Rename more variables --- .../v1/tests/test_staticdata_views.py | 2 +- .../control_list_entries/factories.py | 2 +- .../control_list_entries/tests/test_views.py | 30 +++++++++++-------- api/staticdata/control_list_entries/views.py | 10 +++---- .../control_list_entries/tests/test_views.py | 30 +++++++++++-------- .../exporter/control_list_entries/views.py | 6 ++-- 6 files changed, 44 insertions(+), 36 deletions(-) diff --git a/api/data_workspace/v1/tests/test_staticdata_views.py b/api/data_workspace/v1/tests/test_staticdata_views.py index 08ffbdd85..286f8eaa6 100644 --- a/api/data_workspace/v1/tests/test_staticdata_views.py +++ b/api/data_workspace/v1/tests/test_staticdata_views.py @@ -7,7 +7,7 @@ class DataWorkspaceTests(DataTestClient): def test_control_list_entries(self): url = reverse("data_workspace:v1:dw-control-list-entries-list") - expected_fields = ("id", "rating", "text", "category", "controlled", "deprecated", "parent") + expected_fields = ("id", "rating", "text", "category", "controlled", "selectable_for_assessment", "parent") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/api/staticdata/control_list_entries/factories.py b/api/staticdata/control_list_entries/factories.py index 29cb3224e..f8baa1e1f 100644 --- a/api/staticdata/control_list_entries/factories.py +++ b/api/staticdata/control_list_entries/factories.py @@ -8,7 +8,7 @@ class ControlListEntriesFactory(factory.django.DjangoModelFactory): parent = None category = "test-list" controlled = True - deprecated = False + selectable_for_assessment = True class Meta: model = models.ControlListEntry diff --git a/api/staticdata/control_list_entries/tests/test_views.py b/api/staticdata/control_list_entries/tests/test_views.py index 1a4ae1c69..1dc7c3ef0 100644 --- a/api/staticdata/control_list_entries/tests/test_views.py +++ b/api/staticdata/control_list_entries/tests/test_views.py @@ -14,7 +14,7 @@ def setUp(self): super().setUp() self.url = reverse("staticdata:control_list_entries:control_list_entries") - def test_gov_user_control_list_entries_list_ignores_deprecated_cles(self): + def test_gov_user_control_list_entries_list_ignores_unselectable_cles(self): cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -27,12 +27,14 @@ def test_gov_user_control_list_entries_list_ignores_deprecated_cles(self): # Assert that we have at least 1 CLE returned by the view self.assertTrue(cles_count_data > 0) - # Create a CLE with deprecated=True - deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + # Create a CLE with selectable_for_assessment=False + unselectable_cle = ControlListEntriesFactory(rating="rating123", text="text", selectable_for_assessment=False) # Assert that the object was created successfully - self.assertTrue(deprecated_cle.deprecated) - self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + self.assertFalse(unselectable_cle.selectable_for_assessment) + self.assertTrue( + ControlListEntry.objects.filter(rating="rating123", selectable_for_assessment=False).count() == 1 + ) updated_cles_count_model = ControlListEntry.objects.all().count() @@ -46,11 +48,11 @@ def test_gov_user_control_list_entries_list_ignores_deprecated_cles(self): # Assert that the count returned by the view is unchanged self.assertTrue(updated_cles_count_data == cles_count_data) - # Assert that the data returned by the view does not contain the deprecated CLE + # Assert that the data returned by the view does not contain the unselectable CLE self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) - def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_deprecated_is_true(self): - url = reverse("staticdata:control_list_entries:control_list_entries") + "?include_deprecated=True" + def test_gov_user_control_list_entries_list_includes_unselectable_cles_if_include_unselectable_is_true(self): + url = reverse("staticdata:control_list_entries:control_list_entries") + "?include_unselectable=True" cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -63,12 +65,14 @@ def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_ # Assert that we have at least 1 CLE returned by the view self.assertTrue(cles_count_data > 0) - # Create a CLE with deprecated=True - deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + # Create a CLE with selectable_for_assessment=False + unselectable_cle = ControlListEntriesFactory(rating="rating123", text="text", selectable_for_assessment=False) # Assert that the object was created successfully - self.assertTrue(deprecated_cle.deprecated) - self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + self.assertFalse(unselectable_cle.selectable_for_assessment) + self.assertTrue( + ControlListEntry.objects.filter(rating="rating123", selectable_for_assessment=False).count() == 1 + ) updated_cles_count_model = ControlListEntry.objects.all().count() @@ -82,5 +86,5 @@ def test_gov_user_control_list_entries_list_includes_deprecated_cles_if_include_ # Assert that the count returned by the view has increased by 1 self.assertTrue(updated_cles_count_data == cles_count_data + 1) - # Assert that the data returned by the view contains the deprecated CLE + # Assert that the data returned by the view contains the unselectable CLE self.assertIn("rating123", [cle["rating"] for cle in updated_cles_data]) diff --git a/api/staticdata/control_list_entries/views.py b/api/staticdata/control_list_entries/views.py index 946888de4..182312d3a 100755 --- a/api/staticdata/control_list_entries/views.py +++ b/api/staticdata/control_list_entries/views.py @@ -13,20 +13,20 @@ class ControlListEntriesList(APIView): authentication_classes = (GovAuthentication,) - def get_queryset(self, include_deprecated=False): - if include_deprecated: + def get_queryset(self, include_unselectable=False): + if include_unselectable: return ControlListEntry.objects.filter(controlled=True) - return ControlListEntry.objects.filter(controlled=True, deprecated=False) + return ControlListEntry.objects.filter(controlled=True, selectable_for_assessment=True) def get(self, request): """ Returns list of all Control List Entries """ - include_deprecated = request.GET.get("include_deprecated", False) + include_unselectable = request.GET.get("include_unselectable", False) - queryset = self.get_queryset(include_deprecated=include_deprecated) + queryset = self.get_queryset(include_unselectable=include_unselectable) if request.GET.get("group", False): return JsonResponse(data={"control_list_entries": convert_control_list_entries_to_tree(queryset.values())}) diff --git a/api/staticdata/exporter/control_list_entries/tests/test_views.py b/api/staticdata/exporter/control_list_entries/tests/test_views.py index 299a7e88a..93c476e5b 100644 --- a/api/staticdata/exporter/control_list_entries/tests/test_views.py +++ b/api/staticdata/exporter/control_list_entries/tests/test_views.py @@ -47,7 +47,7 @@ def test_list_view_success_exact_response(self): ], ) - def test_list_view_ignores_deprecated_cles_by_default(self): + def test_list_view_ignores_unselectable_cles_by_default(self): cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -60,12 +60,14 @@ def test_list_view_ignores_deprecated_cles_by_default(self): # Assert that we have at least 1 CLE returned by the view self.assertTrue(cles_count_data > 0) - # Create a CLE with deprecated=True - deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + # Create a CLE with selectable_for_assessment=False + unselectable_cle = ControlListEntriesFactory(rating="rating123", text="text", selectable_for_assessment=False) # Assert that the object was created successfully - self.assertTrue(deprecated_cle.deprecated) - self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + self.assertFalse(unselectable_cle.selectable_for_assessment) + self.assertTrue( + ControlListEntry.objects.filter(rating="rating123", selectable_for_assessment=False).count() == 1 + ) updated_cles_count_model = ControlListEntry.objects.all().count() @@ -79,11 +81,11 @@ def test_list_view_ignores_deprecated_cles_by_default(self): # Assert that the count returned by the view is unchanged self.assertTrue(updated_cles_count_data == cles_count_data) - # Assert that the data returned by the view does not contain the deprecated CLE + # Assert that the data returned by the view does not contain the unselectable CLE self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data]) - def test_list_view_includes_deprecated_cles_if_include_deprecated_is_true(self): - url = reverse("exporter_staticdata:control_list_entries:control_list_entries") + "?include_deprecated=True" + def test_list_view_includes_unselectable_cles_if_include_unselectable_is_true(self): + url = reverse("exporter_staticdata:control_list_entries:control_list_entries") + "?include_unselectable=True" cles_count_model = ControlListEntry.objects.all().count() # Assert that we have at least 1 CLE returned by the db manager @@ -96,12 +98,14 @@ def test_list_view_includes_deprecated_cles_if_include_deprecated_is_true(self): # Assert that we have at least 1 CLE returned by the view self.assertTrue(cles_count_data > 0) - # Create a CLE with deprecated=True - deprecated_cle = ControlListEntriesFactory(rating="rating123", text="text", deprecated=True) + # Create a CLE with selectable_for_assessment=False + unselectable_cle = ControlListEntriesFactory(rating="rating123", text="text", selectable_for_assessment=False) # Assert that the object was created successfully - self.assertTrue(deprecated_cle.deprecated) - self.assertTrue(ControlListEntry.objects.filter(rating="rating123", deprecated=True).count() == 1) + self.assertFalse(unselectable_cle.selectable_for_assessment) + self.assertTrue( + ControlListEntry.objects.filter(rating="rating123", selectable_for_assessment=False).count() == 1 + ) updated_cles_count_model = ControlListEntry.objects.all().count() @@ -115,5 +119,5 @@ def test_list_view_includes_deprecated_cles_if_include_deprecated_is_true(self): # Assert that the count returned by the view has increased by 1 self.assertTrue(updated_cles_count_data == cles_count_data + 1) - # Assert that the data returned by the view contains the deprecated CLE + # Assert that the data returned by the view contains the unselectable CLE self.assertIn("rating123", [cle["rating"] for cle in updated_cles_data]) diff --git a/api/staticdata/exporter/control_list_entries/views.py b/api/staticdata/exporter/control_list_entries/views.py index dbd9cdd94..b95bca580 100644 --- a/api/staticdata/exporter/control_list_entries/views.py +++ b/api/staticdata/exporter/control_list_entries/views.py @@ -11,8 +11,8 @@ class ControlListEntriesList(generics.ListAPIView): serializer_class = ControlListEntriesListSerializer def get_queryset(self): - include_deprecated = self.request.GET.get("include_deprecated", False) - if include_deprecated: + include_unselectable = self.request.GET.get("include_unselectable", False) + if include_unselectable: return ControlListEntry.objects.filter(controlled=True) - return ControlListEntry.objects.filter(controlled=True, deprecated=False) + return ControlListEntry.objects.filter(controlled=True, selectable_for_assessment=True)