Skip to content

Commit

Permalink
fix: missing request in serializer context
Browse files Browse the repository at this point in the history
  • Loading branch information
shadinaif committed May 29, 2024
1 parent c0ad1b5 commit efeafb8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
2 changes: 1 addition & 1 deletion futurex_openedx_extensions/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""One-line description for README and other doc files."""

__version__ = '0.3.2'
__version__ = '0.3.5'
1 change: 0 additions & 1 deletion futurex_openedx_extensions/dashboard/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from lms.djangoapps.certificates.api import get_certificates_for_user_by_course_keys
from lms.djangoapps.courseware.courses import get_course_blocks_completion_summary
from lms.djangoapps.grades.api import CourseGradeFactory
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.block_structure.api import get_block_structure_manager
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.user_api.accounts.serializers import AccountLegacyProfileSerializer
Expand Down
5 changes: 4 additions & 1 deletion futurex_openedx_extensions/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ def get(self, request, username, *args, **kwargs): # pylint: disable=no-self-us
class LearnerCoursesView(APIView):
"""View to get the list of courses for a learner"""
permission_classes = [HasTenantAccess]
pagination_class = DefaultPagination

def get(self, request, username, *args, **kwargs): # pylint: disable=no-self-use
"""
Expand All @@ -201,4 +202,6 @@ def get(self, request, username, *args, **kwargs): # pylint: disable=no-self-us

courses = get_learner_courses_info_queryset(tenant_ids, user_id)

return Response(serializers.LearnerCoursesDetailsSerializer(courses, many=True).data)
return Response(serializers.LearnerCoursesDetailsSerializer(
courses, context={'request': request}, many=True
).data)
10 changes: 5 additions & 5 deletions test_utils/edx_platform_mocks/fake_models/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@
from django.contrib.auth import get_user_model


def get_course_blocks_completion_summary(course_key, user): # pylint: disable=unused-argument
def get_course_blocks_completion_summary(course_key, user): # pylint: disable=unused-argument, useless-return
"""get_course_blocks_completion_summary Mock"""
if not isinstance(user, get_user_model()):
raise Exception(f'Expects a user object but got "{user}" of type "{type(user)}"')
raise TypeError(f'Expects a user object but got "{user}" of type "{type(user)}"')
return None


def get_block_structure_manager(course_key): # pylint: disable=unused-argument
def get_block_structure_manager(course_key):
"""get_block_structure_manager Mock"""
if not isinstance(course_key, str):
raise Exception(f'Expects a coruse_key as string but got "{course_key}" of type "{type(course_key)}"')
raise TypeError(f'Expects a coruse_key as string but got "{course_key}" of type "{type(course_key)}"')

class Dummy: # pylint: disable=too-few-public-methods
"""dummy class"""
Expand All @@ -27,5 +27,5 @@ def get_collected(self): # pylint: disable=no-self-use
def get_certificates_for_user_by_course_keys(user, course_keys): # pylint: disable=unused-argument
"""get_certificates_for_user_by_course_keys Mock"""
if not isinstance(user, get_user_model()):
raise Exception(f'Expects a user object but got "{user}" of type "{type(user)}"')
raise TypeError(f'Expects a user object but got "{user}" of type "{type(user)}"')
return {}
43 changes: 42 additions & 1 deletion tests/test_dashboard/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from django.urls import resolve, reverse
from django.utils.timezone import now, timedelta
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from rest_framework.test import APITestCase
from rest_framework.test import APIRequestFactory, APITestCase

from futurex_openedx_extensions.dashboard import serializers
from futurex_openedx_extensions.helpers.constants import COURSE_STATUSES
Expand All @@ -36,6 +36,17 @@ def login_user(self, user_id):
"""Helper to login user"""
self.client.force_login(get_user_model().objects.get(id=user_id))

def _get_request_view_class(self):
"""Helper to get the view class and a request"""
view_func, _, _ = resolve(self.url)
view_class = view_func.view_class
factory = APIRequestFactory()
request = factory.get(self.url)
request.query_params = {}
request.user = get_user_model().objects.get(id=self.staff_user)

return request, view_class


@pytest.mark.usefixtures('base_data')
class TestTotalCountsView(BaseTestViewMixin):
Expand Down Expand Up @@ -284,6 +295,21 @@ def test_success(self):
data = json.loads(response.content)
self.assertDictEqual(data, serializers.LearnerDetailsExtendedSerializer(user).data)

@patch('futurex_openedx_extensions.dashboard.views.serializers.LearnerDetailsExtendedSerializer')
def test_request_in_context(self, mock_serializer):
"""Verify that the view calls the serializer with the correct context"""
request, view_class = self._get_request_view_class()
mock_serializer.return_value = Mock(data={})

with patch('futurex_openedx_extensions.dashboard.views.get_learner_info_queryset') as mock_get_info:
mock_get_info.return_value = Mock()
view_class.get(self, request, 'user10')

mock_serializer.assert_called_once_with(
mock_get_info.return_value.first(),
context={'request': request},
)


@patch.object(
serializers.LearnerCoursesDetailsSerializer,
Expand Down Expand Up @@ -316,3 +342,18 @@ def test_success(self):
data = json.loads(response.content)
self.assertEqual(len(data), 2)
self.assertEqual(list(data), list(serializers.LearnerCoursesDetailsSerializer(courses, many=True).data))

@patch('futurex_openedx_extensions.dashboard.views.serializers.LearnerCoursesDetailsSerializer')
def test_request_in_context(self, mock_serializer):
"""Verify that the view uses the correct serializer"""
request, view_class = self._get_request_view_class()

with patch('futurex_openedx_extensions.dashboard.views.get_learner_courses_info_queryset') as mock_get_info:
mock_get_info.return_value = Mock()
view_class.get(self, request, 'user10')

mock_serializer.assert_called_once_with(
mock_get_info.return_value,
context={'request': request},
many=True,
)

0 comments on commit efeafb8

Please sign in to comment.