Merge pull request #6198 from edx/afzaledx/WL-105
WL-105 Show course cards sorted by start dates, oldest first.
This commit is contained in:
1
AUTHORS
1
AUTHORS
@@ -182,3 +182,4 @@ Louis Pilfold <louis@lpil.uk>
|
||||
Akiva Leffert <akiva@edx.org>
|
||||
Mike Bifulco <mbifulco@aquent.com>
|
||||
Jim Zheng <jimzheng@stanford.edu>
|
||||
Afzal Wali <afzaledx@edx.org>
|
||||
|
||||
@@ -68,7 +68,7 @@ from xmodule.modulestore import ModuleStoreEnum
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from courseware.courses import get_courses, sort_by_announcement
|
||||
from courseware.courses import get_courses, sort_by_announcement, sort_by_start_date # pylint: disable=import-error
|
||||
from courseware.access import has_access
|
||||
|
||||
from django_comment_common.models import Role
|
||||
@@ -146,7 +146,11 @@ def index(request, extra_context=None, user=AnonymousUser()):
|
||||
domain = request.META.get('HTTP_HOST')
|
||||
|
||||
courses = get_courses(user, domain=domain)
|
||||
courses = sort_by_announcement(courses)
|
||||
if microsite.get_value("ENABLE_COURSE_SORTING_BY_START_DATE",
|
||||
settings.FEATURES["ENABLE_COURSE_SORTING_BY_START_DATE"]):
|
||||
courses = sort_by_start_date(courses)
|
||||
else:
|
||||
courses = sort_by_announcement(courses)
|
||||
|
||||
context = {'courses': courses}
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ from django.http import HttpResponseRedirect
|
||||
from django.test.utils import override_settings
|
||||
from django.test.client import RequestFactory
|
||||
from pytz import UTC
|
||||
from mock import patch, Mock
|
||||
from edxmako.shortcuts import render_to_response
|
||||
|
||||
from branding.views import index
|
||||
from xmodule.modulestore.tests.django_utils import TEST_DATA_MOCK_MODULESTORE
|
||||
@@ -22,6 +24,15 @@ FEATURES_WO_STARTDATE = settings.FEATURES.copy()
|
||||
FEATURES_WO_STARTDATE['DISABLE_START_DATES'] = True
|
||||
|
||||
|
||||
def mock_render_to_response(*args, **kwargs):
|
||||
"""
|
||||
Mock the render_to_response function
|
||||
"""
|
||||
return render_to_response(*args, **kwargs)
|
||||
|
||||
RENDER_MOCK = Mock(side_effect=mock_render_to_response)
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MOCK_MODULESTORE)
|
||||
class AnonymousIndexPageTest(ModuleStoreTestCase):
|
||||
"""
|
||||
@@ -94,3 +105,61 @@ class AnonymousIndexPageTest(ModuleStoreTestCase):
|
||||
self.assertIsInstance(response, HttpResponseRedirect)
|
||||
# Location should be "/login".
|
||||
self.assertEqual(response._headers.get("location")[1], "/login")
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MOCK_MODULESTORE)
|
||||
class IndexPageCourseCardsSortingTests(ModuleStoreTestCase):
|
||||
"""
|
||||
Test for Index page course cards sorting
|
||||
"""
|
||||
def setUp(self):
|
||||
super(IndexPageCourseCardsSortingTests, self).setUp()
|
||||
self.starting_later = CourseFactory.create(
|
||||
org='MITx',
|
||||
number='1000',
|
||||
display_name='Starting later, Announced later',
|
||||
metadata={
|
||||
'start': datetime.datetime.now(UTC) + datetime.timedelta(days=4),
|
||||
'announcement': datetime.datetime.now(UTC) + datetime.timedelta(days=3),
|
||||
}
|
||||
)
|
||||
self.starting_earlier = CourseFactory.create(
|
||||
org='MITx',
|
||||
number='1001',
|
||||
display_name='Starting earlier, Announced earlier',
|
||||
metadata={
|
||||
'start': datetime.datetime.now(UTC) + datetime.timedelta(days=2),
|
||||
'announcement': datetime.datetime.now(UTC) + datetime.timedelta(days=1),
|
||||
}
|
||||
)
|
||||
self.course_with_default_start_date = CourseFactory.create(
|
||||
org='MITx',
|
||||
number='1002',
|
||||
display_name='Tech Beta Course',
|
||||
)
|
||||
self.factory = RequestFactory()
|
||||
|
||||
@patch('student.views.render_to_response', RENDER_MOCK)
|
||||
def test_course_cards_sorted_by_default_sorting(self):
|
||||
response = self.client.get('/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
((template, context), _) = RENDER_MOCK.call_args
|
||||
self.assertEqual(template, 'index.html')
|
||||
|
||||
# Now the courses will be stored in their announcement dates.
|
||||
self.assertEqual(context['courses'][0].id, self.starting_later.id)
|
||||
self.assertEqual(context['courses'][1].id, self.starting_earlier.id)
|
||||
self.assertEqual(context['courses'][2].id, self.course_with_default_start_date.id)
|
||||
|
||||
@patch('student.views.render_to_response', RENDER_MOCK)
|
||||
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_COURSE_SORTING_BY_START_DATE': True})
|
||||
def test_course_cards_sorted_by_start_date_show_earliest_first(self):
|
||||
response = self.client.get('/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
((template, context), _) = RENDER_MOCK.call_args
|
||||
self.assertEqual(template, 'index.html')
|
||||
|
||||
# now the courses will be sorted by their creation dates, earliest first.
|
||||
self.assertEqual(context['courses'][0].id, self.starting_earlier.id)
|
||||
self.assertEqual(context['courses'][1].id, self.starting_later.id)
|
||||
self.assertEqual(context['courses'][2].id, self.course_with_default_start_date.id)
|
||||
|
||||
@@ -373,6 +373,15 @@ def sort_by_announcement(courses):
|
||||
return courses
|
||||
|
||||
|
||||
def sort_by_start_date(courses):
|
||||
"""
|
||||
Returns a list of courses sorted by their start date, latest first.
|
||||
"""
|
||||
courses = sorted(courses, key=lambda course: (course.start is None, course.start), reverse=False)
|
||||
|
||||
return courses
|
||||
|
||||
|
||||
def get_cms_course_link(course, page='course'):
|
||||
"""
|
||||
Returns a link to course_index for editing the course in cms,
|
||||
|
||||
@@ -273,6 +273,11 @@ FEATURES = {
|
||||
# False to not redirect the user
|
||||
'ALWAYS_REDIRECT_HOMEPAGE_TO_DASHBOARD_FOR_AUTHENTICATED_USER': True,
|
||||
|
||||
# When a user goes to the homepage ('/') the user see the
|
||||
# courses listed in the announcement dates order - this is default Open edX behavior.
|
||||
# Set to True to change the course sorting behavior by their start dates, latest first.
|
||||
'ENABLE_COURSE_SORTING_BY_START_DATE': False,
|
||||
|
||||
# Expose Mobile REST API. Note that if you use this, you must also set
|
||||
# ENABLE_OAUTH2_PROVIDER to True
|
||||
'ENABLE_MOBILE_REST_API': False,
|
||||
|
||||
Reference in New Issue
Block a user