Skip to content

Commit

Permalink
feat: add detail capability to ResultNotificationView
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-canon committed Jul 16, 2024
1 parent 4ccb809 commit aebfe51
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
29 changes: 27 additions & 2 deletions eox_nelp/pearson_vue/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from eox_core.edxapp_wrapper.bearer_authentication import BearerAuthentication
from rest_framework import status
from rest_framework.mixins import CreateModelMixin, ListModelMixin
from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet
Expand Down Expand Up @@ -174,14 +174,15 @@ def get_course(self):
return enrollment.course if enrollment else None


class ResultNotificationView(PearsonRTENBaseView):
class ResultNotificationView(RetrieveModelMixin, PearsonRTENBaseView):
"""
View for handling Result Notification events.
This view handles the creation of Result Notification events in the Pearson RTEN system.
The `event_type` attribute is set to "resultNotification".
"""
event_type = RESULT_NOTIFICATION
lookup_field = "course"

def create(self, request, *args, **kwargs):
"""
Expand All @@ -201,6 +202,30 @@ def create(self, request, *args, **kwargs):

return response

def get_object(self):
"""
Retrieves the latest object for the given candidate and course.
This method filters the queryset to find objects matching the current user
and the course specified by the lookup field in the URL. If no objects are found,
it raises a 404 error. If objects are found, it returns the most recently created object.
Returns:
object: The most recently created object that matches the given candidate and course.
Raises:
Http404: If no objects match the given candidate and course.
"""
objects = self.get_queryset().filter(
candidate=self.request.user,
course=self.kwargs[self.lookup_field],
)

if not objects:
raise Http404

return objects.latest("created_at")


class PlaceHoldView(PearsonRTENBaseView):
"""
Expand Down
42 changes: 42 additions & 0 deletions eox_nelp/pearson_vue/tests/api/v1/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
TestUnrevokeResultView: Unit tests for the UnrevokeResultView.
"""
import unittest
from datetime import datetime, timedelta
from unittest.mock import Mock, patch

from django.contrib.auth import get_user_model
Expand Down Expand Up @@ -263,6 +264,47 @@ def test_pipeline_execution(self, result_notification_mock):
result_notification_mock.assert_called_once_with(request_data=payload)
result_notification_mock.return_value.run_pipeline.assert_called_once()

def test_detail_view(self):
"""
Test that the detail view correctly retrieves the latest event for a candidate and course.
Expected behavior:
- Response returns a 200 status code.
- Response data contains the correct event details.
"""
PearsonRTENEvent.objects.create( # pylint: disable=no-member
event_type=self.event_type,
candidate=self.user,
course=self.course,
created_at=datetime.now(),
content={},
)
latest_event = PearsonRTENEvent.objects.create( # pylint: disable=no-member
event_type=self.event_type,
candidate=self.user,
course=self.course,
created_at=datetime.now() + timedelta(seconds=1), # Ensure this is the latest event
content={},
)

response = self.client.get(reverse(f"pearson-vue-api:v1:{self.event_type}-detail", args=[str(self.course_key)]))

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['created_at'], latest_event.created_at.isoformat())

def test_detail_not_found(self):
"""
Test that the detail view returns a 404 status when no event is found for the given candidate and course.
Expected behavior:
- Response returns a 404 status code.
"""
PearsonRTENEvent.objects.filter(candidate=self.user, course=self.course).delete() # pylint: disable=no-member

response = self.client.get(reverse(f"pearson-vue-api:v1:{self.event_type}-detail", args=[str(self.course_key)]))

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


class TestPlaceHoldView(RTENMixin, unittest.TestCase):
"""
Expand Down

0 comments on commit aebfe51

Please sign in to comment.