def test_list_referralanswers_by_unit_member_missing_referral_param( self, _): """ The API returns an error response when the referral parameter is missing. """ user = factories.UserFactory() referral = factories.ReferralFactory() referral.units.first().members.add(user) factories.ReferralAnswerFactory(referral=referral, state=models.ReferralAnswerState.DRAFT) factories.ReferralAnswerFactory( referral=referral, state=models.ReferralAnswerState.PUBLISHED) response = self.client.get( "/api/referralanswers/", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { "errors": ["ReferralAnswer list requests need a referral parameter"] }, )
def test_list_referralanswers_by_unit_member(self, _): """ Referral unit members can get both draft & published answers for referrals their unit is linked with. """ user = factories.UserFactory() referral = factories.ReferralFactory() referral.units.first().members.add(user) draft_answer = factories.ReferralAnswerFactory( referral=referral, state=models.ReferralAnswerState.DRAFT, created_at=arrow.utcnow().shift(days=-15).datetime, ) published_answer = factories.ReferralAnswerFactory( referral=referral, state=models.ReferralAnswerState.PUBLISHED, created_at=arrow.utcnow().shift(days=-7).datetime, ) response = self.client.get( f"/api/referralanswers/?referral={referral.id}", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["count"], 2) self.assertEqual(response.json()["results"][0]["id"], str(published_answer.id)) self.assertEqual(response.json()["results"][1]["id"], str(draft_answer.id))
def test_remove_attachment_by_referral_linked_unit_members(self, _): """ Other unit members who are not the author cannot remove attachments from answers to a referral their unit is linked with. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) answer.referral.units.get().members.add(user) attachment = factories.ReferralAnswerAttachmentFactory() attachment.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment.id}, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1)
def test_create_referralanswerattachment_multiple_files(self): """ The request fails with an apprioriate error when a user attempts to create an attachment with more than one attached file. """ answer = factories.ReferralAnswerFactory() self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", { "answer": str(answer.id), "files": (BytesIO(b"firstfile"), BytesIO(b"secondfile")), }, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { "errors": [ "Referral answer attachments cannot be created with more than one file." ] }, ) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)
def test_remove_attachment_from_published_answer(self, _): """ Attachments cannot be removed from a published answer, even by the answer's author. """ answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.PUBLISHED) answer.referral.units.get().members.add(answer.created_by) ( attachment_1, attachment_2, ) = factories.ReferralAnswerAttachmentFactory.create_batch(2) attachment_1.referral_answers.add(answer) attachment_2.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 2) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment_1.id}, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { "errors": ["attachments cannot be removed from a published answer"] }, ) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 2)
def test_list_referralanswers_by_anonymous_user(self, _): """ Anonymous users cannot make list request for referral answers. """ answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.PUBLISHED) response = self.client.get( f"/api/referralanswers/?referral={answer.referral.id}") self.assertEqual(response.status_code, 401)
def test_list_referralanswervalidationrequest_by_anonymous_user(self): """ Anonymous users cannot get lists of referral answer validation requests. """ answer = factories.ReferralAnswerFactory() factories.ReferralAnswerValidationRequestFactory.create_batch( 2, answer=answer) response = self.client.get( "/api/referralanswervalidationrequests/", {"answer": str(answer.id)}, ) self.assertEqual(response.status_code, 401)
def test_list_referralanswers_by_referral_author(self, _): """ Referral authors can get published answers for their referrals, but not the draft answers. """ user = factories.UserFactory() referral = factories.ReferralFactory(post__users=[user]) factories.ReferralAnswerFactory(referral=referral, state=models.ReferralAnswerState.DRAFT) published_answer = factories.ReferralAnswerFactory( referral=referral, state=models.ReferralAnswerState.PUBLISHED) response = self.client.get( f"/api/referralanswers/?referral={referral.id}", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["count"], 1) self.assertEqual(response.json()["results"][0]["id"], str(published_answer.id))
def test_create_referralanswerattachment_by_anonymous_user(self): """ Anonymous users cannot create referral answer attachments. """ answer = factories.ReferralAnswerFactory() self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id), "files": (BytesIO(b"attachment_file"),)}, ) self.assertEqual(response.status_code, 401) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)
def test_create_referralanswer_with_attachments(self, _): """ Make sure attachments are handled during referral answer creatin (for revisions). """ user = factories.UserFactory() referral = factories.ReferralFactory( state=models.ReferralState.ASSIGNED) referral.units.get().members.add(user) existing_answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) attachments = factories.ReferralAnswerAttachmentFactory.create_batch(3) for attachment in attachments: attachment.referral_answers.add(existing_answer) existing_answer.refresh_from_db() self.assertEqual(existing_answer.attachments.count(), 3) response = self.client.post( "/api/referralanswers/", { "referral": str(referral.id), "content": existing_answer.content, "attachments": [ serializers.ReferralAnswerAttachmentSerializer( existing_answer.attachments.all()[0]).data, serializers.ReferralAnswerAttachmentSerializer( existing_answer.attachments.all()[1]).data, ], }, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 201) new_answer = models.ReferralAnswer.objects.get( id=response.json()["id"]) self.assertEqual(new_answer.attachments.count(), 2) self.assertEqual(response.json()["content"], existing_answer.content) self.assertEqual( response.json()["attachments"][0]["id"], str(existing_answer.attachments.all()[0].id), ) self.assertEqual( response.json()["attachments"][1]["id"], str(existing_answer.attachments.all()[1].id), ) self.assertNotEqual(existing_answer.id, new_answer.id)
def test_create_referralanswerattachment_by_referral_linked_user(self): """ A referral's linked user cannot create attachments for answers to their referral. """ answer = factories.ReferralAnswerFactory() user = answer.referral.users.first() self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id), "files": (BytesIO(b"attachment_file"),)}, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)
def test_create_referralanswerattachment_by_random_logged_in_user(self): """ Random logged in users cannot create attachments for referral answers they have no link to. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory() self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id), "files": (BytesIO(b"attachment_file"),)}, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)
def test_list_referralanswervalidationrequest_by_random_logged_in_user( self): """ Random logged in users cannot get lists of referral answer validation requests. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory() factories.ReferralAnswerValidationRequestFactory.create_batch( 2, answer=answer) response = self.client.get( "/api/referralanswervalidationrequests/", {"answer": str(answer.id)}, HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403)
def test_list_referralanswervalidationrequest_for_nonexistent_answer(self): """ The request fails with an apprioriate error when a user attempts to get a list of validation requests for an answer that does not exist. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory() answer.referral.units.get().members.add(user) factories.ReferralAnswerValidationRequestFactory.create_batch( 2, answer=answer) response = self.client.post( "/api/referralanswerattachments/", {"answer": uuid.uuid4()}, HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 404)
def test_list_referralanswervalidationrequest_by_referral_linked_user( self): """ A referral's linked user cannot get lists of referral answer validation requests for answers to their referral. """ answer = factories.ReferralAnswerFactory() user = answer.referral.users.first() factories.ReferralAnswerValidationRequestFactory.create_batch( 2, answer=answer) response = self.client.get( "/api/referralanswervalidationrequests/", {"answer": str(answer.id)}, HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403)
def test_create_referralanswerattachment_by_referral_linked_unit_member(self): """ A member of a referral's linked unit cannot create attachments for answers to the referral if they are not said answer's author. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory() answer.referral.units.get().members.add(user) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id), "files": (BytesIO(b"attachment_file"),)}, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)
def test_update_referralanswer_by_anonymous_user(self, _): """ Anonymous users cannot update referral answers. """ answer = factories.ReferralAnswerFactory( content="initial content", state=models.ReferralAnswerState.DRAFT) response = self.client.put( f"/api/referralanswers/{answer.id}/", { **serializers.ReferralAnswerSerializer(answer).data, "content": "updated content", }, content_type="application/json", ) self.assertEqual(response.status_code, 401) answer.refresh_from_db() self.assertEqual(answer.content, "initial content")
def test_create_referralanswerattachment_by_answer_author(self): """ An answer's author can create attachments for it. """ answer = factories.ReferralAnswerFactory() attachment_file = BytesIO(b"attachment_file") attachment_file.name = "the attachment file name" response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id), "files": (attachment_file,)}, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 201) attachment = models.ReferralAnswerAttachment.objects.get( id=response.json()["id"] ) self.assertEqual(attachment.name, "the attachment file name") self.assertEqual(attachment.size, 15)
def test_remove_attachment_by_anonymous_user(self, _): """ Anonymous users cannot remove attachments from answers. """ answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) attachment = factories.ReferralAnswerAttachmentFactory() attachment.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment.id}, content_type="application/json", ) self.assertEqual(response.status_code, 401) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1)
def test_update_referralanswer_by_author(self, _): """ An answer's original author can update it. """ answer = factories.ReferralAnswerFactory( content="initial content", state=models.ReferralAnswerState.DRAFT) answer.referral.units.get().members.add(answer.created_by) response = self.client.put( f"/api/referralanswers/{answer.id}/", { **serializers.ReferralAnswerSerializer(answer).data, "content": "updated content", }, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 200) answer.refresh_from_db() self.assertEqual(answer.content, "updated content")
def test_update_referralanswer_by_random_logged_in_user(self, _): """ A random logged in users cannot update a referral answer. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory( content="initial content", state=models.ReferralAnswerState.DRAFT) response = self.client.put( f"/api/referralanswers/{answer.id}/", { **serializers.ReferralAnswerSerializer(answer).data, "content": "updated content", }, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) answer.refresh_from_db() self.assertEqual(answer.content, "initial content")
def test_list_referralanswers_by_random_logged_in_user(self, _): """ Random logged-in users can make list requests for referral answers, will receive an empty response. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.PUBLISHED) response = self.client.get( f"/api/referralanswers/?referral={answer.referral.id}", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json(), { "count": 0, "next": None, "previous": None, "results": [] })
def test_list_referralanswervalidationrequest_by_referral_linked_unit_member( self): """ A member of a referral's linked unit can get lists of referral answer validation requests for answers to said referral. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory() answer.referral.units.get().members.add(user) validation_requests = factories.ReferralAnswerValidationRequestFactory.create_batch( 2, answer=answer) response = self.client.get( "/api/referralanswervalidationrequests/", {"answer": str(answer.id)}, HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 200) self.assertEqual(response.json()["count"], 2) self.assertEqual(response.json()["results"][0]["id"], str(validation_requests[0].id)) self.assertEqual(response.json()["results"][1]["id"], str(validation_requests[1].id))
def test_remove_attachment_by_referral_linked_user(self, _): """ A given referral's linked user cannot remove attachments from answers to their referral. """ answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) user = answer.referral.users.first() attachment = factories.ReferralAnswerAttachmentFactory() attachment.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment.id}, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1)
def test_remove_attachment_by_random_logged_in_user(self, _): """ Random logged-in users cannot remove attachments from answers they did not author. """ user = factories.UserFactory() answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) attachment = factories.ReferralAnswerAttachmentFactory() attachment.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment.id}, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=user)[0]}", ) self.assertEqual(response.status_code, 403) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1)
def test_remove_attachment_by_author(self, _): """ An answer's author can unattach an attachment from their answer. This does not delete the attachment object itself as it could be linked to other answers. """ answer = factories.ReferralAnswerFactory( state=models.ReferralAnswerState.DRAFT) answer.referral.units.get().members.add(answer.created_by) ( attachment_1, attachment_2, ) = factories.ReferralAnswerAttachmentFactory.create_batch(2) attachment_1.referral_answers.add(answer) attachment_2.referral_answers.add(answer) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 2) response = self.client.post( f"/api/referralanswers/{answer.id}/remove_attachment/", {"attachment": attachment_1.id}, content_type="application/json", HTTP_AUTHORIZATION= f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()["attachments"]), 1) self.assertEqual(response.json()["attachments"][0]["id"], str(attachment_2.id)) answer.refresh_from_db() self.assertEqual(answer.attachments.count(), 1) # The attachment object was not deleted, only unlinked from the answer self.assertEqual( models.ReferralAnswerAttachment.objects.filter( id=attachment_1.id).exists(), True, )
def test_create_referralanswerattachment_missing_file(self): """ The request fails with an apprioriate error when a user attempts to create an attachment but does not any file. """ answer = factories.ReferralAnswerFactory() self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0) response = self.client.post( "/api/referralanswerattachments/", {"answer": str(answer.id)}, HTTP_AUTHORIZATION=f"Token {Token.objects.get_or_create(user=answer.created_by)[0]}", ) self.assertEqual(response.status_code, 400) self.assertEqual( response.json(), { "errors": [ "Referral answer attachments cannot be created without a file." ] }, ) self.assertEqual(models.ReferralAnswerAttachment.objects.all().count(), 0)