diff --git a/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py b/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
index 293c49c556..9d80d29bd1 100644
--- a/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
+++ b/common/lib/xmodule/xmodule/modulestore/tests/django_utils.py
@@ -3,6 +3,7 @@
Modulestore configuration for test cases.
"""
import datetime
+import functools
import pytz
from uuid import uuid4
@@ -220,7 +221,8 @@ class SharedModuleStoreTestCase(TestCase):
Subclass for any test case that uses a ModuleStore that can be shared
between individual tests. This class ensures that the ModuleStore is cleaned
before/after the entire test case has run. Use this class if your tests
- set up one or a small number of courses that individual tests do not modify.
+ set up one or a small number of courses that individual tests do not modify
+ (or modify extermely rarely -- see @modifies_courseware).
If your tests modify contents in the ModuleStore, you should use
ModuleStoreTestCase instead.
@@ -279,6 +281,52 @@ class SharedModuleStoreTestCase(TestCase):
OverrideFieldData.provider_classes = None
super(SharedModuleStoreTestCase, self).setUp()
+ def reset(self):
+ """
+ Manually run tearDownClass/setUpClass again.
+
+ This is so that if you have a mostly read-only course that you're just
+ modifying in one test, you can write `self.reset()` at the
+ end of that test and reset the state of the world for other tests in
+ the class.
+ """
+ self.tearDownClass()
+ self.setUpClass()
+
+ @staticmethod
+ def modifies_courseware(f):
+ """
+ Decorator to place around tests that modify course content.
+
+ For performance reasons, SharedModuleStoreTestCase intentionally does
+ not reset the modulestore between individual tests. However, sometimes
+ you might have a test case where the vast majority of tests treat a
+ course as read-only, but one or two want to modify it. In that case, you
+ can do this:
+
+ class MyTestCase(SharedModuleStoreTestCase):
+ # ...
+ @SharedModuleStoreTestCase.modifies_courseware
+ def test_that_edits_modulestore(self):
+ do_something()
+
+ This is equivalent to calling `self.reset()` at the end of
+ your test.
+
+ If you find yourself using this functionality a lot, it might indicate
+ that you should be using ModuleStoreTestCase instead, or that you should
+ break up your tests into different TestCases.
+ """
+ @functools.wraps(f)
+ def wrapper(*args, **kwargs):
+ """Call the object method, and reset the test case afterwards."""
+ return_val = f(*args, **kwargs)
+ obj = args[0]
+ obj.reset()
+ return return_val
+
+ return wrapper
+
class ModuleStoreTestCase(TestCase):
"""
diff --git a/lms/djangoapps/instructor/tests/test_access.py b/lms/djangoapps/instructor/tests/test_access.py
index 7ddbd7233e..f66d3957a0 100644
--- a/lms/djangoapps/instructor/tests/test_access.py
+++ b/lms/djangoapps/instructor/tests/test_access.py
@@ -6,7 +6,7 @@ from nose.tools import raises
from nose.plugins.attrib import attr
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.factories import CourseFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from student.roles import CourseBetaTesterRole, CourseStaffRole
@@ -19,13 +19,15 @@ from instructor.access import (allow_access,
@attr('shard_1')
-class TestInstructorAccessList(ModuleStoreTestCase):
+class TestInstructorAccessList(SharedModuleStoreTestCase):
""" Test access listings. """
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAccessList, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
def setUp(self):
super(TestInstructorAccessList, self).setUp()
-
- self.course = CourseFactory.create()
-
self.instructors = [UserFactory.create() for _ in xrange(4)]
for user in self.instructors:
allow_access(self.course, user, 'instructor')
@@ -43,8 +45,13 @@ class TestInstructorAccessList(ModuleStoreTestCase):
@attr('shard_1')
-class TestInstructorAccessAllow(ModuleStoreTestCase):
+class TestInstructorAccessAllow(SharedModuleStoreTestCase):
""" Test access allow. """
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAccessAllow, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
def setUp(self):
super(TestInstructorAccessAllow, self).setUp()
@@ -79,13 +86,15 @@ class TestInstructorAccessAllow(ModuleStoreTestCase):
@attr('shard_1')
-class TestInstructorAccessRevoke(ModuleStoreTestCase):
+class TestInstructorAccessRevoke(SharedModuleStoreTestCase):
""" Test access revoke. """
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAccessRevoke, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
def setUp(self):
super(TestInstructorAccessRevoke, self).setUp()
-
- self.course = CourseFactory.create()
-
self.staff = [UserFactory.create() for _ in xrange(4)]
for user in self.staff:
allow_access(self.course, user, 'staff')
@@ -115,15 +124,17 @@ class TestInstructorAccessRevoke(ModuleStoreTestCase):
@attr('shard_1')
-class TestInstructorAccessForum(ModuleStoreTestCase):
+class TestInstructorAccessForum(SharedModuleStoreTestCase):
"""
Test forum access control.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAccessForum, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
def setUp(self):
super(TestInstructorAccessForum, self).setUp()
-
- self.course = CourseFactory.create()
-
self.mod_role = Role.objects.create(
course_id=self.course.id,
name=FORUM_ROLE_MODERATOR
diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py
index 1703ae7960..9dfc50f26e 100644
--- a/lms/djangoapps/instructor/tests/test_api.py
+++ b/lms/djangoapps/instructor/tests/test_api.py
@@ -51,7 +51,7 @@ from student.tests.factories import UserFactory, CourseModeFactory, AdminFactory
from student.roles import CourseBetaTesterRole, CourseSalesAdminRole, CourseFinanceAdminRole, CourseInstructorRole
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.django import modulestore
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.fields import Date
@@ -184,22 +184,26 @@ class TestCommonExceptions400(TestCase):
@attr('shard_1')
@patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message'))
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False})
-class TestInstructorAPIDenyLevels(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPIDenyLevels(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Ensure that users cannot access endpoints they shouldn't be able to.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIDenyLevels, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.problem_location = msk_from_problem_urlname(
+ cls.course.id,
+ 'robot-some-problem-urlname'
+ )
+ cls.problem_urlname = cls.problem_location.to_deprecated_string()
+
def setUp(self):
super(TestInstructorAPIDenyLevels, self).setUp()
- self.course = CourseFactory.create()
self.user = UserFactory.create()
CourseEnrollment.enroll(self.user, self.course.id)
- self.problem_location = msk_from_problem_urlname(
- self.course.id,
- 'robot-some-problem-urlname'
- )
- self.problem_urlname = self.problem_location.to_deprecated_string()
_module = StudentModule.objects.create(
student=self.user,
course_id=self.course.id,
@@ -347,18 +351,22 @@ class TestInstructorAPIDenyLevels(ModuleStoreTestCase, LoginEnrollmentTestCase):
@attr('shard_1')
@patch.dict(settings.FEATURES, {'ALLOW_AUTOMATED_SIGNUPS': True})
-class TestInstructorAPIBulkAccountCreationAndEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPIBulkAccountCreationAndEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test Bulk account creation and enrollment from csv file
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIBulkAccountCreationAndEnrollment, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.url = reverse('register_and_enroll_students', kwargs={'course_id': cls.course.id.to_deprecated_string()})
+
def setUp(self):
super(TestInstructorAPIBulkAccountCreationAndEnrollment, self).setUp()
self.request = RequestFactory().request()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
- self.url = reverse('register_and_enroll_students', kwargs={'course_id': self.course.id.to_deprecated_string()})
self.not_enrolled_student = UserFactory(
username='NotEnrolledStudent',
@@ -647,7 +655,7 @@ class TestInstructorAPIBulkAccountCreationAndEnrollment(ModuleStoreTestCase, Log
@attr('shard_1')
@ddt.ddt
-class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPIEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test enrollment modification endpoint.
@@ -655,11 +663,23 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
job of test_enrollment. This tests the response and action switch.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIEnrollment, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
+ # Email URL values
+ cls.site_name = microsite.get_value(
+ 'SITE_NAME',
+ settings.SITE_NAME
+ )
+ cls.about_path = '/courses/{}/about'.format(cls.course.id)
+ cls.course_path = '/courses/{}/'.format(cls.course.id)
+
def setUp(self):
super(TestInstructorAPIEnrollment, self).setUp()
self.request = RequestFactory().request()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -679,14 +699,6 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
self.notregistered_email = 'robot-not-an-email-yet@robot.org'
self.assertEqual(User.objects.filter(email=self.notregistered_email).count(), 0)
- # Email URL values
- self.site_name = microsite.get_value(
- 'SITE_NAME',
- settings.SITE_NAME
- )
- self.about_path = '/courses/{}/about'.format(self.course.id)
- self.course_path = '/courses/{}/'.format(self.course.id)
-
# uncomment to enable enable printing of large diffs
# from failed assertions in the event of a test failure.
# (comment because pylint C0103(invalid-name))
@@ -1399,15 +1411,25 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
@attr('shard_1')
@ddt.ddt
-class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPIBulkBetaEnrollment(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test bulk beta modify access endpoint.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIBulkBetaEnrollment, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ # Email URL values
+ cls.site_name = microsite.get_value(
+ 'SITE_NAME',
+ settings.SITE_NAME
+ )
+ cls.about_path = '/courses/{}/about'.format(cls.course.id)
+ cls.course_path = '/courses/{}/'.format(cls.course.id)
def setUp(self):
super(TestInstructorAPIBulkBetaEnrollment, self).setUp()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -1425,14 +1447,6 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
self.request = RequestFactory().request()
- # Email URL values
- self.site_name = microsite.get_value(
- 'SITE_NAME',
- settings.SITE_NAME
- )
- self.about_path = '/courses/{}/about'.format(self.course.id)
- self.course_path = '/courses/{}/'.format(self.course.id)
-
# uncomment to enable enable printing of large diffs
# from failed assertions in the event of a test failure.
# (comment because pylint C0103(invalid-name))
@@ -1720,7 +1734,7 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
@attr('shard_1')
-class TestInstructorAPILevelsAccess(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPILevelsAccess(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test endpoints whereby instructors can change permissions
of other users.
@@ -1731,11 +1745,14 @@ class TestInstructorAPILevelsAccess(ModuleStoreTestCase, LoginEnrollmentTestCase
Actually, modify_access does not have a very meaningful
response yet, so only the status code is tested.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPILevelsAccess, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestInstructorAPILevelsAccess, self).setUp()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
@@ -1961,14 +1978,17 @@ class TestInstructorAPILevelsAccess(ModuleStoreTestCase, LoginEnrollmentTestCase
@attr('shard_1')
@ddt.ddt
@patch.dict('django.conf.settings.FEATURES', {'ENABLE_PAID_COURSE_REGISTRATION': True})
-class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPILevelsDataDump(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test endpoints that show data without side effects.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPILevelsDataDump, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestInstructorAPILevelsDataDump, self).setUp()
- self.course = CourseFactory.create()
self.course_mode = CourseMode(course_id=self.course.id,
mode_slug="honor",
mode_display_name="honor cert",
@@ -2539,9 +2559,11 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
body = response.content.replace('\r', '')
self.assertTrue(body.startswith(
'"User ID","Anonymized User ID","Course Specific Anonymized User ID"'
- '\n"3","41","42"\n'
+ '\n"{user_id}","41","42"\n'.format(user_id=self.students[0].id)
))
- self.assertTrue(body.endswith('"8","41","42"\n'))
+ self.assertTrue(
+ body.endswith('"{user_id}","41","42"\n'.format(user_id=self.students[-1].id))
+ )
def test_list_report_downloads(self):
url = reverse('list_report_downloads', kwargs={'course_id': self.course.id.to_deprecated_string()})
@@ -2664,7 +2686,7 @@ class TestInstructorAPILevelsDataDump(ModuleStoreTestCase, LoginEnrollmentTestCa
@attr('shard_1')
-class TestInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test endpoints whereby instructors can change student grades.
This includes resetting attempts and starting rescore tasks.
@@ -2672,23 +2694,24 @@ class TestInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollmentTestCase)
This test does NOT test whether the actions had an effect on the
database, that is the job of task tests and test_enrollment.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIRegradeTask, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.problem_location = msk_from_problem_urlname(
+ cls.course.id,
+ 'robot-some-problem-urlname'
+ )
+ cls.problem_urlname = cls.problem_location.to_deprecated_string()
def setUp(self):
super(TestInstructorAPIRegradeTask, self).setUp()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
- self.problem_location = msk_from_problem_urlname(
- self.course.id,
- 'robot-some-problem-urlname'
- )
-
- self.problem_urlname = self.problem_location.to_deprecated_string()
-
self.module_to_reset = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
@@ -2827,21 +2850,51 @@ class TestInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollmentTestCase)
@attr('shard_1')
@patch.dict(settings.FEATURES, {'ENTRANCE_EXAMS': True})
-class TestEntranceExamInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestEntranceExamInstructorAPIRegradeTask(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test endpoints whereby instructors can rescore student grades,
reset student attempts and delete state for entrance exam.
"""
-
- def setUp(self):
- super(TestEntranceExamInstructorAPIRegradeTask, self).setUp()
- self.course = CourseFactory.create(
+ @classmethod
+ def setUpClass(cls):
+ super(TestEntranceExamInstructorAPIRegradeTask, cls).setUpClass()
+ cls.course = CourseFactory.create(
org='test_org',
course='test_course',
run='test_run',
entrance_exam_id='i4x://{}/{}/chapter/Entrance_exam'.format('test_org', 'test_course')
)
- self.course_with_invalid_ee = CourseFactory.create(entrance_exam_id='invalid_exam')
+ cls.course_with_invalid_ee = CourseFactory.create(entrance_exam_id='invalid_exam')
+
+ with cls.store.bulk_operations(cls.course.id, emit_signals=False):
+ cls.entrance_exam = ItemFactory.create(
+ parent=cls.course,
+ category='chapter',
+ display_name='Entrance exam'
+ )
+ subsection = ItemFactory.create(
+ parent=cls.entrance_exam,
+ category='sequential',
+ display_name='Subsection 1'
+ )
+ vertical = ItemFactory.create(
+ parent=subsection,
+ category='vertical',
+ display_name='Vertical 1'
+ )
+ cls.ee_problem_1 = ItemFactory.create(
+ parent=vertical,
+ category="problem",
+ display_name="Exam Problem - Problem 1"
+ )
+ cls.ee_problem_2 = ItemFactory.create(
+ parent=vertical,
+ category="problem",
+ display_name="Exam Problem - Problem 2"
+ )
+
+ def setUp(self):
+ super(TestEntranceExamInstructorAPIRegradeTask, self).setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
# Add instructor to invalid ee course
@@ -2851,32 +2904,6 @@ class TestEntranceExamInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollm
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
- self.entrance_exam = ItemFactory.create(
- parent=self.course,
- category='chapter',
- display_name='Entrance exam'
- )
- subsection = ItemFactory.create(
- parent=self.entrance_exam,
- category='sequential',
- display_name='Subsection 1'
- )
- vertical = ItemFactory.create(
- parent=subsection,
- category='vertical',
- display_name='Vertical 1'
- )
- self.ee_problem_1 = ItemFactory.create(
- parent=vertical,
- category="problem",
- display_name="Exam Problem - Problem 1"
- )
- self.ee_problem_2 = ItemFactory.create(
- parent=vertical,
- category="problem",
- display_name="Exam Problem - Problem 2"
- )
-
ee_module_to_reset1 = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
@@ -3073,27 +3100,30 @@ class TestEntranceExamInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollm
@attr('shard_1')
@patch('bulk_email.models.html_to_text', Mock(return_value='Mocking CourseEmail.text_message'))
@patch.dict(settings.FEATURES, {'ENABLE_INSTRUCTOR_EMAIL': True, 'REQUIRE_COURSE_EMAIL_AUTH': False})
-class TestInstructorSendEmail(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorSendEmail(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Checks that only instructors have access to email endpoints, and that
these endpoints are only accessible with courses that actually exist,
only with valid email messages.
"""
-
- def setUp(self):
- super(TestInstructorSendEmail, self).setUp()
-
- self.course = CourseFactory.create()
- self.instructor = InstructorFactory(course_key=self.course.id)
- self.client.login(username=self.instructor.username, password='test')
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorSendEmail, cls).setUpClass()
+ cls.course = CourseFactory.create()
test_subject = u'\u1234 test subject'
test_message = u'\u6824 test message'
- self.full_test_message = {
+ cls.full_test_message = {
'send_to': 'staff',
'subject': test_subject,
'message': test_message,
}
+ def setUp(self):
+ super(TestInstructorSendEmail, self).setUp()
+
+ self.instructor = InstructorFactory(course_key=self.course.id)
+ self.client.login(username=self.instructor.username, password='test')
+
def test_send_email_as_logged_in_instructor(self):
url = reverse('send_email', kwargs={'course_id': self.course.id.to_deprecated_string()})
response = self.client.post(url, self.full_test_message)
@@ -3156,7 +3186,7 @@ class MockCompletionInfo(object):
@attr('shard_1')
-class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorAPITaskLists(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test instructor task list endpoint.
"""
@@ -3204,23 +3234,26 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
attr_dict['created'] = attr_dict['created'].isoformat()
return attr_dict
- def setUp(self):
- super(TestInstructorAPITaskLists, self).setUp()
- self.course = CourseFactory.create(
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPITaskLists, cls).setUpClass()
+ cls.course = CourseFactory.create(
entrance_exam_id='i4x://{}/{}/chapter/Entrance_exam'.format('test_org', 'test_course')
)
+ cls.problem_location = msk_from_problem_urlname(
+ cls.course.id,
+ 'robot-some-problem-urlname'
+ )
+ cls.problem_urlname = cls.problem_location.to_deprecated_string()
+
+ def setUp(self):
+ super(TestInstructorAPITaskLists, self).setUp()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
- self.problem_location = msk_from_problem_urlname(
- self.course.id,
- 'robot-some-problem-urlname'
- )
- self.problem_urlname = self.problem_location.to_deprecated_string()
-
self.module = StudentModule.objects.create(
student=self.student,
course_id=self.course.id,
@@ -3316,15 +3349,18 @@ class TestInstructorAPITaskLists(ModuleStoreTestCase, LoginEnrollmentTestCase):
@attr('shard_1')
@patch.object(instructor_task.api, 'get_instructor_task_history')
-class TestInstructorEmailContentList(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorEmailContentList(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test the instructor email content history endpoint.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorEmailContentList, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestInstructorEmailContentList, self).setUp()
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
self.tasks = {}
@@ -3500,10 +3536,30 @@ def get_extended_due(course, unit, user):
@attr('shard_1')
-class TestDueDateExtensions(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestDueDateExtensions(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Test data dumps for reporting.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestDueDateExtensions, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
+
+ with cls.store.bulk_operations(cls.course.id, emit_signals=False):
+ cls.week1 = ItemFactory.create(due=cls.due)
+ cls.week2 = ItemFactory.create(due=cls.due)
+ cls.week3 = ItemFactory.create() # No due date
+ cls.course.children = [
+ cls.week1.location.to_deprecated_string(),
+ cls.week2.location.to_deprecated_string(),
+ cls.week3.location.to_deprecated_string()
+ ]
+ cls.homework = ItemFactory.create(
+ parent_location=cls.week1.location,
+ due=cls.due
+ )
+ cls.week1.children = [cls.homework.location.to_deprecated_string()]
def setUp(self):
"""
@@ -3511,75 +3567,55 @@ class TestDueDateExtensions(ModuleStoreTestCase, LoginEnrollmentTestCase):
"""
super(TestDueDateExtensions, self).setUp()
- due = datetime.datetime(2010, 5, 12, 2, 42, tzinfo=utc)
- course = CourseFactory.create()
- week1 = ItemFactory.create(due=due)
- week2 = ItemFactory.create(due=due)
- week3 = ItemFactory.create() # No due date
- course.children = [week1.location.to_deprecated_string(), week2.location.to_deprecated_string(),
- week3.location.to_deprecated_string()]
-
- homework = ItemFactory.create(
- parent_location=week1.location,
- due=due
- )
- week1.children = [homework.location.to_deprecated_string()]
-
user1 = UserFactory.create()
StudentModule(
state='{}',
student_id=user1.id,
- course_id=course.id,
- module_state_key=week1.location).save()
+ course_id=self.course.id,
+ module_state_key=self.week1.location).save()
StudentModule(
state='{}',
student_id=user1.id,
- course_id=course.id,
- module_state_key=week2.location).save()
+ course_id=self.course.id,
+ module_state_key=self.week2.location).save()
StudentModule(
state='{}',
student_id=user1.id,
- course_id=course.id,
- module_state_key=week3.location).save()
+ course_id=self.course.id,
+ module_state_key=self.week3.location).save()
StudentModule(
state='{}',
student_id=user1.id,
- course_id=course.id,
- module_state_key=homework.location).save()
+ course_id=self.course.id,
+ module_state_key=self.homework.location).save()
user2 = UserFactory.create()
StudentModule(
state='{}',
student_id=user2.id,
- course_id=course.id,
- module_state_key=week1.location).save()
+ course_id=self.course.id,
+ module_state_key=self.week1.location).save()
StudentModule(
state='{}',
student_id=user2.id,
- course_id=course.id,
- module_state_key=homework.location).save()
+ course_id=self.course.id,
+ module_state_key=self.homework.location).save()
user3 = UserFactory.create()
StudentModule(
state='{}',
student_id=user3.id,
- course_id=course.id,
- module_state_key=week1.location).save()
+ course_id=self.course.id,
+ module_state_key=self.week1.location).save()
StudentModule(
state='{}',
student_id=user3.id,
- course_id=course.id,
- module_state_key=homework.location).save()
+ course_id=self.course.id,
+ module_state_key=self.homework.location).save()
- self.course = course
- self.week1 = week1
- self.homework = homework
- self.week2 = week2
- self.week3 = week3
self.user1 = user1
self.user2 = user2
-
- self.instructor = InstructorFactory(course_key=course.id)
+ self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
def test_change_due_date(self):
@@ -3640,6 +3676,7 @@ class TestDueDateExtensions(ModuleStoreTestCase, LoginEnrollmentTestCase):
})
self.assertEqual(response.status_code, 400, response.content)
+ @SharedModuleStoreTestCase.modifies_courseware
def test_reset_extension_to_deleted_date(self):
"""
Test that we can delete a due date extension after deleting the normal
@@ -3690,10 +3727,18 @@ class TestDueDateExtensions(ModuleStoreTestCase, LoginEnrollmentTestCase):
@attr('shard_1')
@override_settings(REGISTRATION_CODE_LENGTH=8)
-class TestCourseRegistrationCodes(ModuleStoreTestCase):
+class TestCourseRegistrationCodes(SharedModuleStoreTestCase):
"""
Test data dumps for E-commerce Course Registration Codes.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestCourseRegistrationCodes, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.url = reverse(
+ 'generate_registration_codes',
+ kwargs={'course_id': cls.course.id.to_deprecated_string()}
+ )
def setUp(self):
"""
@@ -3701,15 +3746,11 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
"""
super(TestCourseRegistrationCodes, self).setUp()
- self.course = CourseFactory.create()
CourseModeFactory.create(course_id=self.course.id, min_price=50)
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
CourseSalesAdminRole(self.course.id).add_users(self.instructor)
- url = reverse('generate_registration_codes',
- kwargs={'course_id': self.course.id.to_deprecated_string()})
-
data = {
'total_registration_codes': 12, 'company_name': 'Test Group', 'company_contact_name': 'Test@company.com',
'company_contact_email': 'Test@company.com', 'unit_price': 122.45, 'recipient_name': 'Test123',
@@ -3718,7 +3759,7 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
'customer_reference_number': '123A23F', 'internal_reference': '', 'invoice': ''
}
- response = self.client.post(url, data, **{'HTTP_HOST': 'localhost'})
+ response = self.client.post(self.url, data, **{'HTTP_HOST': 'localhost'})
self.assertEqual(response.status_code, 200, response.content)
for i in range(5):
order = Order(user=self.instructor, status='purchased')
@@ -4148,13 +4189,17 @@ class TestCourseRegistrationCodes(ModuleStoreTestCase):
@attr('shard_1')
-class TestBulkCohorting(ModuleStoreTestCase):
+class TestBulkCohorting(SharedModuleStoreTestCase):
"""
Test adding users to cohorts in bulk via CSV upload.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestBulkCohorting, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
def setUp(self):
super(TestBulkCohorting, self).setUp()
- self.course = CourseFactory.create()
self.staff_user = StaffFactory(course_key=self.course.id)
self.non_staff_user = UserFactory.create()
self.tempdir = tempfile.mkdtemp()
diff --git a/lms/djangoapps/instructor/tests/test_api_email_localization.py b/lms/djangoapps/instructor/tests/test_api_email_localization.py
index d9fd87df93..ca0fd14ff7 100644
--- a/lms/djangoapps/instructor/tests/test_api_email_localization.py
+++ b/lms/djangoapps/instructor/tests/test_api_email_localization.py
@@ -13,15 +13,19 @@ from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
from xmodule.modulestore.tests.factories import CourseFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@attr('shard_1')
-class TestInstructorAPIEnrollmentEmailLocalization(ModuleStoreTestCase):
+class TestInstructorAPIEnrollmentEmailLocalization(SharedModuleStoreTestCase):
"""
Test whether the enroll, unenroll and beta role emails are sent in the
proper language, i.e: the student's language.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorAPIEnrollmentEmailLocalization, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestInstructorAPIEnrollmentEmailLocalization, self).setUp()
@@ -29,7 +33,6 @@ class TestInstructorAPIEnrollmentEmailLocalization(ModuleStoreTestCase):
# Platform language is English, instructor's language is Chinese,
# student's language is French, so the emails should all be sent in
# French.
- self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id)
set_user_preference(self.instructor, LANGUAGE_KEY, 'zh-cn')
self.client.login(username=self.instructor.username, password='test')
diff --git a/lms/djangoapps/instructor/tests/test_certificates.py b/lms/djangoapps/instructor/tests/test_certificates.py
index 7bf5b7fd3b..027c15671d 100644
--- a/lms/djangoapps/instructor/tests/test_certificates.py
+++ b/lms/djangoapps/instructor/tests/test_certificates.py
@@ -8,7 +8,7 @@ from nose.plugins.attrib import attr
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
from django.conf import settings
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from config_models.models import cache
from courseware.tests.factories import GlobalStaffFactory, InstructorFactory, UserFactory
@@ -18,19 +18,23 @@ from certificates import api as certs_api
@attr('shard_1')
@ddt.ddt
-class CertificatesInstructorDashTest(ModuleStoreTestCase):
+class CertificatesInstructorDashTest(SharedModuleStoreTestCase):
"""Tests for the certificate panel of the instructor dash. """
ERROR_REASON = "An error occurred!"
DOWNLOAD_URL = "http://www.example.com/abcd123/cert.pdf"
+ @classmethod
+ def setUpClass(cls):
+ super(CertificatesInstructorDashTest, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.url = reverse(
+ 'instructor_dashboard',
+ kwargs={'course_id': unicode(cls.course.id)}
+ )
+
def setUp(self):
super(CertificatesInstructorDashTest, self).setUp()
- self.course = CourseFactory.create()
- self.url = reverse(
- 'instructor_dashboard',
- kwargs={'course_id': unicode(self.course.id)}
- )
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
@@ -189,12 +193,15 @@ class CertificatesInstructorDashTest(ModuleStoreTestCase):
@attr('shard_1')
@override_settings(CERT_QUEUE='certificates')
@ddt.ddt
-class CertificatesInstructorApiTest(ModuleStoreTestCase):
+class CertificatesInstructorApiTest(SharedModuleStoreTestCase):
"""Tests for the certificates end-points in the instructor dash API. """
+ @classmethod
+ def setUpClass(cls):
+ super(CertificatesInstructorApiTest, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(CertificatesInstructorApiTest, self).setUp()
- self.course = CourseFactory.create()
self.global_staff = GlobalStaffFactory()
self.instructor = InstructorFactory(course_key=self.course.id)
diff --git a/lms/djangoapps/instructor/tests/test_ecommerce.py b/lms/djangoapps/instructor/tests/test_ecommerce.py
index 7fb4f895ac..4297d09cad 100644
--- a/lms/djangoapps/instructor/tests/test_ecommerce.py
+++ b/lms/djangoapps/instructor/tests/test_ecommerce.py
@@ -13,18 +13,26 @@ from course_modes.models import CourseMode
from student.roles import CourseFinanceAdminRole
from shoppingcart.models import Coupon, CourseRegistrationCode
from student.tests.factories import AdminFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@attr('shard_1')
-class TestECommerceDashboardViews(ModuleStoreTestCase):
+class TestECommerceDashboardViews(SharedModuleStoreTestCase):
"""
Check for E-commerce view on the new instructor dashboard
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestECommerceDashboardViews, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
+ # URL for instructor dash
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': cls.course.id.to_deprecated_string()})
+ cls.e_commerce_link = 'E-Commerce'
+
def setUp(self):
super(TestECommerceDashboardViews, self).setUp()
- self.course = CourseFactory.create()
# Create instructor account
self.instructor = AdminFactory.create()
@@ -34,9 +42,6 @@ class TestECommerceDashboardViews(ModuleStoreTestCase):
mode_display_name='honor', min_price=10, currency='usd'
)
mode.save()
- # URL for instructor dash
- self.url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id.to_deprecated_string()})
- self.e_commerce_link = 'E-Commerce'
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
def test_pass_e_commerce_tab_in_instructor_dashboard(self):
diff --git a/lms/djangoapps/instructor/tests/test_email.py b/lms/djangoapps/instructor/tests/test_email.py
index d18e9f403a..7f1bc0633f 100644
--- a/lms/djangoapps/instructor/tests/test_email.py
+++ b/lms/djangoapps/instructor/tests/test_email.py
@@ -11,30 +11,36 @@ from nose.plugins.attrib import attr
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from bulk_email.models import CourseAuthorization
-from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_TOY_MODULESTORE, ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import (
+ TEST_DATA_MIXED_TOY_MODULESTORE, SharedModuleStoreTestCase
+)
from student.tests.factories import AdminFactory
from xmodule.modulestore.tests.factories import CourseFactory
@attr('shard_1')
-class TestNewInstructorDashboardEmailViewMongoBacked(ModuleStoreTestCase):
+class TestNewInstructorDashboardEmailViewMongoBacked(SharedModuleStoreTestCase):
"""
Check for email view on the new instructor dashboard
for Mongo-backed courses
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestNewInstructorDashboardEmailViewMongoBacked, cls).setUpClass()
+ cls.course = CourseFactory.create()
+
+ # URL for instructor dash
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': cls.course.id.to_deprecated_string()})
+ # URL for email view
+ cls.email_link = 'Email'
+
def setUp(self):
super(TestNewInstructorDashboardEmailViewMongoBacked, self).setUp()
- self.course = CourseFactory.create()
# Create instructor account
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password="test")
- # URL for instructor dash
- self.url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id.to_deprecated_string()})
- # URL for email view
- self.email_link = 'Email'
-
# In order for bulk email to work, we must have both the ENABLE_INSTRUCTOR_EMAIL_FLAG
# set to True and for the course to be Mongo-backed.
# The flag is enabled and the course is Mongo-backed (should work)
@@ -101,16 +107,25 @@ class TestNewInstructorDashboardEmailViewMongoBacked(ModuleStoreTestCase):
@attr('shard_1')
-class TestNewInstructorDashboardEmailViewXMLBacked(ModuleStoreTestCase):
+class TestNewInstructorDashboardEmailViewXMLBacked(SharedModuleStoreTestCase):
"""
Check for email view on the new instructor dashboard
"""
MODULESTORE = TEST_DATA_MIXED_TOY_MODULESTORE
+ @classmethod
+ def setUpClass(cls):
+ super(TestNewInstructorDashboardEmailViewXMLBacked, cls).setUpClass()
+ cls.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
+
+ # URL for instructor dash
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': cls.course_key.to_deprecated_string()})
+ # URL for email view
+ cls.email_link = 'Email'
+
def setUp(self):
super(TestNewInstructorDashboardEmailViewXMLBacked, self).setUp()
- self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
# Create instructor account
instructor = AdminFactory.create()
diff --git a/lms/djangoapps/instructor/tests/test_enrollment.py b/lms/djangoapps/instructor/tests/test_enrollment.py
index 1a6e3d268e..c20bc98777 100644
--- a/lms/djangoapps/instructor/tests/test_enrollment.py
+++ b/lms/djangoapps/instructor/tests/test_enrollment.py
@@ -30,7 +30,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from submissions import api as sub_api
from student.models import anonymous_id_for_user
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@attr('shard_1')
@@ -296,40 +296,40 @@ class TestInstructorUnenrollDB(TestEnrollmentChangeBase):
@attr('shard_1')
-class TestInstructorEnrollmentStudentModule(ModuleStoreTestCase):
+class TestInstructorEnrollmentStudentModule(SharedModuleStoreTestCase):
""" Test student module manipulations. """
- def setUp(self):
- super(TestInstructorEnrollmentStudentModule, self).setUp()
- store = modulestore()
- self.user = UserFactory()
- self.course = CourseFactory(
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorEnrollmentStudentModule, cls).setUpClass()
+ cls.course = CourseFactory(
name='fake',
org='course',
run='id',
)
# pylint: disable=no-member
- self.course_key = self.course.location.course_key
- self.parent = ItemFactory(
- category="library_content",
- user_id=self.user.id,
- parent=self.course,
- publish_item=True,
- modulestore=store,
- )
- self.child = ItemFactory(
- category="html",
- user_id=self.user.id,
- parent=self.parent,
- publish_item=True,
- modulestore=store,
- )
- self.unrelated = ItemFactory(
- category="html",
- user_id=self.user.id,
- parent=self.course,
- publish_item=True,
- modulestore=store,
- )
+ cls.course_key = cls.course.location.course_key
+ with cls.store.bulk_operations(cls.course.id, emit_signals=False):
+ cls.parent = ItemFactory(
+ category="library_content",
+ parent=cls.course,
+ publish_item=True,
+ )
+ cls.child = ItemFactory(
+ category="html",
+ parent=cls.parent,
+ publish_item=True,
+ )
+ cls.unrelated = ItemFactory(
+ category="html",
+ parent=cls.course,
+ publish_item=True,
+ )
+
+ def setUp(self):
+ super(TestInstructorEnrollmentStudentModule, self).setUp()
+
+ self.user = UserFactory()
+
parent_state = json.dumps({'attempts': 32, 'otherstuff': 'alsorobots'})
child_state = json.dumps({'attempts': 10, 'whatever': 'things'})
unrelated_state = json.dumps({'attempts': 12, 'brains': 'zombie'})
@@ -567,26 +567,27 @@ class TestSendBetaRoleEmail(TestCase):
@attr('shard_1')
-class TestGetEmailParams(ModuleStoreTestCase):
+class TestGetEmailParams(SharedModuleStoreTestCase):
"""
Test what URLs the function get_email_params returns under different
production-like conditions.
"""
- def setUp(self):
- super(TestGetEmailParams, self).setUp()
-
- self.course = CourseFactory.create()
+ @classmethod
+ def setUpClass(cls):
+ super(TestGetEmailParams, cls).setUpClass()
+ cls.course = CourseFactory.create()
# Explicitly construct what we expect the course URLs to be
site = settings.SITE_NAME
- self.course_url = u'https://{}/courses/{}/'.format(
- site,
- self.course.id.to_deprecated_string()
- )
- self.course_about_url = self.course_url + 'about'
- self.registration_url = u'https://{}/register'.format(
+ cls.course_url = u'https://{}/courses/{}/'.format(
site,
+ cls.course.id.to_deprecated_string()
)
+ cls.course_about_url = cls.course_url + 'about'
+ cls.registration_url = u'https://{}/register'.format(site)
+
+ def setUp(self):
+ super(TestGetEmailParams, self).setUp()
def test_normal_params(self):
# For a normal site, what do we expect to get for the URLs?
@@ -612,16 +613,19 @@ class TestGetEmailParams(ModuleStoreTestCase):
@attr('shard_1')
-class TestRenderMessageToString(ModuleStoreTestCase):
+class TestRenderMessageToString(SharedModuleStoreTestCase):
"""
Test that email templates can be rendered in a language chosen manually.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestRenderMessageToString, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.subject_template = 'emails/enroll_email_allowedsubject.txt'
+ cls.message_template = 'emails/enroll_email_allowedmessage.txt'
def setUp(self):
super(TestRenderMessageToString, self).setUp()
- self.subject_template = 'emails/enroll_email_allowedsubject.txt'
- self.message_template = 'emails/enroll_email_allowedmessage.txt'
- self.course = CourseFactory.create()
def get_email_params(self):
"""
diff --git a/lms/djangoapps/instructor/tests/test_hint_manager.py b/lms/djangoapps/instructor/tests/test_hint_manager.py
index 5ce0e7e325..39e9dbc06c 100644
--- a/lms/djangoapps/instructor/tests/test_hint_manager.py
+++ b/lms/djangoapps/instructor/tests/test_hint_manager.py
@@ -8,14 +8,21 @@ from courseware.models import XModuleUserStateSummaryField
from courseware.tests.factories import UserStateSummaryFactory
import instructor.hint_manager as view
from student.tests.factories import UserFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
# pylint: disable=missing-docstring
@attr('shard_1')
-class HintManagerTest(ModuleStoreTestCase):
+class HintManagerTest(SharedModuleStoreTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(HintManagerTest, cls).setUpClass()
+ cls.course = CourseFactory.create(org='Me', number='19.002', display_name='test_course')
+ cls.url = '/courses/Me/19.002/test_course/hint_manager'
+ cls.course_id = cls.course.id
+ cls.problem_id = cls.course_id.make_usage_key('crowdsource_hinter', 'crowdsource_hinter_001')
def setUp(self):
"""
@@ -24,13 +31,9 @@ class HintManagerTest(ModuleStoreTestCase):
"""
super(HintManagerTest, self).setUp()
- self.course = CourseFactory.create(org='Me', number='19.002', display_name='test_course')
- self.url = '/courses/Me/19.002/test_course/hint_manager'
self.user = UserFactory.create(username='robot', email='robot@edx.org', password='test', is_staff=True)
self.c = Client()
self.c.login(username='robot', password='test')
- self.course_id = self.course.id
- self.problem_id = self.course_id.make_usage_key('crowdsource_hinter', 'crowdsource_hinter_001')
UserStateSummaryFactory.create(
field_name='hints',
usage_id=self.problem_id,
diff --git a/lms/djangoapps/instructor/tests/test_legacy_enrollment.py b/lms/djangoapps/instructor/tests/test_legacy_enrollment.py
index 314185bcdd..e7ed19ae73 100644
--- a/lms/djangoapps/instructor/tests/test_legacy_enrollment.py
+++ b/lms/djangoapps/instructor/tests/test_legacy_enrollment.py
@@ -12,7 +12,7 @@ from django.core.urlresolvers import reverse
from courseware.tests.helpers import LoginEnrollmentTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import UserFactory, CourseEnrollmentFactory, AdminFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from student.models import CourseEnrollment, CourseEnrollmentAllowed
from instructor.views.legacy import get_and_clean_student_list, send_mail_to_student
from django.core import mail
@@ -22,10 +22,14 @@ USER_COUNT = 4
@attr('shard_1')
@ddt.ddt
-class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase):
+class TestInstructorEnrollsStudent(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
"""
Check Enrollment/Unenrollment with/without auto-enrollment on activation and with/without email notification
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestInstructorEnrollsStudent, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestInstructorEnrollsStudent, self).setUp()
@@ -33,8 +37,6 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password='test')
- self.course = CourseFactory.create()
-
self.users = [
UserFactory.create(username="student%d" % i, email="student%d@test.com" % i)
for i in xrange(USER_COUNT)
diff --git a/lms/djangoapps/instructor/tests/test_legacy_xss.py b/lms/djangoapps/instructor/tests/test_legacy_xss.py
index ff541ff69c..919c512dcd 100644
--- a/lms/djangoapps/instructor/tests/test_legacy_xss.py
+++ b/lms/djangoapps/instructor/tests/test_legacy_xss.py
@@ -9,7 +9,7 @@ from nose.plugins.attrib import attr
from student.tests.factories import UserFactory, CourseEnrollmentFactory
from edxmako.tests import mako_middleware_process_request
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from instructor.views import legacy
@@ -18,12 +18,16 @@ from instructor.views import legacy
@attr('shard_1')
-class TestXss(ModuleStoreTestCase):
+class TestXss(SharedModuleStoreTestCase):
+ @classmethod
+ def setUpClass(cls):
+ super(TestXss, cls).setUpClass()
+ cls._course = CourseFactory.create()
+
def setUp(self):
super(TestXss, self).setUp()
self._request_factory = RequestFactory()
- self._course = CourseFactory.create()
self._evil_student = UserFactory.create(
email="robot+evil@edx.org",
username="evil-robot",
diff --git a/lms/djangoapps/instructor/tests/test_proctoring.py b/lms/djangoapps/instructor/tests/test_proctoring.py
index 7bac68a0ee..12bc0eb257 100644
--- a/lms/djangoapps/instructor/tests/test_proctoring.py
+++ b/lms/djangoapps/instructor/tests/test_proctoring.py
@@ -10,29 +10,32 @@ from nose.plugins.attrib import attr
from student.roles import CourseFinanceAdminRole
from student.tests.factories import AdminFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
@attr('shard_1')
@patch.dict(settings.FEATURES, {'ENABLE_PROCTORED_EXAMS': True})
-class TestProctoringDashboardViews(ModuleStoreTestCase):
+class TestProctoringDashboardViews(SharedModuleStoreTestCase):
"""
Check for Proctoring view on the new instructor dashboard
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestProctoringDashboardViews, cls).setUpClass()
+ cls.course = CourseFactory.create(enable_proctored_exams=True)
+
+ # URL for instructor dash
+ cls.url = reverse('instructor_dashboard', kwargs={'course_id': cls.course.id.to_deprecated_string()})
+ cls.proctoring_link = 'Proctoring'
+
def setUp(self):
super(TestProctoringDashboardViews, self).setUp()
- self.course = CourseFactory.create()
- self.course.enable_proctored_exams = True
# Create instructor account
self.instructor = AdminFactory.create()
self.client.login(username=self.instructor.username, password="test")
- self.course = self.update_course(self.course, self.instructor.id)
- # URL for instructor dash
- self.url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id.to_deprecated_string()})
- self.proctoring_link = 'Proctoring'
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
def test_pass_proctoring_tab_in_instructor_dashboard(self):
diff --git a/lms/djangoapps/instructor/tests/test_registration_codes.py b/lms/djangoapps/instructor/tests/test_registration_codes.py
index 2812fdfd9c..30cc2fbb7a 100644
--- a/lms/djangoapps/instructor/tests/test_registration_codes.py
+++ b/lms/djangoapps/instructor/tests/test_registration_codes.py
@@ -15,19 +15,22 @@ import json
from student.tests.factories import UserFactory, CourseModeFactory
from django.core.urlresolvers import reverse
from django.test.utils import override_settings
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
@attr('shard_1')
@override_settings(REGISTRATION_CODE_LENGTH=8)
-class TestCourseRegistrationCodeStatus(ModuleStoreTestCase):
+class TestCourseRegistrationCodeStatus(SharedModuleStoreTestCase):
"""
Test registration code status.
"""
+ @classmethod
+ def setUpClass(cls):
+ super(TestCourseRegistrationCodeStatus, cls).setUpClass()
+ cls.course = CourseFactory.create()
def setUp(self):
super(TestCourseRegistrationCodeStatus, self).setUp()
- self.course = CourseFactory.create()
CourseModeFactory.create(course_id=self.course.id, min_price=50)
self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test')
diff --git a/lms/djangoapps/instructor/tests/test_services.py b/lms/djangoapps/instructor/tests/test_services.py
index 9137a9cee7..aaaae3ec36 100644
--- a/lms/djangoapps/instructor/tests/test_services.py
+++ b/lms/djangoapps/instructor/tests/test_services.py
@@ -3,7 +3,7 @@ Tests for the InstructorService
"""
import json
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from courseware.models import StudentModule
from instructor.services import InstructorService
@@ -15,31 +15,31 @@ from student.tests.factories import UserFactory
@attr('shard_1')
-class InstructorServiceTests(ModuleStoreTestCase):
+class InstructorServiceTests(SharedModuleStoreTestCase):
"""
Tests for the InstructorService
"""
+ @classmethod
+ def setUpClass(cls):
+ super(InstructorServiceTests, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ cls.problem_location = msk_from_problem_urlname(
+ cls.course.id,
+ 'robot-some-problem-urlname'
+ )
+ cls.other_problem_location = msk_from_problem_urlname(
+ cls.course.id,
+ 'robot-some-other_problem-urlname'
+ )
+ cls.problem_urlname = unicode(cls.problem_location)
+ cls.other_problem_urlname = unicode(cls.other_problem_location)
def setUp(self):
super(InstructorServiceTests, self).setUp()
- self.course = CourseFactory.create()
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
- self.problem_location = msk_from_problem_urlname(
- self.course.id,
- 'robot-some-problem-urlname'
- )
-
- self.other_problem_location = msk_from_problem_urlname(
- self.course.id,
- 'robot-some-other_problem-urlname'
- )
-
- self.problem_urlname = unicode(self.problem_location)
- self.other_problem_urlname = unicode(self.other_problem_location)
-
self.service = InstructorService()
self.module_to_reset = StudentModule.objects.create(
student=self.student,
diff --git a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
index 2e0ca99a73..8da7e4d835 100644
--- a/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
+++ b/lms/djangoapps/instructor/tests/test_spoc_gradebook.py
@@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse
from nose.plugins.attrib import attr
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from student.tests.factories import UserFactory, CourseEnrollmentFactory, AdminFactory
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from capa.tests.response_xml_factory import StringResponseXMLFactory
from courseware.tests.factories import StudentModuleFactory
from xmodule.modulestore.django import modulestore
@@ -16,7 +16,7 @@ USER_COUNT = 11
@attr('shard_1')
-class TestGradebook(ModuleStoreTestCase):
+class TestGradebook(SharedModuleStoreTestCase):
"""
Test functionality of the spoc gradebook. Sets up a course with assignments and
students who've scored various scores on these assignments. Base class for further
@@ -24,45 +24,48 @@ class TestGradebook(ModuleStoreTestCase):
"""
grading_policy = None
+ @classmethod
+ def setUpClass(cls):
+ super(TestGradebook, cls).setUpClass()
+
+ # Create a course with the desired grading policy (from our class attribute)
+ kwargs = {}
+ if cls.grading_policy is not None:
+ kwargs['grading_policy'] = cls.grading_policy
+ cls.course = CourseFactory.create(**kwargs)
+
+ # Now give it some content
+ with cls.store.bulk_operations(cls.course.id, emit_signals=False):
+ chapter = ItemFactory.create(
+ parent_location=cls.course.location,
+ category="sequential",
+ )
+ section = ItemFactory.create(
+ parent_location=chapter.location,
+ category="sequential",
+ metadata={'graded': True, 'format': 'Homework'}
+ )
+ cls.items = [
+ ItemFactory.create(
+ parent_location=section.location,
+ category="problem",
+ data=StringResponseXMLFactory().build_xml(answer='foo'),
+ metadata={'rerandomize': 'always'}
+ )
+ for __ in xrange(USER_COUNT - 1)
+ ]
+
def setUp(self):
super(TestGradebook, self).setUp()
instructor = AdminFactory.create()
self.client.login(username=instructor.username, password='test')
-
- # remove the caches
- modulestore().request_cache = None
- modulestore().metadata_inheritance_cache_subsystem = None
-
- kwargs = {}
- if self.grading_policy is not None:
- kwargs['grading_policy'] = self.grading_policy
-
- self.course = CourseFactory.create(**kwargs)
- chapter = ItemFactory.create(
- parent_location=self.course.location,
- category="sequential",
- )
- section = ItemFactory.create(
- parent_location=chapter.location,
- category="sequential",
- metadata={'graded': True, 'format': 'Homework'}
- )
-
self.users = [UserFactory.create() for _ in xrange(USER_COUNT)]
for user in self.users:
CourseEnrollmentFactory.create(user=user, course_id=self.course.id)
- for i in xrange(USER_COUNT - 1):
- category = "problem"
- item = ItemFactory.create(
- parent_location=section.location,
- category=category,
- data=StringResponseXMLFactory().build_xml(answer='foo'),
- metadata={'rerandomize': 'always'}
- )
-
+ for i, item in enumerate(self.items):
for j, user in enumerate(self.users):
StudentModuleFactory.create(
grade=1 if i < j else 0,
diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py
index 5378aa5330..54068d4ce2 100644
--- a/lms/djangoapps/instructor/tests/test_tools.py
+++ b/lms/djangoapps/instructor/tests/test_tools.py
@@ -14,7 +14,7 @@ from nose.plugins.attrib import attr
from courseware.field_overrides import OverrideFieldData # pylint: disable=import-error
from student.tests.factories import UserFactory # pylint: disable=import-error
from xmodule.fields import Date
-from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
+from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from opaque_keys.edx.keys import CourseKey
@@ -102,23 +102,17 @@ class TestParseDatetime(unittest.TestCase):
@attr('shard_1')
-class TestFindUnit(ModuleStoreTestCase):
+class TestFindUnit(SharedModuleStoreTestCase):
"""
Test the find_unit function.
"""
-
- def setUp(self):
- """
- Fixtures.
- """
- super(TestFindUnit, self).setUp()
-
- course = CourseFactory.create()
- week1 = ItemFactory.create(parent=course)
- homework = ItemFactory.create(parent=week1)
-
- self.course = course
- self.homework = homework
+ @classmethod
+ def setUpClass(cls):
+ super(TestFindUnit, cls).setUpClass()
+ cls.course = CourseFactory.create()
+ with cls.store.bulk_operations(cls.course.id, emit_signals=False):
+ week1 = ItemFactory.create(parent=cls.course)
+ cls.homework = ItemFactory.create(parent=week1)
def test_find_unit_success(self):
"""