Skip to content

Commit

Permalink
feat: add emeritus api list view (#3329)
Browse files Browse the repository at this point in the history
* feat: add emeritus api list view

* chore: add superuser permission

* chore: add permissions

* fix tests

* refactor: log exception

* refactor: add exception message in response
  • Loading branch information
asadali145 authored Dec 5, 2024
1 parent b331af6 commit fde762d
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
6 changes: 6 additions & 0 deletions courses/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from rest_framework import routers

from courses.views import v1
from courses.views.v1 import EmeritusCourseListView

router = routers.SimpleRouter()
router.register(r"programs", v1.ProgramViewSet, basename="programs_api")
Expand All @@ -29,4 +30,9 @@
re_path(
r"^api/enrollments/", v1.UserEnrollmentsView.as_view(), name="user-enrollments"
),
path(
"api/emeritus_courses/",
EmeritusCourseListView.as_view(),
name="emeritus_courses",
),
]
24 changes: 23 additions & 1 deletion courses/views/v1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from mitol.digitalcredentials.mixins import DigitalCredentialsRequestViewSetMixin
from rest_framework import status, viewsets
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

Expand All @@ -27,6 +27,7 @@
ProgramEnrollmentSerializer,
ProgramSerializer,
)
from courses.sync_external_courses.emeritus_api import fetch_emeritus_courses
from ecommerce.models import Product


Expand Down Expand Up @@ -202,3 +203,24 @@ def get_queryset(self):
Returns parent topics with course count > 0.
"""
return CourseTopic.parent_topics_with_courses()


class EmeritusCourseListView(APIView):
"""
ReadOnly View to list Emeritus courses.
"""

permission_classes = [IsAdminUser]

def get(self, request, *args, **kwargs): # noqa: ARG002
"""
Get Emeritus courses list from the Emeritus API and return it.
"""
try:
data = fetch_emeritus_courses()
return Response(data, status=status.HTTP_200_OK)
except Exception as e: # noqa: BLE001
return Response(
{"error": "Some error occurred.", "details": str(e)},
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
32 changes: 32 additions & 0 deletions courses/views_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
Tests for course views
"""

import json
import operator as op
from datetime import timedelta
from pathlib import Path

import pytest
from django.contrib.auth.models import AnonymousUser
Expand Down Expand Up @@ -611,3 +613,33 @@ def test_course_topics_api(client, django_assert_num_queries):
assert len(resp_json) == 1
assert resp_json[0]["name"] == parent_topic.name
assert resp_json[0]["course_count"] == 4


@pytest.mark.parametrize("expected_status_code", [200, 500])
def test_emeritus_course_list_view(admin_drf_client, mocker, expected_status_code):
"""
Test that the Emeritus API List calls fetch_emeritus_courses and returns its mocked response.
"""
if expected_status_code == 200:
with Path(
"courses/sync_external_courses/test_data/batch_test.json"
).open() as test_data_file:
mocked_response = json.load(test_data_file)["rows"]

patched_fetch_emeritus_courses = mocker.patch(
"courses.views.v1.fetch_emeritus_courses", return_value=mocked_response
)
else:
patched_fetch_emeritus_courses = mocker.patch(
"courses.views.v1.fetch_emeritus_courses",
side_effect=Exception("Some error occurred."),
)
mocked_response = {
"error": "Some error occurred.",
"details": "Some error occurred.",
}

response = admin_drf_client.get(reverse("emeritus_courses"))
assert response.json() == mocked_response
assert response.status_code == expected_status_code
patched_fetch_emeritus_courses.assert_called_once()

0 comments on commit fde762d

Please sign in to comment.