Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions lms/djangoapps/courseware/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,14 @@ def get_course_about_section(course, section_key):
html = ''

if about_module is not None:
html = about_module.render('student_view').content

try:
html = about_module.render('student_view').content
except Exception: # pylint: disable=broad-except
html = "Error message"
log.exception("Error rendering course={course}, section_key={section_key}".format(
course=course,
section_key=section_key
))
return html

except ItemNotFoundError:
Expand Down Expand Up @@ -231,7 +237,13 @@ def get_course_info_section(request, course, section_key):
html = ''

if info_module is not None:
html = info_module.render('student_view').content
try:
html = info_module.render('student_view').content
except Exception: # pylint: disable=broad-except
log.exception("Error rendering course={course}, section_key={section_key}".format(
course=course,
section_key=section_key
))

return html

Expand Down
13 changes: 10 additions & 3 deletions lms/djangoapps/courseware/tabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,8 @@ def get_static_tab_by_slug(course, tab_slug):

def get_static_tab_contents(request, course, tab):
loc = Location(course.location.tag, course.location.org, course.location.course, 'static_tab', tab['url_slug'])
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course.id,
request.user, modulestore().get_instance(course.id, loc), depth=0)
field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
course.id, request.user, modulestore().get_instance(course.id, loc), depth=0)
tab_module = get_module(request.user, request, loc, field_data_cache, course.id,
static_asset_path=course.static_asset_path)

Expand All @@ -419,6 +419,13 @@ def get_static_tab_contents(request, course, tab):
html = ''

if tab_module is not None:
html = tab_module.render('student_view').content
try:
html = tab_module.render('student_view').content
except Exception: # pylint: disable=broad-except
html = "Error message"
log.exception("Error rendering course={course}, tab={tab_url}".format(
course=course,
tab_url=tab['url_slug']
))

return html
60 changes: 36 additions & 24 deletions lms/djangoapps/courseware/tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,57 @@

from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.test.client import RequestFactory

from student.models import Registration

from django.test import TestCase


def check_for_get_code(self, code, url):
"""
Check that we got the expected code when accessing url via GET.
Returns the HTTP response.
"""
Check that we got the expected code when accessing url via GET.
Returns the HTTP response.

`self` is a class that subclasses TestCase.
`self` is a class that subclasses TestCase.

`code` is a status code for HTTP responses.
`code` is a status code for HTTP responses.

`url` is a url pattern for which we have to test the response.
"""
resp = self.client.get(url)
self.assertEqual(resp.status_code, code,
"got code %d for url '%s'. Expected code %d"
% (resp.status_code, url, code))
return resp
`url` is a url pattern for which we have to test the response.
"""
resp = self.client.get(url)
self.assertEqual(resp.status_code, code,
"got code %d for url '%s'. Expected code %d"
% (resp.status_code, url, code))
return resp


def check_for_post_code(self, code, url, data={}):
"""
Check that we got the expected code when accessing url via POST.
Returns the HTTP response.
`self` is a class that subclasses TestCase.
"""
Check that we got the expected code when accessing url via POST.
Returns the HTTP response.
`self` is a class that subclasses TestCase.

`code` is a status code for HTTP responses.
`code` is a status code for HTTP responses.

`url` is a url pattern for which we want to test the response.
"""
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, code,
"got code %d for url '%s'. Expected code %d"
% (resp.status_code, url, code))
return resp
`url` is a url pattern for which we want to test the response.
"""
resp = self.client.post(url, data)
self.assertEqual(resp.status_code, code,
"got code %d for url '%s'. Expected code %d"
% (resp.status_code, url, code))
return resp


def get_request_for_user(user):
"""Create a request object for user."""

request = RequestFactory()
request.user = user
request.META = {}
request.is_secure = lambda: True
request.get_host = lambda: "edx.org"
return request


class LoginEnrollmentTestCase(TestCase):
Expand Down
47 changes: 44 additions & 3 deletions lms/djangoapps/courseware/tests/test_courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from django.http import Http404
from django.test.utils import override_settings
from courseware.courses import get_course_by_id, get_course, get_cms_course_link
from courseware.courses import get_course_by_id, get_course, get_cms_course_link, get_course_info_section, get_course_about_section
from student.tests.factories import UserFactory
from xmodule.modulestore.django import get_default_store_name_for_current_request
from xmodule.modulestore.tests.factories import CourseFactory
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE

from courseware.tests.helpers import get_request_for_user
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE, TEST_DATA_MIXED_MODULESTORE

CMS_BASE_TEST = 'testcms'

Expand Down Expand Up @@ -79,3 +80,43 @@ def test_default_modulestore_preview_mapping(self):
)
def test_default_modulestore_published_mapping(self):
self.assertEqual(get_default_store_name_for_current_request(), 'default')


class CoursesRenderTest(ModuleStoreTestCase):
"""Test methods related to rendering courses content."""

@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
def test_get_course_info_section_render(self):
course = get_course_by_id('edX/toy/2012_Fall')
request = get_request_for_user(UserFactory.create())

# Test render works okay
course_info = get_course_info_section(request, course, 'handouts')
self.assertEqual(course_info, "<a href='/static/toy/handouts/sample_handout.txt'>Sample</a>")

# Test when render raises an exception
with mock.patch('courseware.courses.get_module') as mock_module_render:
mock_module_render.return_value = mock.MagicMock(
render=mock.Mock(side_effect=Exception('Render failed!'))
)
course_info = get_course_info_section(request, course, 'handouts')
self.assertIsInstance(course_info, basestring)

@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
@mock.patch('courseware.courses.get_request_for_thread')
def test_get_course_about_section_render(self, mock_get_request):
course = get_course_by_id('edX/toy/2012_Fall')
request = get_request_for_user(UserFactory.create())
mock_get_request.return_value = request

# Test render works okay
course_info = get_course_about_section(course, 'effort')
self.assertEqual(course_info, "6 hours")

# Test when render raises an exception
with mock.patch('courseware.courses.get_module') as mock_module_render:
mock_module_render.return_value = mock.MagicMock(
render=mock.Mock(side_effect=Exception('Render failed!'))
)
course_info = get_course_about_section(course, 'effort')
self.assertIsInstance(course_info, basestring)
35 changes: 30 additions & 5 deletions lms/djangoapps/courseware/tests/test_tabs.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
from django.test import TestCase
from mock import MagicMock
from mock import patch
from mock import MagicMock, Mock, patch

import courseware.tabs as tabs
from courseware import tabs
from courseware.courses import get_course_by_id

from django.test.utils import override_settings
from django.core.urlresolvers import reverse

from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from courseware.tests.helpers import get_request_for_user
from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE


FAKE_REQUEST = None


def tab_constructor(active_page, course, user, tab={'name': 'same'}, generator=tabs._progress):
return generator(tab, user, course, active_page, FAKE_REQUEST)


class ProgressTestCase(TestCase):

def setUp(self):
Expand Down Expand Up @@ -112,7 +117,7 @@ def test_external_link(self):
self.assertEqual(tab_list[0].is_active, False)


class StaticTabTestCase(TestCase):
class StaticTabTestCase(ModuleStoreTestCase):

def setUp(self):

Expand All @@ -133,7 +138,7 @@ def test_static_tab(self):
tab_list = tab_constructor(
self.schmug, self.course, self.user, tab=self.tabby, generator=tabs._static_tab
)
expected_link = reverse('static_tab', args=[self.course.id,self.tabby['url_slug']])
expected_link = reverse('static_tab', args=[self.course.id, self.tabby['url_slug']])
self.assertEqual(tab_list[0].link, expected_link)

tab_list = tab_constructor(
Expand All @@ -146,6 +151,26 @@ def test_static_tab(self):
)
self.assertEqual(tab_list[0].is_active, False)

@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
def test_get_static_tab_contents(self):
course = get_course_by_id('edX/toy/2012_Fall')
request = get_request_for_user(UserFactory.create())
tab = tabs.get_static_tab_by_slug(course, 'resources')

# Test render works okay
tab_content = tabs.get_static_tab_contents(request, course, tab)
self.assertIn('edX/toy/2012_Fall', tab_content)
self.assertIn('static_tab', tab_content)

# Test when render raises an exception
with patch('courseware.tabs.get_module') as mock_module_render:
mock_module_render.return_value = MagicMock(
render=Mock(side_effect=Exception('Render failed!'))
)
course_info = tabs.get_static_tab_contents(request, course, tab)
self.assertIsInstance(course_info, basestring)


class TextbooksTestCase(TestCase):

def setUp(self):
Expand Down