diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index e7ce721c19..4ec167ad29 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -201,6 +201,11 @@ def index(request, extra_context=None, user=AnonymousUser()):
# 1) Change False to True
context['show_homepage_promo_video'] = configuration_helpers.get_value('show_homepage_promo_video', False)
+ # Maximum number of courses to display on the homepage.
+ context['homepage_course_max'] = configuration_helpers.get_value(
+ 'HOMEPAGE_COURSE_MAX', settings.HOMEPAGE_COURSE_MAX
+ )
+
# 2) Add your video's YouTube ID (11 chars, eg "123456789xX"), or specify via site configuration
# Note: This value should be moved into a configuration setting and plumbed-through to the
# context via the site configuration workflow, versus living here
diff --git a/lms/djangoapps/courseware/tests/test_microsites.py b/lms/djangoapps/courseware/tests/test_microsites.py
index e58acda3cb..051002bee2 100644
--- a/lms/djangoapps/courseware/tests/test_microsites.py
+++ b/lms/djangoapps/courseware/tests/test_microsites.py
@@ -1,9 +1,12 @@
"""
-Tests related to the Site COnfiguration feature
+Tests related to the Site Configuration feature
"""
+from bs4 import BeautifulSoup
+from contextlib import contextmanager
from django.conf import settings
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
+from mock import patch
from nose.plugins.attrib import attr
from course_modes.models import CourseMode
@@ -129,6 +132,72 @@ class TestSites(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
# assert that footer template has been properly overriden on homepage
self.assertNotContains(resp, 'This is a Test Site footer')
+ @override_settings(SITE_NAME=settings.MICROSITE_TEST_HOSTNAME)
+ def test_site_homepage_course_max(self):
+ """
+ Verify that the number of courses displayed on the homepage honors
+ the HOMEPAGE_COURSE_MAX setting.
+ """
+ @contextmanager
+ def homepage_course_max_site_config(limit):
+ """Temporarily set the microsite HOMEPAGE_COURSE_MAX setting to desired value."""
+ with patch.dict(settings.MICROSITE_CONFIGURATION, {
+ 'test_site': dict(
+ settings.MICROSITE_CONFIGURATION['test_site'],
+ HOMEPAGE_COURSE_MAX=limit,
+ )
+ }):
+ yield
+
+ def assert_displayed_course_count(response, expected_count):
+ """Assert that the number of courses displayed matches the expectation."""
+ soup = BeautifulSoup(response.content, 'html.parser')
+ courses = soup.find_all(class_='course')
+ self.assertEqual(len(courses), expected_count)
+
+ # By default the number of courses on the homepage is not limited.
+ # We should see both courses and no link to all courses.
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 2)
+ self.assertNotContains(resp, 'View all Courses')
+
+ # With the limit set to 5, we should still see both courses and no link to all courses.
+ with homepage_course_max_site_config(5):
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 2)
+ self.assertNotContains(resp, 'View all Courses')
+
+ # With the limit set to 2, we should still see both courses and no link to all courses.
+ with homepage_course_max_site_config(2):
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 2)
+ self.assertNotContains(resp, 'View all Courses')
+
+ # With the limit set to 1, we should only see one course.
+ # We should also see the link to all courses.
+ with homepage_course_max_site_config(1):
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 1)
+ self.assertContains(resp, 'View all Courses')
+
+ # If no site configuration is set, the limit falls back to settings.HOMEPAGE_COURSE_MAX.
+ with override_settings(HOMEPAGE_COURSE_MAX=1):
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 1)
+ self.assertContains(resp, 'View all Courses')
+
+ # Site configuration takes precedence over settings when both are set.
+ with homepage_course_max_site_config(2), override_settings(HOMEPAGE_COURSE_MAX=1):
+ resp = self.client.get('/', HTTP_HOST=settings.MICROSITE_TEST_HOSTNAME)
+ self.assertEqual(resp.status_code, 200)
+ assert_displayed_course_count(resp, 2)
+ self.assertNotContains(resp, 'View all Courses')
+
@override_settings(SITE_NAME=settings.MICROSITE_TEST_HOSTNAME)
def test_site_anonymous_copyright_content(self):
"""
diff --git a/lms/templates/courses_list.html b/lms/templates/courses_list.html
index e091b4db20..18b8851b7c 100644
--- a/lms/templates/courses_list.html
+++ b/lms/templates/courses_list.html
@@ -9,7 +9,7 @@
## limiting the course number by using HOMEPAGE_COURSE_MAX as the maximum number of courses
- %for course in courses[:settings.HOMEPAGE_COURSE_MAX]:
+ %for course in courses[:homepage_course_max]: