Commit a12f7ae5 by Andy Armstrong Committed by GitHub

Merge pull request #15021 from edx/andya/enable-course-sidebar

Enable course sidebar for new course home page
parents 08dcbace 9ce46a3f
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
Test cases for tabs. Test cases for tabs.
""" """
import waffle from waffle.testutils import override_flag
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import Http404 from django.http import Http404
...@@ -781,10 +781,9 @@ class CourseInfoTabTestCase(TabTestCase): ...@@ -781,10 +781,9 @@ class CourseInfoTabTestCase(TabTestCase):
tabs = get_course_tab_list(self.request, self.course) tabs = get_course_tab_list(self.request, self.course)
self.assertEqual(tabs[0].type, 'course_info') self.assertEqual(tabs[0].type, 'course_info')
@patch('waffle.flag_is_active') @override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
def test_default_tab_for_new_course_experience(self, patched_flag_is_active): def test_default_tab_for_new_course_experience(self):
# Verify that the unified course experience hides the course info tab # Verify that the unified course experience hides the course info tab
patched_flag_is_active.return_value = True
tabs = get_course_tab_list(self.request, self.course) tabs = get_course_tab_list(self.request, self.course)
self.assertEqual(tabs[0].type, 'courseware') self.assertEqual(tabs[0].type, 'courseware')
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
from datetime import datetime from datetime import datetime
from pytz import timezone, utc from pytz import timezone, utc
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from courseware.courses import get_course_info_section, get_course_date_blocks from courseware.courses import get_course_info_section, get_course_date_blocks
...@@ -113,6 +114,13 @@ from openedx.core.djangolib.markup import HTML, Text ...@@ -113,6 +114,13 @@ from openedx.core.djangolib.markup import HTML, Text
</section> </section>
<section aria-label="${_('Handout Navigation')}" class="handouts"> <section aria-label="${_('Handout Navigation')}" class="handouts">
<h3 class="hd hd-3 handouts-header">${_("Course Tools")}</h3>
<div>
<a class="action-show-bookmarks" href="${reverse('openedx.course_bookmarks.home', args=[course.id])}">
<span class="icon fa fa-bookmark" aria-hidden="true"></span>
${_("Bookmarks")}
</a>
</div>
% if SelfPacedConfiguration.current().enable_course_home_improvements: % if SelfPacedConfiguration.current().enable_course_home_improvements:
${HTML(dates_fragment.body_html())} ${HTML(dates_fragment.body_html())}
......
...@@ -23,13 +23,7 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG ...@@ -23,13 +23,7 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
<header class="page-header has-secondary"> <header class="page-header has-secondary">
<div class="page-header-main"> <div class="page-header-main">
<nav aria-label="${_('Course Outline')}" class="sr-is-focusable" tabindex="-1"> <nav aria-label="${_('Course Outline')}" class="sr-is-focusable" tabindex="-1">
% if waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG): <h2 class="hd hd-3 page-title">${course.display_name_with_default}</h2>
<h2 class="hd hd-3 page-title">
${_("{course_name}").format(org=course.display_org_with_default, course_name=course.display_name_with_default)}
</h2>
% else:
<h2 class="hd hd-2 page-title">${_('Course Outline')}</h2>
% endif
</nav> </nav>
</div> </div>
<div class="page-header-secondary"> <div class="page-header-secondary">
...@@ -49,11 +43,6 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG ...@@ -49,11 +43,6 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
</div> </div>
% endif % endif
<div class="form-actions"> <div class="form-actions">
% if not waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG):
<a class="btn action-show-bookmarks" href="${reverse('openedx.course_bookmarks.home', args=[course_key])}">
${_("Bookmarks")}
</a>
% endif
% if resume_course_url: % if resume_course_url:
<a class="btn btn-brand action-resume-course" href="${resume_course_url}"> <a class="btn btn-brand action-resume-course" href="${resume_course_url}">
% if has_visited_course: % if has_visited_course:
...@@ -67,43 +56,41 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG ...@@ -67,43 +56,41 @@ from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
</div> </div>
</header> </header>
<div class="page-content"> <div class="page-content">
% if waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG): <div class="layout layout-1q3q">
<div class="layout layout-1q3q"> <main class="layout-col layout-col-b">
<main class="layout-col layout-col-b"> ${HTML(outline_fragment.body_html())}
${HTML(outline_fragment.body_html())} </main>
</main> <aside class="course-sidebar layout-col layout-col-a">
<aside class="course-sidebar layout-col layout-col-a"> <div class="section section-tools">
<div class="section section-tools"> <h3 class="hd-6">${_("Course Tools")}</h3>
<h3 class="hd-6">${_("Course Tools")}</h3> <ul class="list-unstyled">
<ul class="list-unstyled"> <li>
<a href="${reverse('openedx.course_bookmarks.home', args=[course_key])}">
<span class="icon fa fa-bookmark" aria-hidden="true"></span>
${_("Bookmarks")}
</a>
</li>
% if waffle.flag_is_active(request, UNIFIED_COURSE_EXPERIENCE_FLAG):
<li> <li>
<a class="action-show-bookmarks" href="${reverse('openedx.course_bookmarks.home', args=[course_key])}"> <a href="${reverse('openedx.course_experience.course_updates', args=[course.id])}">
<span class="icon fa fa-bookmark" aria-hidden="true"></span>
${_("Bookmarks")}
</a>
</li>
<li>
<a class="action-show-bookmarks" href="${reverse('openedx.course_experience.course_updates', args=[course.id])}">
<span class="icon fa fa-newspaper-o" aria-hidden="true"></span> <span class="icon fa fa-newspaper-o" aria-hidden="true"></span>
${_("Updates")} ${_("Updates")}
</a> </a>
</li> </li>
</ul> % endif
</div> </ul>
<div class="section section-dates"> </div>
${HTML(dates_fragment.body_html())} <div class="section section-dates">
${HTML(dates_fragment.body_html())}
</div>
% if handouts_html:
<div class="section section-handouts">
<h3 class="hd-6">${_("Course Handouts")}</h3>
${HTML(handouts_html)}
</div> </div>
% if handouts_html: % endif
<div class="section section-handouts"> </aside>
<h3 class="hd-6">${_("Course Handouts")}</h3> </div>
${HTML(handouts_html)}
</div>
% endif
</aside>
</div>
% else:
${HTML(outline_fragment.body_html())}
% endif
</div> </div>
</div> </div>
</%block> </%block>
""" """
Tests for the course home page. Tests for the course home page.
""" """
from waffle.testutils import override_flag
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from openedx.core.djangoapps.content.block_structure.api import get_course_in_cache from openedx.core.djangoapps.content.block_structure.api import get_course_in_cache
...@@ -10,6 +13,8 @@ from xmodule.modulestore import ModuleStoreEnum ...@@ -10,6 +13,8 @@ from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
from openedx.features.course_experience import UNIFIED_COURSE_EXPERIENCE_FLAG
TEST_PASSWORD = 'test' TEST_PASSWORD = 'test'
...@@ -36,7 +41,7 @@ class TestCourseHomePage(SharedModuleStoreTestCase): ...@@ -36,7 +41,7 @@ class TestCourseHomePage(SharedModuleStoreTestCase):
# pylint: disable=super-method-not-called # pylint: disable=super-method-not-called
with super(TestCourseHomePage, cls).setUpClassAndTestData(): with super(TestCourseHomePage, cls).setUpClassAndTestData():
with cls.store.default_store(ModuleStoreEnum.Type.split): with cls.store.default_store(ModuleStoreEnum.Type.split):
cls.course = CourseFactory.create() cls.course = CourseFactory.create(org='edX', number='test', display_name='Test Course')
with cls.store.bulk_operations(cls.course.id): with cls.store.bulk_operations(cls.course.id):
chapter = ItemFactory.create(category='chapter', parent_location=cls.course.location) chapter = ItemFactory.create(category='chapter', parent_location=cls.course.location)
section = ItemFactory.create(category='sequential', parent_location=chapter.location) section = ItemFactory.create(category='sequential', parent_location=chapter.location)
...@@ -57,6 +62,15 @@ class TestCourseHomePage(SharedModuleStoreTestCase): ...@@ -57,6 +62,15 @@ class TestCourseHomePage(SharedModuleStoreTestCase):
super(TestCourseHomePage, self).setUp() super(TestCourseHomePage, self).setUp()
self.client.login(username=self.user.username, password=TEST_PASSWORD) self.client.login(username=self.user.username, password=TEST_PASSWORD)
@override_flag(UNIFIED_COURSE_EXPERIENCE_FLAG, active=True)
def test_unified_page(self):
"""
Verify the rendering of the unified page.
"""
url = course_home_url(self.course)
response = self.client.get(url)
self.assertContains(response, '<h2 class="hd hd-3 page-title">Test Course</h2>')
def test_queries(self): def test_queries(self):
""" """
Verify that the view's query count doesn't regress. Verify that the view's query count doesn't regress.
...@@ -65,7 +79,7 @@ class TestCourseHomePage(SharedModuleStoreTestCase): ...@@ -65,7 +79,7 @@ class TestCourseHomePage(SharedModuleStoreTestCase):
get_course_in_cache(self.course.id) get_course_in_cache(self.course.id)
# Fetch the view and verify the query counts # Fetch the view and verify the query counts
with self.assertNumQueries(37): with self.assertNumQueries(35):
with check_mongo_calls(3): with check_mongo_calls(3):
url = course_home_url(self.course) url = course_home_url(self.course)
self.client.get(url) self.client.get(url)
...@@ -96,14 +96,16 @@ class CourseHomeFragmentView(EdxFragmentView): ...@@ -96,14 +96,16 @@ class CourseHomeFragmentView(EdxFragmentView):
# Render the course dates as a fragment # Render the course dates as a fragment
dates_fragment = CourseDatesFragmentView().render_to_fragment(request, course_id=course_id, **kwargs) dates_fragment = CourseDatesFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)
# Get the handouts
# TODO: Use get_course_overview_with_access and blocks api # TODO: Use get_course_overview_with_access and blocks api
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
# Get the handouts
handouts_html = get_course_info_section(request, request.user, course, 'handouts') handouts_html = get_course_info_section(request, request.user, course, 'handouts')
# Render the course home fragment # Render the course home fragment
context = { context = {
'csrf': csrf(request)['csrf_token'], 'csrf': csrf(request)['csrf_token'],
'course': course,
'course_key': course_key, 'course_key': course_key,
'course': course, 'course': course,
'outline_fragment': outline_fragment, 'outline_fragment': outline_fragment,
......
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