Commit 482d0c0c by Clinton Blackburn Committed by GitHub

Fixed program course/course run sorting issue (#341)

The sorting code now exits with the default value if a course has no course runs.

ECOM-5696
parent 7dab67de
...@@ -454,6 +454,11 @@ class ProgramSerializer(serializers.ModelSerializer): ...@@ -454,6 +454,11 @@ class ProgramSerializer(serializers.ModelSerializer):
# #
# For more, refer to https://docs.djangoproject.com/en/1.10/ref/models/querysets/#latest. # For more, refer to https://docs.djangoproject.com/en/1.10/ref/models/querysets/#latest.
_course_runs = [course_run for course_run in course_runs if course_run.course == course] _course_runs = [course_run for course_run in course_runs if course_run.course == course]
# Return early if we have no course runs since min() will fail.
if not _course_runs:
return min_datetime
run = min(_course_runs, key=lambda run: run.enrollment_start or min_datetime) run = min(_course_runs, key=lambda run: run.enrollment_start or min_datetime)
return run.enrollment_start or min_datetime return run.enrollment_start or min_datetime
...@@ -464,6 +469,11 @@ class ProgramSerializer(serializers.ModelSerializer): ...@@ -464,6 +469,11 @@ class ProgramSerializer(serializers.ModelSerializer):
max_datetime = datetime.datetime.max.replace(tzinfo=pytz.UTC) max_datetime = datetime.datetime.max.replace(tzinfo=pytz.UTC)
_course_runs = [course_run for course_run in course_runs if course_run.course == course] _course_runs = [course_run for course_run in course_runs if course_run.course == course]
# Return early if we have no course runs since min() will fail.
if not _course_runs:
return max_datetime
run = min(_course_runs, key=lambda run: run.start or max_datetime) run = min(_course_runs, key=lambda run: run.start or max_datetime)
return run.start or max_datetime return run.start or max_datetime
......
...@@ -6,7 +6,7 @@ from course_discovery.apps.api.serializers import ProgramSerializer ...@@ -6,7 +6,7 @@ from course_discovery.apps.api.serializers import ProgramSerializer
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.course_metadata.choices import ProgramStatus from course_discovery.apps.course_metadata.choices import ProgramStatus
from course_discovery.apps.course_metadata.models import Program from course_discovery.apps.course_metadata.models import Program
from course_discovery.apps.course_metadata.tests.factories import ProgramFactory from course_discovery.apps.course_metadata.tests.factories import ProgramFactory, CourseFactory
@ddt.ddt @ddt.ddt
...@@ -20,6 +20,14 @@ class ProgramViewSetTests(APITestCase): ...@@ -20,6 +20,14 @@ class ProgramViewSetTests(APITestCase):
self.request = APIRequestFactory().get('/') self.request = APIRequestFactory().get('/')
self.request.user = self.user self.request.user = self.user
def assert_retrieve_success(self, program):
""" Verify the retrieve endpoint succesfully returns a serialized program. """
url = reverse('api:v1:program-detail', kwargs={'uuid': program.uuid})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, ProgramSerializer(program, context={'request': self.request}).data)
def test_authentication(self): def test_authentication(self):
""" Verify the endpoint requires the user to be authenticated. """ """ Verify the endpoint requires the user to be authenticated. """
response = self.client.get(self.list_path) response = self.client.get(self.list_path)
...@@ -29,14 +37,16 @@ class ProgramViewSetTests(APITestCase): ...@@ -29,14 +37,16 @@ class ProgramViewSetTests(APITestCase):
response = self.client.get(self.list_path) response = self.client.get(self.list_path)
self.assertEqual(response.status_code, 403) self.assertEqual(response.status_code, 403)
def test_get(self): def test_retrieve(self):
""" Verify the endpoint returns the details for a single program. """ """ Verify the endpoint returns the details for a single program. """
program = ProgramFactory() program = ProgramFactory()
url = reverse('api:v1:program-detail', kwargs={'uuid': program.uuid}) self.assert_retrieve_success(program)
response = self.client.get(url) def test_retrieve_without_course_runs(self):
self.assertEqual(response.status_code, 200) """ Verify the endpoint returns data for a program even if the program's courses have no course runs. """
self.assertEqual(response.data, ProgramSerializer(program, context={'request': self.request}).data) course = CourseFactory()
program = ProgramFactory(courses=[course])
self.assert_retrieve_success(program)
def assert_list_results(self, url, expected): def assert_list_results(self, url, expected):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment