Beispiel #1
0
 def setUp(self):
     self.user = user_factory()
     self.other_user = user_factory()
     self.finished_essay = essay_factory()
     self.finished_feedback_request = feedback_request_factory(
         self.finished_essay, assign=True)
     self.finished_feedback_response = FeedbackResponseManager.create_for_feedback_request(
         self.user, self.finished_feedback_request)
     FeedbackResponseManager(self.finished_feedback_response).finish()
     self.essay = essay_factory(revision_of=self.finished_essay)
     self.feedback_request = feedback_request_factory(self.essay,
                                                      assign=True)
Beispiel #2
0
    def test_update_feedback_response(self):
        """ Test updating a feedback response. """
        unfinished_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, self.feedback_request)
        url = reverse('feedback-response-detail',
                      kwargs={'pk': unfinished_response.pk})
        NEW_CONTENT = 'dfsgfsdhjfdsa'

        updated_data = FeedbackResponseSerializer(unfinished_response).data
        updated_data['content'] = NEW_CONTENT

        # Cannot update a response created by another user
        self.client.force_login(self.other_user)
        response = self.client.put(url,
                                   json.dumps(updated_data),
                                   content_type=JSON)
        self.assertEqual(response.status_code, 404)
        unfinished_response.refresh_from_db()
        self.assertEqual(unfinished_response.content, '')  # Defaults to blank

        # Can update content field
        self.client.force_login(self.user)
        response = self.client.put(url,
                                   json.dumps(updated_data),
                                   content_type=JSON)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(data['content'], NEW_CONTENT)
        unfinished_response.refresh_from_db()
        self.assertEqual(unfinished_response.content,
                         NEW_CONTENT)  # Defaults to blank
        self.assertIn('previous_revision_feedback', data)

        # Cannot update other fields
        updated_data['editor'] = self.other_user.pk
        response = self.client.put(url,
                                   json.dumps(updated_data),
                                   content_type=JSON)
        self.assertEqual(response.status_code, 200)
        unfinished_response.refresh_from_db()
        self.assertEqual(unfinished_response.content, NEW_CONTENT)
        self.assertEqual(unfinished_response.editor, self.user)

        # Cannot update a finished response
        FeedbackResponseManager(unfinished_response).finish()
        updated_data['content'] = ''
        response = self.client.put(url,
                                   json.dumps(updated_data),
                                   content_type=JSON)
        self.assertEqual(response.status_code, 400)
        unfinished_response.refresh_from_db()
        self.assertEqual(unfinished_response.content, NEW_CONTENT)
Beispiel #3
0
    def finish(self, request, pk, *args, **kwargs):
        """ Finish the specified FeedbackResponse.

			No effect if the specified FeedbackResponse is already finished.

			Returns 200 on success.
		"""
        feedback_response = self.get_object()
        if not feedback_response.finished:
            feedback_response_manager = FeedbackResponseManager(
                feedback_response)
            feedback_response_manager.finish()
        return Response(self.get_serializer(feedback_response).data)
Beispiel #4
0
    def test_list_matched_feedback_requests(self):
        """ Test listing feedback requests matched with the a user. """
        url = reverse('feedback-request-list')

        # Must be authenticated to access feedback requests
        response = self.client.get(url)
        self.assertEqual(response.status_code, 403)

        self.client.force_login(self.user)

        # The user sees requests matched with them, not requests matched with others
        fr_matched_with_editor = feedback_request_factory(self.essay)
        fr_matched_with_editor.assigned_editors.add(self.user)
        fr_matched_with_editor.assigned_editors.add(self.admin)
        fr_not_matched_with_editor = feedback_request_factory(self.old_essay)
        fr_not_matched_with_editor.assigned_editors.add(self.admin)

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0].get('pk'), fr_matched_with_editor.pk)
        self.assertIsInstance(data[0].get('essay'), dict)

        # The user sees requests with an active feedback response
        feedback_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, fr_matched_with_editor)
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0].get('pk'), fr_matched_with_editor.pk)

        # But only if the feedback response is their own
        feedback_response.editor = self.admin
        feedback_response.save()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 0)

        # The user does not see requests that are completely finished
        feedback_response.editor = self.user
        feedback_response.save()
        FeedbackResponseManager(feedback_response).finish()
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 0)
Beispiel #5
0
    def test_start_response(self):
        """ Test starting a response. """
        feedback_request_1 = feedback_request_factory(self.essay)
        feedback_request_2 = feedback_request_factory(self.old_essay)
        url = reverse('feedback-request-start-response',
                      kwargs={'pk': feedback_request_1.pk})

        # User must be authenticated to start a response
        response = self.client.get(url)
        self.assertEqual(response.status_code, 403)

        self.client.force_login(self.user)

        # User cannot start a response on a request they are not matched with
        response = self.client.post(url)
        self.assertEqual(response.status_code, 400)
        feedback_request_1.refresh_from_db()
        self.assertFalse(feedback_request_1.feedback_responses.exists())
        self.assertIn('not assigned', str(response.content))

        feedback_request_1.assigned_editors.add(self.user, self.admin)
        feedback_request_2.assigned_editors.add(self.user, self.admin)

        # User cannot start a response on a request someone else has started
        feedback_response = FeedbackResponseManager.create_for_feedback_request(
            self.admin, feedback_request_1)
        response = self.client.post(url)
        self.assertEqual(response.status_code, 400)
        self.assertIn('open feedback response', str(response.content))

        feedback_response.delete()

        # User cannot start a response if they have another unfinished response
        feedback_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, feedback_request_2)
        response = self.client.post(url)
        self.assertEqual(response.status_code, 400)
        feedback_request_1.refresh_from_db()
        self.assertFalse(feedback_request_1.feedback_responses.exists())
        self.assertIn('unfinished feedback response', str(response.content))

        feedback_response.delete()

        # User **CAN** start a response otherwise
        response = self.client.post(url)
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.content)
        self.assertIn('previous_revision_feedback', data)
Beispiel #6
0
 def test_get_previous_feedback_responses_empty(self):
     """ Test getting feedback responses when there are none. """
     self.assertEqual(
         len(
             FeedbackResponseManager(
                 self.feedback_response).get_previous_feedback_responses()),
         0)
Beispiel #7
0
    def test_list_feedback_responses(self):
        """ Test listing feedback responses created by the current user. """
        url = reverse('feedback-response-list')
        self.client.force_login(self.user)
        unfinished_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, self.feedback_request)

        # By default, all feedback responses, finished and unfinished, are included
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 2)
        self.assertNotIn('previous_revision_feedback', data[0])

        # Can filter to only finished
        response = self.client.get(url + '?only_finished=true')
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['pk'], self.finished_feedback_response.pk)

        # Can filter to only unfinished
        response = self.client.get(url + '?only_unfinished=true')
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['pk'], unfinished_response.pk)
Beispiel #8
0
    def test_get_previous_feedback_responses_one(self):
        """ Test getting previous feedback responses when there is one revision. """
        self.essay.revision_of = self.finished_essay
        self.essay.save()

        feedback_responses = FeedbackResponseManager(
            self.feedback_response).get_previous_feedback_responses()
        self.assertEqual(len(feedback_responses), 1)
        self.assertEqual(feedback_responses[0],
                         self.finished_feedback_response)
Beispiel #9
0
    def test_get_previous_feedback_responses_no_revision(self):
        """ Test getting previous feedback responses when there is a revision but it was not edited """
        self.finished_feedback_response.finished = False
        self.finished_feedback_response.save()

        self.assertEqual(
            len(
                FeedbackResponseManager(
                    self.feedback_response).get_previous_feedback_responses()),
            0)
Beispiel #10
0
    def test_get_previous_feedback_responses_two(self):
        """ Test getting previous feedback responses when there are two revisions. """
        FeedbackResponseManager(self.feedback_response).finish()

        old_essay = essay_factory()
        old_feedback_request = feedback_request_factory(old_essay, assign=True)
        old_feedback_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, old_feedback_request)
        FeedbackResponseManager(old_feedback_response).finish()
        self.finished_essay.revision_of = old_essay
        self.finished_essay.save()
        self.essay.revision_of = self.finished_essay
        self.essay.save()

        feedback_responses = FeedbackResponseManager(
            self.feedback_response).get_previous_feedback_responses()
        self.assertEqual(len(feedback_responses), 2)
        self.assertEqual(feedback_responses[0],
                         self.finished_feedback_response)
        self.assertEqual(feedback_responses[1], old_feedback_response)
Beispiel #11
0
    def test_finish_feedback_response(self):
        """ Test finishing a feedback response. """
        unfinished_response = FeedbackResponseManager.create_for_feedback_request(
            self.user, self.feedback_request)
        url = reverse('feedback-response-finish',
                      kwargs={'pk': unfinished_response.pk})

        # Can finish a response (happy path test)
        self.client.force_login(self.user)
        response = self.client.post(url)
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.content)
        self.assertIn('previous_revision_feedback', data)
        self.assertTrue(data['finished'])
        unfinished_response.refresh_from_db()
        self.assertTrue(unfinished_response.finished)
        self.assertIsNotNone(unfinished_response.finish_time)
Beispiel #12
0
    def start_response(self, request, pk, *args, **kwargs):
        """ Start a new FeedbackResponse, if possible.

			Returns a 400 if the FeedbackRequest has already been taken.

			Returns a 201 with a serialized FeedbackResponse if the request succeeds.
		"""
        # This isn't great but we skip `get_queryset` and let the manager enforce perms here to get clean errors
        feedback_request = get_object_or_404(FeedbackRequest, pk=pk)
        try:
            feedback_response = FeedbackResponseManager.create_for_feedback_request(
                self.request.user, feedback_request)
            return Response(FeedbackResponseSerializer(
                feedback_response,
                context={
                    FeedbackResponseSerializer.INCLUDE_PREVIOUS_REVISIONS: True
                }).data,
                            status=status.HTTP_201_CREATED)
        except FeedbackResponseExistsError:
            return Response(
                {
                    'detail':
                    f'Feedback request {feedback_request.pk} already has an open feedback response.'
                },
                status=status.HTTP_400_BAD_REQUEST)
        except EditorHasOpenFeedbackResponseError:
            return Response(
             {
             'detail': f'You cannot start feedback on request {feedback_request.pk} because you have another' \
                                                                                                                                              + ' unfinished feedback response.'
             },
             status=status.HTTP_400_BAD_REQUEST
            )
        except EditorNotAssignedToFeedbackRequestError:
            return Response(
                {'detail': 'That feedback request is not assigned to you.'},
                status=status.HTTP_400_BAD_REQUEST)
Beispiel #13
0
 def get_queryset(self):
     return FeedbackResponseManager.query_for_user(
         self.request.user).select_related('feedback_request__essay')