Add a TestCase mixin for enabling caches in tests

By default, disable all caching in tests, to preserve test independence.
In order to enable caching, inherit from CacheSetupMixin, and specify
which cache configuration is needed.

[EV-32]
This commit is contained in:
Calen Pennington
2016-04-14 16:21:54 -04:00
parent 18e1610043
commit 853bfe7a36
47 changed files with 624 additions and 272 deletions

View File

@@ -52,6 +52,8 @@ class FieldOverridePerformanceTestCase(ProceduralCourseTestMixin,
# TEST_DATA must be overridden by subclasses
TEST_DATA = None
ENABLED_CACHES = ['default', 'mongo_metadata_inheritance', 'loc_cache']
def setUp(self):
"""
Create a test client, course, and user.

View File

@@ -68,6 +68,8 @@ from lms.djangoapps.ccx.tests.utils import (
from lms.djangoapps.ccx.utils import is_email
from lms.djangoapps.ccx.views import get_date
from xmodule.modulestore.django import modulestore
def intercept_renderer(path, context):
"""
@@ -184,10 +186,6 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
Tests for Custom Courses views.
"""
@classmethod
def setUpClass(cls):
super(TestCoachDashboard, cls).setUpClass()
def setUp(self):
"""
Set up tests
@@ -206,31 +204,6 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
allow_access(self.course, instructor, 'instructor')
self.assertTrue(CourseInstructorRole(self.course.id).has_user(instructor))
def assert_elements_in_schedule(self, url, n_chapters=2, n_sequentials=4, n_verticals=8):
"""
Helper function to count visible elements in the schedule
"""
response = self.client.get(url)
# the schedule contains chapters
chapters = json.loads(response.mako_context['schedule']) # pylint: disable=no-member
sequentials = flatten([chapter.get('children', []) for chapter in chapters])
verticals = flatten([sequential.get('children', []) for sequential in sequentials])
# check that the numbers of nodes at different level are the expected ones
self.assertEqual(n_chapters, len(chapters))
self.assertEqual(n_sequentials, len(sequentials))
self.assertEqual(n_verticals, len(verticals))
# extract the locations of all the nodes
all_elements = chapters + sequentials + verticals
return [elem['location'] for elem in all_elements if 'location' in elem]
def hide_node(self, node):
"""
Helper function to set the node `visible_to_staff_only` property
to True and save the change
"""
node.visible_to_staff_only = True
self.mstore.update_item(node, self.coach.id)
def test_not_a_coach(self):
"""
User is not a coach, should get Forbidden response.
@@ -352,43 +325,6 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
self.assertEqual(get_date(ccx, unit, 'start', parent_node=subsection), self.mooc_start)
self.assertEqual(get_date(ccx, unit, 'due', parent_node=subsection), self.mooc_due)
@SharedModuleStoreTestCase.modifies_courseware
@patch('ccx.views.render_to_response', intercept_renderer)
@patch('ccx.views.TODAY')
def test_get_ccx_schedule(self, today):
"""
Gets CCX schedule and checks number of blocks in it.
Hides nodes at a different depth and checks that these nodes
are not in the schedule.
"""
today.return_value = datetime.datetime(2014, 11, 25, tzinfo=pytz.UTC)
self.make_coach()
ccx = self.make_ccx()
url = reverse(
'ccx_coach_dashboard',
kwargs={
'course_id': CCXLocator.from_course_locator(
self.course.id, ccx.id)
}
)
# all the elements are visible
self.assert_elements_in_schedule(url)
# hide a vertical
vertical = self.verticals[0]
self.hide_node(vertical)
locations = self.assert_elements_in_schedule(url, n_verticals=7)
self.assertNotIn(unicode(vertical.location), locations)
# hide a sequential
sequential = self.sequentials[0]
self.hide_node(sequential)
locations = self.assert_elements_in_schedule(url, n_sequentials=3, n_verticals=6)
self.assertNotIn(unicode(sequential.location), locations)
# hide a chapter
chapter = self.chapters[0]
self.hide_node(chapter)
locations = self.assert_elements_in_schedule(url, n_chapters=1, n_sequentials=2, n_verticals=4)
self.assertNotIn(unicode(chapter.location), locations)
@patch('ccx.views.render_to_response', intercept_renderer)
@patch('ccx.views.TODAY')
def test_edit_schedule(self, today):
@@ -842,6 +778,134 @@ class TestCoachDashboard(CcxTestCase, LoginEnrollmentTestCase):
)
@attr('shard_1')
class TestCoachDashboardSchedule(CcxTestCase, LoginEnrollmentTestCase, ModuleStoreTestCase):
"""
Tests of the CCX Coach Dashboard which need to modify the course content.
"""
ENABLED_CACHES = ['default', 'mongo_inheritance_cache', 'loc_cache']
def setUp(self):
super(TestCoachDashboardSchedule, self).setUp()
self.course = course = CourseFactory.create()
# Create a course outline
self.mooc_start = start = datetime.datetime(
2010, 5, 12, 2, 42, tzinfo=pytz.UTC
)
self.mooc_due = due = datetime.datetime(
2010, 7, 7, 0, 0, tzinfo=pytz.UTC
)
self.chapters = [
ItemFactory.create(start=start, parent=course) for _ in xrange(2)
]
self.sequentials = flatten([
[
ItemFactory.create(parent=chapter) for _ in xrange(2)
] for chapter in self.chapters
])
self.verticals = flatten([
[
ItemFactory.create(
start=start, due=due, parent=sequential, graded=True, format='Homework', category=u'vertical'
) for _ in xrange(2)
] for sequential in self.sequentials
])
# Trying to wrap the whole thing in a bulk operation fails because it
# doesn't find the parents. But we can at least wrap this part...
with self.store.bulk_operations(course.id, emit_signals=False):
blocks = flatten([ # pylint: disable=unused-variable
[
ItemFactory.create(parent=vertical) for _ in xrange(2)
] for vertical in self.verticals
])
# Create instructor account
self.coach = UserFactory.create()
# create an instance of modulestore
self.mstore = modulestore()
# Login with the instructor account
self.client.login(username=self.coach.username, password="test")
# adding staff to master course.
staff = UserFactory()
allow_access(self.course, staff, 'staff')
self.assertTrue(CourseStaffRole(self.course.id).has_user(staff))
# adding instructor to master course.
instructor = UserFactory()
allow_access(self.course, instructor, 'instructor')
self.assertTrue(CourseInstructorRole(self.course.id).has_user(instructor))
self.assertTrue(modulestore().has_course(self.course.id))
def assert_elements_in_schedule(self, url, n_chapters=2, n_sequentials=4, n_verticals=8):
"""
Helper function to count visible elements in the schedule
"""
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
# the schedule contains chapters
chapters = json.loads(response.mako_context['schedule']) # pylint: disable=no-member
sequentials = flatten([chapter.get('children', []) for chapter in chapters])
verticals = flatten([sequential.get('children', []) for sequential in sequentials])
# check that the numbers of nodes at different level are the expected ones
self.assertEqual(n_chapters, len(chapters))
self.assertEqual(n_sequentials, len(sequentials))
self.assertEqual(n_verticals, len(verticals))
# extract the locations of all the nodes
all_elements = chapters + sequentials + verticals
return [elem['location'] for elem in all_elements if 'location' in elem]
def hide_node(self, node):
"""
Helper function to set the node `visible_to_staff_only` property
to True and save the change
"""
node.visible_to_staff_only = True
self.mstore.update_item(node, self.coach.id)
@patch('ccx.views.render_to_response', intercept_renderer)
@patch('ccx.views.TODAY')
def test_get_ccx_schedule(self, today):
"""
Gets CCX schedule and checks number of blocks in it.
Hides nodes at a different depth and checks that these nodes
are not in the schedule.
"""
today.return_value = datetime.datetime(2014, 11, 25, tzinfo=pytz.UTC)
self.make_coach()
ccx = self.make_ccx()
url = reverse(
'ccx_coach_dashboard',
kwargs={
'course_id': CCXLocator.from_course_locator(
self.course.id, ccx.id)
}
)
# all the elements are visible
self.assert_elements_in_schedule(url)
# hide a vertical
vertical = self.verticals[0]
self.hide_node(vertical)
locations = self.assert_elements_in_schedule(url, n_verticals=7)
self.assertNotIn(unicode(vertical.location), locations)
# hide a sequential
sequential = self.sequentials[0]
self.hide_node(sequential)
locations = self.assert_elements_in_schedule(url, n_sequentials=3, n_verticals=6)
self.assertNotIn(unicode(sequential.location), locations)
# hide a chapter
chapter = self.chapters[0]
self.hide_node(chapter)
locations = self.assert_elements_in_schedule(url, n_chapters=1, n_sequentials=2, n_verticals=4)
self.assertNotIn(unicode(chapter.location), locations)
GET_CHILDREN = XModuleMixin.get_children