Commit 08343b96 by David Ormsbee

Merge pull request #9438 from edx/ormsbee/instructor_dash_tests_speedup

Speed up Instructor Dash tests + add manual reset for SharedModuleStoreTestCase
parents 73722c47 2ecf7aec
......@@ -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):
"""
......
......@@ -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
......
......@@ -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,37 +2850,30 @@ 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')
self.instructor = InstructorFactory(course_key=self.course.id)
# Add instructor to invalid ee course
CourseInstructorRole(self.course_with_invalid_ee.id).add_users(self.instructor)
self.client.login(username=self.instructor.username, password='test')
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
cls.course_with_invalid_ee = CourseFactory.create(entrance_exam_id='invalid_exam')
self.entrance_exam = ItemFactory.create(
parent=self.course,
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=self.entrance_exam,
parent=cls.entrance_exam,
category='sequential',
display_name='Subsection 1'
)
......@@ -2866,17 +2882,28 @@ class TestEntranceExamInstructorAPIRegradeTask(ModuleStoreTestCase, LoginEnrollm
category='vertical',
display_name='Vertical 1'
)
self.ee_problem_1 = ItemFactory.create(
cls.ee_problem_1 = ItemFactory.create(
parent=vertical,
category="problem",
display_name="Exam Problem - Problem 1"
)
self.ee_problem_2 = ItemFactory.create(
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
CourseInstructorRole(self.course_with_invalid_ee.id).add_users(self.instructor)
self.client.login(username=self.instructor.username, password='test')
self.student = UserFactory()
CourseEnrollment.enroll(self.student, self.course.id)
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()
......
......@@ -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')
......
......@@ -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"
def setUp(self):
super(CertificatesInstructorDashTest, self).setUp()
self.course = CourseFactory.create()
self.url = reverse(
@classmethod
def setUpClass(cls):
super(CertificatesInstructorDashTest, cls).setUpClass()
cls.course = CourseFactory.create()
cls.url = reverse(
'instructor_dashboard',
kwargs={'course_id': unicode(self.course.id)}
kwargs={'course_id': unicode(cls.course.id)}
)
def setUp(self):
super(CertificatesInstructorDashTest, self).setUp()
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)
......
......@@ -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 = '<a href="" data-section="e-commerce">E-Commerce</a>'
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 = '<a href="" data-section="e-commerce">E-Commerce</a>'
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
def test_pass_e_commerce_tab_in_instructor_dashboard(self):
......
......@@ -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 = '<a href="" data-section="send_email">Email</a>'
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 = '<a href="" data-section="send_email">Email</a>'
# 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 = '<a href="" data-section="send_email">Email</a>'
def setUp(self):
super(TestNewInstructorDashboardEmailViewXMLBacked, self).setUp()
self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
# Create instructor account
instructor = AdminFactory.create()
......
......@@ -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(
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",
user_id=self.user.id,
parent=self.course,
parent=cls.course,
publish_item=True,
modulestore=store,
)
self.child = ItemFactory(
cls.child = ItemFactory(
category="html",
user_id=self.user.id,
parent=self.parent,
parent=cls.parent,
publish_item=True,
modulestore=store,
)
self.unrelated = ItemFactory(
cls.unrelated = ItemFactory(
category="html",
user_id=self.user.id,
parent=self.course,
parent=cls.course,
publish_item=True,
modulestore=store,
)
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):
"""
......
......@@ -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,
......
......@@ -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)
......
......@@ -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",
......
......@@ -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 = '<a href="" data-section="proctoring">Proctoring</a>'
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 = '<a href="" data-section="proctoring">Proctoring</a>'
CourseFinanceAdminRole(self.course.id).add_users(self.instructor)
def test_pass_proctoring_tab_in_instructor_dashboard(self):
......
......@@ -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')
......
......@@ -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,
......
......@@ -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,23 +24,20 @@ class TestGradebook(ModuleStoreTestCase):
"""
grading_policy = None
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
@classmethod
def setUpClass(cls):
super(TestGradebook, cls).setUpClass()
# Create a course with the desired grading policy (from our class attribute)
kwargs = {}
if self.grading_policy is not None:
kwargs['grading_policy'] = self.grading_policy
if cls.grading_policy is not None:
kwargs['grading_policy'] = cls.grading_policy
cls.course = CourseFactory.create(**kwargs)
self.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=self.course.location,
parent_location=cls.course.location,
category="sequential",
)
section = ItemFactory.create(
......@@ -48,21 +45,27 @@ class TestGradebook(ModuleStoreTestCase):
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')
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,
......
......@@ -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):
"""
......
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