Skip to content

Commit

Permalink
Merge pull request #2190 from uktrade/LTD-5399-CLE-api-calls-visibility
Browse files Browse the repository at this point in the history
[LTD-5399] Add caseworker-specific CLEs endpoint
  • Loading branch information
currycoder authored Sep 23, 2024
2 parents 5cca1a5 + 7be7448 commit b57fba2
Show file tree
Hide file tree
Showing 13 changed files with 121 additions and 49 deletions.
1 change: 1 addition & 0 deletions api/conf/caseworker_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
urlpatterns = [
path("applications/", include("api.applications.caseworker.urls")),
path("organisations/", include("api.organisations.caseworker.urls")),
path("static/", include("api.staticdata.caseworker.urls")),
]
Empty file.
Empty file.
9 changes: 9 additions & 0 deletions api/staticdata/caseworker/control_list_entries/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import serializers

from api.staticdata.control_list_entries.models import ControlListEntry


class ControlListEntriesListSerializer(serializers.ModelSerializer):
class Meta:
model = ControlListEntry
fields = ("rating", "text", "parent")
Empty file.
67 changes: 67 additions & 0 deletions api/staticdata/caseworker/control_list_entries/tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from rest_framework import status
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


class ControlListEntriesListTests(DataTestClient):
def setUp(self):
self.url = reverse("caseworker_staticdata:control_list_entries:control_list_entries")
super().setUp()
ControlListEntry.objects.all().delete()
self.parent_cle = ControlListEntriesFactory(
rating="ML1",
selectable_for_assessment=False,
text="some ML1 text",
)
self.child_cle = ControlListEntriesFactory(
rating="ML1a",
parent=self.parent_cle,
selectable_for_assessment=True,
text="some ML1a text",
)

def test_GET_success(self):
response = self.client.get(self.url, **self.gov_headers)

self.assertEqual(response.status_code, status.HTTP_200_OK)

self.assertEqual(
response.json(),
[
{
"rating": "ML1a",
"text": "some ML1a text",
"parent": str(self.parent_cle.id),
}
],
)

def test_GET_exporter_forbidden(self):
response = self.client.get(self.url, **self.exporter_headers)

self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_GET_include_non_selectable_for_assessment_param(self):
url = self.url + "?include_non_selectable_for_assessment=True"
response = self.client.get(url, **self.gov_headers)

self.assertEqual(response.status_code, status.HTTP_200_OK)

self.assertEqual(
response.json(),
[
{
"rating": "ML1",
"text": "some ML1 text",
"parent": None,
},
{
"rating": "ML1a",
"text": "some ML1a text",
"parent": str(self.parent_cle.id),
},
],
)
9 changes: 9 additions & 0 deletions api/staticdata/caseworker/control_list_entries/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from django.urls import path

from api.staticdata.caseworker.control_list_entries import views

app_name = "control_list_entries"

urlpatterns = [
path("", views.ControlListEntriesList.as_view(), name="control_list_entries"),
]
18 changes: 18 additions & 0 deletions api/staticdata/caseworker/control_list_entries/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from rest_framework import generics

from api.core.authentication import GovAuthentication
from api.staticdata.control_list_entries.models import ControlListEntry
from api.staticdata.caseworker.control_list_entries.serializers import ControlListEntriesListSerializer


class ControlListEntriesList(generics.ListAPIView):
authentication_classes = (GovAuthentication,)
pagination_class = None
serializer_class = ControlListEntriesListSerializer

def get_queryset(self):
include_unselectable = self.request.GET.get("include_non_selectable_for_assessment", False)
if include_unselectable:
return ControlListEntry.objects.filter(controlled=True)

return ControlListEntry.objects.filter(controlled=True, selectable_for_assessment=True)
7 changes: 7 additions & 0 deletions api/staticdata/caseworker/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls import path, include

app_name = "caseworker_staticdata"

urlpatterns = [
path("control-list-entries/", include("api.staticdata.caseworker.control_list_entries.urls")),
]
41 changes: 2 additions & 39 deletions api/staticdata/control_list_entries/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,8 @@ def setUp(self):
super().setUp()
self.url = reverse("staticdata:control_list_entries:control_list_entries")

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
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 selectable_for_assessment=False
unselectable_cle = ControlListEntriesFactory(rating="rating123", text="text", selectable_for_assessment=False)

# Assert that the object was created successfully
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()

# 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)

# 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_unselectable_cles_if_include_unselectable_is_true(self):
url = reverse("staticdata:control_list_entries:control_list_entries") + "?include_unselectable=True"
def test_gov_user_control_list_entries_list_includes_unselectable_cles(self):
url = reverse("staticdata:control_list_entries:control_list_entries")
cles_count_model = ControlListEntry.objects.all().count()

# Assert that we have at least 1 CLE returned by the db manager
Expand Down
11 changes: 3 additions & 8 deletions api/staticdata/control_list_entries/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,19 @@
from api.staticdata.control_list_entries.serializers import ControlListEntrySerializerWithLinks


# TODO: Remove this endpoint when all callers are calling exporter/caseworker variants
@permission_classes((permissions.AllowAny,))
class ControlListEntriesList(APIView):
authentication_classes = (GovAuthentication,)

def get_queryset(self, include_unselectable=False):
if include_unselectable:
return ControlListEntry.objects.filter(controlled=True)

return ControlListEntry.objects.filter(controlled=True, selectable_for_assessment=True)
return ControlListEntry.objects.filter(controlled=True)

def get(self, request):
"""
Returns list of all Control List Entries
"""

include_unselectable = request.GET.get("include_unselectable", False)

queryset = self.get_queryset(include_unselectable=include_unselectable)
queryset = self.get_queryset()

if request.GET.get("group", False):
return JsonResponse(data={"control_list_entries": convert_control_list_entries_to_tree(queryset.values())})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ def test_list_view_ignores_unselectable_cles_by_default(self):
self.assertNotIn("rating123", [cle["rating"] for cle in updated_cles_data])

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"
url = (
reverse("exporter_staticdata:control_list_entries:control_list_entries")
+ "?include_non_selectable_for_assessment=True"
)
cles_count_model = ControlListEntry.objects.all().count()

# Assert that we have at least 1 CLE returned by the db manager
Expand Down
2 changes: 1 addition & 1 deletion api/staticdata/exporter/control_list_entries/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ControlListEntriesList(generics.ListAPIView):
serializer_class = ControlListEntriesListSerializer

def get_queryset(self):
include_unselectable = self.request.GET.get("include_unselectable", False)
include_unselectable = self.request.GET.get("include_non_selectable_for_assessment", False)
if include_unselectable:
return ControlListEntry.objects.filter(controlled=True)

Expand Down

0 comments on commit b57fba2

Please sign in to comment.