diff --git a/django_workflow_system/api/tests/views/user/workflows/test_engagement_detail.py b/django_workflow_system/api/tests/views/user/workflows/test_engagement_detail.py index c54f0ce..5f6466d 100644 --- a/django_workflow_system/api/tests/views/user/workflows/test_engagement_detail.py +++ b/django_workflow_system/api/tests/views/user/workflows/test_engagement_detail.py @@ -518,6 +518,9 @@ def test_post_survey_cant_start_on_second_workflow(self): class TestWorkflowCollectionEngagementDetailView(TestCase): def setUp(self): self.view = WorkflowCollectionEngagementDetailView.as_view() + + # There are times when we will want to call the collection level view as part of a test. + self.collection_view = WorkflowCollectionEngagementDetailsView.as_view() self.factory = APIRequestFactory() self.single_activity_collection: WorkflowCollection = WorkflowCollectionFactory( **{ @@ -1393,3 +1396,45 @@ def test_patch__valid_payload_with_schema_existing_response_fails(self): request, my_workflow_engagement.id, my_workflow_engagement_detail.id ) self.assertEqual(response.status_code, 400) + + def test_user_can_delete_personal_engagement_detail(self): + """A user can delete their own CollectionEngagementDetail resources.""" + + # Step 1: Ensure there is 1 engagement detail on the engagement that can be deleted. + request = self.factory.get( + f"/users/self/workflows/engagements/{self.user_with_engagement__engagement.id}/details/" + ) + request.user = self.user_with_engagement + response = self.collection_view( + request, self.user_with_engagement__engagement.id + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 1) + + # Step 2: Attempt to delete the engagment detail. + request = self.factory.delete( + f"http://testserver/api/workflow_system/users/self/workflows/engagements/" + f"{self.user_with_engagement__engagement.id}/details/" + f"{self.user_with_engagement__detail.id}/" + ) + + request.user = self.user_with_engagement + response = self.view( + request, + self.user_with_engagement__engagement.id, + self.user_with_engagement__detail.id, + ) + self.assertEqual(response.status_code, 204) + + # Step 3: Verify the engagement detail was deleted. + request = self.factory.get( + f"/users/self/workflows/engagements/{self.user_with_engagement__engagement.id}/details/" + ) + request.user = self.user_with_engagement + response = self.collection_view( + request, self.user_with_engagement__engagement.id + ) + + self.assertEqual(response.status_code, 200) + self.assertEqual(len(response.data), 0) diff --git a/django_workflow_system/api/views/user/workflows/engagement_detail.py b/django_workflow_system/api/views/user/workflows/engagement_detail.py index 3ccf06f..430bdc1 100644 --- a/django_workflow_system/api/views/user/workflows/engagement_detail.py +++ b/django_workflow_system/api/views/user/workflows/engagement_detail.py @@ -205,6 +205,9 @@ class WorkflowCollectionEngagementDetailView(APIView): * Patch: Update a specific WorkflowCollectionEngagementDetail resource associated with a given WorkflowEngagement and belonging to the requesting user. + + * Delete: Deletes a WorkflowCollectionEngagementDetail resource for a + given WorkflowEngagement on behalf of the requesting user. """ required_scopes = ["read", "write"] @@ -375,3 +378,14 @@ def patch(self, request, engagement_id, id): data["state"]["proceed"] = True return Response(data=data, status=status.HTTP_200_OK) + + def delete(self, request, engagement_id, id): + # TODO: Need to handle case where a request is received to delete a detail that does not belong to the user. + """Delete a WorkflowCollectionEngagementDetail associated with a given WorkflowEngagement for current user.""" + engagement_detail = WorkflowCollectionEngagementDetail.objects.get( + id=id, + workflow_collection_engagement=engagement_id, + workflow_collection_engagement__user=request.user, + ) + engagement_detail.delete() + return Response(status=status.HTTP_204_NO_CONTENT)