Commit 4ca5012f by Don Mitchell

Use split to test views

parent d43d5d7d
"""
Script for finding all courses whose org/name pairs == other courses when ignoring case
"""
from django.core.management.base import BaseCommand
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import ModuleStoreEnum
#
# To run from command line: ./manage.py cms --settings dev course_id_clash
#
class Command(BaseCommand):
"""
Script for finding all courses in the Mongo Modulestore whose org/name pairs == other courses when ignoring case
"""
help = 'List all courses ids in the Mongo Modulestore which may collide when ignoring case'
def handle(self, *args, **options):
mstore = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.mongo) # pylint: disable=protected-access
if hasattr(mstore, 'collection'):
map_fn = '''
function () {
emit(this._id.org.toLowerCase()+this._id.course.toLowerCase(), {target: this._id});
}
'''
reduce_fn = '''
function (idpair, matches) {
var result = {target: []};
matches.forEach(function (match) {
result.target.push(match.target);
});
return result;
}
'''
finalize = '''
function(key, reduced) {
if (Array.isArray(reduced.target)) {
return reduced;
}
else {return null;}
}
'''
results = mstore.collection.map_reduce(
map_fn, reduce_fn, {'inline': True}, query={'_id.category': 'course'}, finalize=finalize
)
results = results.get('results')
for entry in results:
if entry.get('value') is not None:
print '{:-^40}'.format(entry.get('_id'))
for course_id in entry.get('value').get('target'):
print ' {}/{}/{}'.format(course_id.get('org'), course_id.get('course'), course_id.get('name'))
import sys
from StringIO import StringIO
from django.test import TestCase
from django.core.management import call_command
from xmodule.modulestore.tests.factories import CourseFactory
class ClashIdTestCase(TestCase):
"""
Test for course_id_clash.
"""
def test_course_clash(self):
"""
Test for course_id_clash.
"""
expected = []
# clashing courses
course = CourseFactory.create(org="test", course="courseid", display_name="run1")
expected.append(course.id)
course = CourseFactory.create(org="TEST", course="courseid", display_name="RUN12")
expected.append(course.id)
course = CourseFactory.create(org="test", course="CourseId", display_name="aRUN123")
expected.append(course.id)
# not clashing courses
not_expected = []
course = CourseFactory.create(org="test", course="course2", display_name="run1")
not_expected.append(course.id)
course = CourseFactory.create(org="test1", course="courseid", display_name="run1")
not_expected.append(course.id)
course = CourseFactory.create(org="test", course="courseid0", display_name="run1")
not_expected.append(course.id)
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
call_command('course_id_clash', stdout=mystdout)
sys.stdout = old_stdout
result = mystdout.getvalue()
for courseid in expected:
self.assertIn(courseid.to_deprecated_string(), result)
for courseid in not_expected:
self.assertNotIn(courseid.to_deprecated_string(), result)
...@@ -49,8 +49,6 @@ from opaque_keys import InvalidKeyError ...@@ -49,8 +49,6 @@ from opaque_keys import InvalidKeyError
from contentstore.tests.utils import get_url from contentstore.tests.utils import get_url
from course_action_state.models import CourseRerunState, CourseRerunUIStateManager from course_action_state.models import CourseRerunState, CourseRerunUIStateManager
from unittest import skipIf
from course_action_state.managers import CourseActionStateItemNotFoundError from course_action_state.managers import CourseActionStateItemNotFoundError
...@@ -63,7 +61,7 @@ class ContentStoreTestCase(CourseTestCase): ...@@ -63,7 +61,7 @@ class ContentStoreTestCase(CourseTestCase):
""" """
Base class for Content Store Test Cases Base class for Content Store Test Cases
""" """
pass
class ContentStoreToyCourseTest(ContentStoreTestCase): class ContentStoreToyCourseTest(ContentStoreTestCase):
""" """
...@@ -317,7 +315,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -317,7 +315,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
def test_delete(self): def test_delete(self):
store = self.store store = self.store
course = CourseFactory.create(org='edX', course='999', display_name='Robot Super Course') course = CourseFactory.create()
chapterloc = ItemFactory.create(parent_location=course.location, display_name="Chapter").location chapterloc = ItemFactory.create(parent_location=course.location, display_name="Chapter").location
ItemFactory.create(parent_location=chapterloc, category='sequential', display_name="Sequential") ItemFactory.create(parent_location=chapterloc, category='sequential', display_name="Sequential")
...@@ -567,7 +565,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase): ...@@ -567,7 +565,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
def test_illegal_draft_crud_ops(self): def test_illegal_draft_crud_ops(self):
draft_store = self.store draft_store = self.store
course = CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') course = CourseFactory.create()
location = course.id.make_usage_key('chapter', 'neuvo') location = course.id.make_usage_key('chapter', 'neuvo')
# Ensure draft mongo store does not create drafts for things that shouldn't be draft # Ensure draft mongo store does not create drafts for things that shouldn't be draft
...@@ -1186,7 +1184,7 @@ class ContentStoreTest(ContentStoreTestCase): ...@@ -1186,7 +1184,7 @@ class ContentStoreTest(ContentStoreTestCase):
def test_course_index_view_with_course(self): def test_course_index_view_with_course(self):
"""Test viewing the index page with an existing course""" """Test viewing the index page with an existing course"""
CourseFactory.create(display_name='Robot Super Educational Course') CourseFactory.create(, display_name='Robot Super Educational Course')
resp = self.client.get_html('/course/') resp = self.client.get_html('/course/')
self.assertContains( self.assertContains(
resp, resp,
...@@ -1197,13 +1195,14 @@ class ContentStoreTest(ContentStoreTestCase): ...@@ -1197,13 +1195,14 @@ class ContentStoreTest(ContentStoreTestCase):
def test_course_overview_view_with_course(self): def test_course_overview_view_with_course(self):
"""Test viewing the course overview page with an existing course""" """Test viewing the course overview page with an existing course"""
course = CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course') course_cat_num = self.random_course_name()
course = CourseFactory.create(org='MITx', course=course_cat_num, display_name='Robot Super Course')
resp = self._show_course_overview(course.id) resp = self._show_course_overview(course.id)
self.assertContains( self.assertContains(
resp, resp,
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}">'.format( '<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}">'.format(
locator='i4x://MITx/999/course/Robot_Super_Course', locator=unicode(course.location),
course_key='MITx/999/Robot_Super_Course', course_key=unicode(course.id),
), ),
status_code=200, status_code=200,
html=True html=True
...@@ -1211,7 +1210,7 @@ class ContentStoreTest(ContentStoreTestCase): ...@@ -1211,7 +1210,7 @@ class ContentStoreTest(ContentStoreTestCase):
def test_create_item(self): def test_create_item(self):
"""Test creating a new xblock instance.""" """Test creating a new xblock instance."""
course = _course_factory_create_course() course = CourseFactory.create()()
section_data = { section_data = {
'parent_locator': unicode(course.location), 'parent_locator': unicode(course.location),
...@@ -1223,14 +1222,12 @@ class ContentStoreTest(ContentStoreTestCase): ...@@ -1223,14 +1222,12 @@ class ContentStoreTest(ContentStoreTestCase):
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
data = parse_json(resp) data = parse_json(resp)
self.assertRegexpMatches( retarget = unicode(course.id.make_usage_key('chapter', 'REPLACE')).replace('REPLACE', r'([0-9]|[a-f]){3,}')
data['locator'], self.assertRegexpMatches(data['locator'], retarget)
r"MITx/999/chapter/([0-9]|[a-f]){3,}$"
)
def test_capa_module(self): def test_capa_module(self):
"""Test that a problem treats markdown specially.""" """Test that a problem treats markdown specially."""
course = _course_factory_create_course() course = CourseFactory.create()()
problem_data = { problem_data = {
'parent_locator': unicode(course.location), 'parent_locator': unicode(course.location),
...@@ -1382,7 +1379,7 @@ class ContentStoreTest(ContentStoreTestCase): ...@@ -1382,7 +1379,7 @@ class ContentStoreTest(ContentStoreTestCase):
self.assertTrue(did_load_item) self.assertTrue(did_load_item)
def test_forum_id_generation(self): def test_forum_id_generation(self):
course = CourseFactory.create(org='edX', course='999', display_name='Robot Super Course') course = CourseFactory.create()
# crate a new module and add it as a child to a vertical # crate a new module and add it as a child to a vertical
new_discussion_item = self.store.create_item(self.user.id, course.id, 'discussion', 'new_component') new_discussion_item = self.store.create_item(self.user.id, course.id, 'discussion', 'new_component')
...@@ -1501,8 +1498,7 @@ class MetadataSaveTestCase(ContentStoreTestCase): ...@@ -1501,8 +1498,7 @@ class MetadataSaveTestCase(ContentStoreTestCase):
def setUp(self): def setUp(self):
super(MetadataSaveTestCase, self).setUp() super(MetadataSaveTestCase, self).setUp()
course = CourseFactory.create( course = CourseFactory.create()
org='edX', course='999', display_name='Robot Super Course')
video_sample_xml = ''' video_sample_xml = '''
<video display_name="Test Video" <video display_name="Test Video"
...@@ -1640,7 +1636,6 @@ class RerunCourseTest(ContentStoreTestCase): ...@@ -1640,7 +1636,6 @@ class RerunCourseTest(ContentStoreTestCase):
self.assertInCourseListing(source_course_key) self.assertInCourseListing(source_course_key)
self.assertInCourseListing(destination_course_key) self.assertInCourseListing(destination_course_key)
def test_rerun_course_success(self): def test_rerun_course_success(self):
source_course = CourseFactory.create() source_course = CourseFactory.create()
destination_course_key = self.post_rerun_request(source_course.id) destination_course_key = self.post_rerun_request(source_course.id)
...@@ -1755,13 +1750,6 @@ def _create_course(test, course_key, course_data): ...@@ -1755,13 +1750,6 @@ def _create_course(test, course_key, course_data):
test.assertEqual(data['url'], course_url) test.assertEqual(data['url'], course_url)
def _course_factory_create_course():
"""
Creates a course via the CourseFactory and returns the locator for it.
"""
return CourseFactory.create(org='MITx', course='999', display_name='Robot Super Course')
def _get_course_id(course_data, key_class=SlashSeparatedCourseKey): def _get_course_id(course_data, key_class=SlashSeparatedCourseKey):
"""Returns the course ID (org/number/run).""" """Returns the course ID (org/number/run)."""
return key_class(course_data['org'], course_data['number'], course_data['run']) return key_class(course_data['org'], course_data['number'], course_data['run'])
...@@ -210,57 +210,6 @@ class TestCourseListing(ModuleStoreTestCase): ...@@ -210,57 +210,6 @@ class TestCourseListing(ModuleStoreTestCase):
with check_mongo_calls(3): with check_mongo_calls(3):
_accessible_courses_list(self.request) _accessible_courses_list(self.request)
def test_get_course_list_with_same_course_id(self):
"""
Test getting courses with same id but with different name case. Then try to delete one of them and
check that it is properly deleted and other one is accessible
"""
course_location_caps = SlashSeparatedCourseKey('Org', 'COURSE', 'Run')
self._create_course_with_access_groups(course_location_caps, self.user)
# get courses through iterating all courses
courses_list, __ = _accessible_courses_list(self.request)
self.assertEqual(len(courses_list), 1)
# get courses by reversing group name formats
courses_list_by_groups, __ = _accessible_courses_list_from_groups(self.request)
self.assertEqual(len(courses_list_by_groups), 1)
# check both course lists have same courses
self.assertEqual(courses_list, courses_list_by_groups)
# now create another course with same course_id but different name case
course_location_camel = SlashSeparatedCourseKey('Org', 'Course', 'Run')
self._create_course_with_access_groups(course_location_camel, self.user)
# test that get courses through iterating all courses returns both courses
courses_list, __ = _accessible_courses_list(self.request)
self.assertEqual(len(courses_list), 2)
# test that get courses by reversing group name formats returns both courses
courses_list_by_groups, __ = _accessible_courses_list_from_groups(self.request)
self.assertEqual(len(courses_list_by_groups), 2)
# now delete first course (course_location_caps) and check that it is no longer accessible
delete_course_and_groups(course_location_caps, self.user.id)
# test that get courses through iterating all courses now returns one course
courses_list, __ = _accessible_courses_list(self.request)
self.assertEqual(len(courses_list), 1)
# test that get courses by reversing group name formats also returns one course
courses_list_by_groups, __ = _accessible_courses_list_from_groups(self.request)
self.assertEqual(len(courses_list_by_groups), 1)
# now check that deleted course is not accessible
outline_url = reverse_course_url('course_handler', course_location_caps)
response = self.client.get(outline_url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 403)
# now check that other course is accessible
outline_url = reverse_course_url('course_handler', course_location_camel)
response = self.client.get(outline_url, HTTP_ACCEPT='application/json')
self.assertEqual(response.status_code, 200)
def test_course_listing_errored_deleted_courses(self): def test_course_listing_errored_deleted_courses(self):
""" """
Create good courses, courses that won't load, and deleted courses which still have Create good courses, courses that won't load, and deleted courses which still have
......
...@@ -441,19 +441,19 @@ class CourseMetadataEditingTest(CourseTestCase): ...@@ -441,19 +441,19 @@ class CourseMetadataEditingTest(CourseTestCase):
""" """
def setUp(self): def setUp(self):
CourseTestCase.setUp(self) CourseTestCase.setUp(self)
self.fullcourse = CourseFactory.create(org='edX', course='999', display_name='Robot Super Course') self.fullcourse = CourseFactory.create()
self.course_setting_url = get_url(self.course.id, 'advanced_settings_handler') self.course_setting_url = get_url(self.course.id, 'advanced_settings_handler')
self.fullcourse_setting_url = get_url(self.fullcourse.id, 'advanced_settings_handler') self.fullcourse_setting_url = get_url(self.fullcourse.id, 'advanced_settings_handler')
def test_fetch_initial_fields(self): def test_fetch_initial_fields(self):
test_model = CourseMetadata.fetch(self.course) test_model = CourseMetadata.fetch(self.course)
self.assertIn('display_name', test_model, 'Missing editable metadata field') self.assertIn('display_name', test_model, 'Missing editable metadata field')
self.assertEqual(test_model['display_name']['value'], 'Robot Super Course', "not expected value") self.assertEqual(test_model['display_name']['value'], self.course.display_name)
test_model = CourseMetadata.fetch(self.fullcourse) test_model = CourseMetadata.fetch(self.fullcourse)
self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in') self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in')
self.assertIn('display_name', test_model, 'full missing editable metadata field') self.assertIn('display_name', test_model, 'full missing editable metadata field')
self.assertEqual(test_model['display_name']['value'], 'Robot Super Course', "not expected value") self.assertEqual(test_model['display_name']['value'], self.fullcourse.display_name)
self.assertIn('rerandomize', test_model, 'Missing rerandomize metadata field') self.assertIn('rerandomize', test_model, 'Missing rerandomize metadata field')
self.assertIn('showanswer', test_model, 'showanswer field ') self.assertIn('showanswer', test_model, 'showanswer field ')
self.assertIn('xqa_key', test_model, 'xqa_key field ') self.assertIn('xqa_key', test_model, 'xqa_key field ')
...@@ -554,7 +554,7 @@ class CourseMetadataEditingTest(CourseTestCase): ...@@ -554,7 +554,7 @@ class CourseMetadataEditingTest(CourseTestCase):
checks that updates were made checks that updates were made
""" """
self.assertIn('display_name', test_model, 'Missing editable metadata field') self.assertIn('display_name', test_model, 'Missing editable metadata field')
self.assertEqual(test_model['display_name']['value'], 'Robot Super Course', "not expected value") self.assertEqual(test_model['display_name']['value'], self.course.display_name)
self.assertIn('advertised_start', test_model, 'Missing new advertised_start metadata field') self.assertIn('advertised_start', test_model, 'Missing new advertised_start metadata field')
self.assertEqual(test_model['advertised_start']['value'], 'start A', "advertised_start not expected value") self.assertEqual(test_model['advertised_start']['value'], 'start A', "advertised_start not expected value")
self.assertIn('days_early_for_beta', test_model, 'Missing days_early_for_beta metadata field') self.assertIn('days_early_for_beta', test_model, 'Missing days_early_for_beta metadata field')
...@@ -564,13 +564,13 @@ class CourseMetadataEditingTest(CourseTestCase): ...@@ -564,13 +564,13 @@ class CourseMetadataEditingTest(CourseTestCase):
response = self.client.get_json(self.course_setting_url) response = self.client.get_json(self.course_setting_url)
test_model = json.loads(response.content) test_model = json.loads(response.content)
self.assertIn('display_name', test_model, 'Missing editable metadata field') self.assertIn('display_name', test_model, 'Missing editable metadata field')
self.assertEqual(test_model['display_name']['value'], 'Robot Super Course', "not expected value") self.assertEqual(test_model['display_name']['value'], self.course.display_name)
response = self.client.get_json(self.fullcourse_setting_url) response = self.client.get_json(self.fullcourse_setting_url)
test_model = json.loads(response.content) test_model = json.loads(response.content)
self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in') self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in')
self.assertIn('display_name', test_model, 'full missing editable metadata field') self.assertIn('display_name', test_model, 'full missing editable metadata field')
self.assertEqual(test_model['display_name']['value'], 'Robot Super Course', "not expected value") self.assertEqual(test_model['display_name']['value'], self.fullcourse.display_name)
self.assertIn('rerandomize', test_model, 'Missing rerandomize metadata field') self.assertIn('rerandomize', test_model, 'Missing rerandomize metadata field')
self.assertIn('showanswer', test_model, 'showanswer field ') self.assertIn('showanswer', test_model, 'showanswer field ')
self.assertIn('xqa_key', test_model, 'xqa_key field ') self.assertIn('xqa_key', test_model, 'xqa_key field ')
......
...@@ -12,7 +12,7 @@ from contentstore import utils ...@@ -12,7 +12,7 @@ from contentstore import utils
from contentstore.tests.utils import CourseTestCase from contentstore.tests.utils import CourseTestCase
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey, Location from opaque_keys.edx.locations import SlashSeparatedCourseKey
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from opaque_keys.edx.locator import CourseLocator from opaque_keys.edx.locator import CourseLocator
...@@ -168,27 +168,26 @@ class CourseImageTestCase(TestCase): ...@@ -168,27 +168,26 @@ class CourseImageTestCase(TestCase):
def test_get_image_url(self): def test_get_image_url(self):
"""Test image URL formatting.""" """Test image URL formatting."""
course = CourseFactory.create(org='edX', course='999') course = CourseFactory.create()
url = utils.course_image_url(course) url = utils.course_image_url(course)
self.assertEquals(url, '/c4x/edX/999/asset/{0}'.format(course.course_image)) self.assertEquals(url, unicode(course.id.make_asset_key('asset', course.course_image)))
def test_non_ascii_image_name(self): def test_non_ascii_image_name(self):
# Verify that non-ascii image names are cleaned """ Verify that non-ascii image names are cleaned """
course = CourseFactory.create(course_image=u'before_\N{SNOWMAN}_after.jpg') course_image = u'before_\N{SNOWMAN}_after.jpg'
course = CourseFactory.create(course_image=course_image)
self.assertEquals( self.assertEquals(
utils.course_image_url(course), utils.course_image_url(course),
'/c4x/{org}/{course}/asset/before___after.jpg'.format(org=course.location.org, course=course.location.course) unicode(course.id.make_asset_key('asset', course_image.replace(u'\N{SNOWMAN}', '_')))
) )
def test_spaces_in_image_name(self): def test_spaces_in_image_name(self):
# Verify that image names with spaces in them are cleaned """ Verify that image names with spaces in them are cleaned """
course_image = u'before after.jpg'
course = CourseFactory.create(course_image=u'before after.jpg') course = CourseFactory.create(course_image=u'before after.jpg')
self.assertEquals( self.assertEquals(
utils.course_image_url(course), utils.course_image_url(course),
'/c4x/{org}/{course}/asset/before_after.jpg'.format( unicode(course.id.make_asset_key('asset', course_image.replace(" ", "_")))
org=course.location.org,
course=course.location.course
)
) )
......
...@@ -77,11 +77,7 @@ class CourseTestCase(ModuleStoreTestCase): ...@@ -77,11 +77,7 @@ class CourseTestCase(ModuleStoreTestCase):
self.client = AjaxEnabledTestClient() self.client = AjaxEnabledTestClient()
self.client.login(username=self.user.username, password=user_password) self.client.login(username=self.user.username, password=user_password)
self.course = CourseFactory.create( self.course = CourseFactory.create()
org='MITx',
number='999',
display_name='Robot Super Course',
)
def create_non_staff_authed_user_client(self, authenticate=True): def create_non_staff_authed_user_client(self, authenticate=True):
""" """
......
...@@ -8,6 +8,7 @@ from pytz import UTC ...@@ -8,6 +8,7 @@ from pytz import UTC
from contentstore.views.tests.utils import StudioPageTestCase from contentstore.views.tests.utils import StudioPageTestCase
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore.tests.factories import ItemFactory from xmodule.modulestore.tests.factories import ItemFactory
from django.utils import http
class ContainerPageTestCase(StudioPageTestCase): class ContainerPageTestCase(StudioPageTestCase):
...@@ -59,8 +60,8 @@ class ContainerPageTestCase(StudioPageTestCase): ...@@ -59,8 +60,8 @@ class ContainerPageTestCase(StudioPageTestCase):
course=re.escape(unicode(self.course.id)), course=re.escape(unicode(self.course.id)),
unit=re.escape(unicode(self.vertical.location)), unit=re.escape(unicode(self.vertical.location)),
classes='navigation-item navigation-link navigation-parent', classes='navigation-item navigation-link navigation-parent',
section_parameters=re.escape(u'?show=i4x%3A//MITx/999/chapter/Week_1'), section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
subsection_parameters=re.escape(u'?show=i4x%3A//MITx/999/sequential/Lesson_1'), subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
), ),
) )
...@@ -89,8 +90,8 @@ class ContainerPageTestCase(StudioPageTestCase): ...@@ -89,8 +90,8 @@ class ContainerPageTestCase(StudioPageTestCase):
unit=re.escape(unicode(self.vertical.location)), unit=re.escape(unicode(self.vertical.location)),
split_test=re.escape(unicode(self.child_container.location)), split_test=re.escape(unicode(self.child_container.location)),
classes='navigation-item navigation-link navigation-parent', classes='navigation-item navigation-link navigation-parent',
section_parameters=re.escape(u'?show=i4x%3A//MITx/999/chapter/Week_1'), section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
subsection_parameters=re.escape(u'?show=i4x%3A//MITx/999/sequential/Lesson_1'), subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
), ),
) )
......
...@@ -106,8 +106,8 @@ class TestCourseIndex(CourseTestCase): ...@@ -106,8 +106,8 @@ class TestCourseIndex(CourseTestCase):
# First spot check some values in the root response # First spot check some values in the root response
self.assertEqual(json_response['category'], 'course') self.assertEqual(json_response['category'], 'course')
self.assertEqual(json_response['id'], 'i4x://MITx/999/course/Robot_Super_Course') self.assertEqual(json_response['id'], unicode(self.course.location))
self.assertEqual(json_response['display_name'], 'Robot Super Course') self.assertEqual(json_response['display_name'], self.course.display_name)
self.assertTrue(json_response['published']) self.assertTrue(json_response['published'])
self.assertIsNone(json_response['visibility_state']) self.assertIsNone(json_response['visibility_state'])
...@@ -116,7 +116,7 @@ class TestCourseIndex(CourseTestCase): ...@@ -116,7 +116,7 @@ class TestCourseIndex(CourseTestCase):
self.assertTrue(len(children) > 0) self.assertTrue(len(children) > 0)
first_child_response = children[0] first_child_response = children[0]
self.assertEqual(first_child_response['category'], 'chapter') self.assertEqual(first_child_response['category'], 'chapter')
self.assertEqual(first_child_response['id'], 'i4x://MITx/999/chapter/Week_1') self.assertEqual(first_child_response['id'], unicode(chapter.location))
self.assertEqual(first_child_response['display_name'], 'Week 1') self.assertEqual(first_child_response['display_name'], 'Week 1')
self.assertTrue(json_response['published']) self.assertTrue(json_response['published'])
self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled) self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled)
...@@ -227,8 +227,8 @@ class TestCourseOutline(CourseTestCase): ...@@ -227,8 +227,8 @@ class TestCourseOutline(CourseTestCase):
# First spot check some values in the root response # First spot check some values in the root response
self.assertEqual(json_response['category'], 'course') self.assertEqual(json_response['category'], 'course')
self.assertEqual(json_response['id'], 'i4x://MITx/999/course/Robot_Super_Course') self.assertEqual(json_response['id'], unicode(self.course.location))
self.assertEqual(json_response['display_name'], 'Robot Super Course') self.assertEqual(json_response['display_name'], self.course.display_name)
self.assertTrue(json_response['published']) self.assertTrue(json_response['published'])
self.assertIsNone(json_response['visibility_state']) self.assertIsNone(json_response['visibility_state'])
...@@ -237,7 +237,7 @@ class TestCourseOutline(CourseTestCase): ...@@ -237,7 +237,7 @@ class TestCourseOutline(CourseTestCase):
self.assertTrue(len(children) > 0) self.assertTrue(len(children) > 0)
first_child_response = children[0] first_child_response = children[0]
self.assertEqual(first_child_response['category'], 'chapter') self.assertEqual(first_child_response['category'], 'chapter')
self.assertEqual(first_child_response['id'], 'i4x://MITx/999/chapter/Week_1') self.assertEqual(first_child_response['id'], unicode(self.chapter.location))
self.assertEqual(first_child_response['display_name'], 'Week 1') self.assertEqual(first_child_response['display_name'], 'Week 1')
self.assertTrue(json_response['published']) self.assertTrue(json_response['published'])
self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled) self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled)
......
...@@ -10,6 +10,8 @@ from contentstore.tests.utils import CourseTestCase ...@@ -10,6 +10,8 @@ from contentstore.tests.utils import CourseTestCase
from xmodule.partitions.partitions import Group, UserPartition from xmodule.partitions.partitions import Group, UserPartition
from xmodule.modulestore.tests.factories import ItemFactory from xmodule.modulestore.tests.factories import ItemFactory
from xmodule.split_test_module import ValidationMessage, ValidationMessageType from xmodule.split_test_module import ValidationMessage, ValidationMessageType
from xmodule.modulestore.django import modulestore
from xmodule.modulestore import ModuleStoreEnum
GROUP_CONFIGURATION_JSON = { GROUP_CONFIGURATION_JSON = {
u'name': u'Test name', u'name': u'Test name',
...@@ -266,12 +268,6 @@ class GroupConfigurationsDetailHandlerTestCase(CourseTestCase, GroupConfiguratio ...@@ -266,12 +268,6 @@ class GroupConfigurationsDetailHandlerTestCase(CourseTestCase, GroupConfiguratio
ID = 0 ID = 0
def setUp(self):
"""
Set up GroupConfigurationsDetailHandlerTestCase.
"""
super(GroupConfigurationsDetailHandlerTestCase, self).setUp()
def _url(self, cid=-1): def _url(self, cid=-1):
""" """
Return url for the handler. Return url for the handler.
...@@ -450,7 +446,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ...@@ -450,7 +446,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
Test if group configurations json updated successfully with usage information. Test if group configurations json updated successfully with usage information.
""" """
self._add_user_partitions(count=2) self._add_user_partitions(count=2)
self._create_content_experiment(cid=0, name_suffix='0') vertical, __ = self._create_content_experiment(cid=0, name_suffix='0')
self._create_content_experiment(name_suffix='1') self._create_content_experiment(name_suffix='1')
actual = GroupConfiguration.add_usage_info(self.course, self.store) actual = GroupConfiguration.add_usage_info(self.course, self.store)
...@@ -466,7 +462,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ...@@ -466,7 +462,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
{'id': 2, 'name': 'Group C', 'version': 1}, {'id': 2, 'name': 'Group C', 'version': 1},
], ],
'usage': [{ 'usage': [{
'url': '/container/i4x://MITx/999/vertical/Test_Unit_0', 'url': '/container/{}'.format(vertical.location),
'label': 'Test Unit 0 / Test Content Experiment 0', 'label': 'Test Unit 0 / Test Content Experiment 0',
'validation': None, 'validation': None,
}], }],
...@@ -491,8 +487,8 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ...@@ -491,8 +487,8 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
group configuration. group configuration.
""" """
self._add_user_partitions() self._add_user_partitions()
self._create_content_experiment(cid=0, name_suffix='0') vertical, __ = self._create_content_experiment(cid=0, name_suffix='0')
self._create_content_experiment(cid=0, name_suffix='1') vertical1, __ = self._create_content_experiment(cid=0, name_suffix='1')
actual = GroupConfiguration.add_usage_info(self.course, self.store) actual = GroupConfiguration.add_usage_info(self.course, self.store)
...@@ -507,11 +503,11 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ...@@ -507,11 +503,11 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
{'id': 2, 'name': 'Group C', 'version': 1}, {'id': 2, 'name': 'Group C', 'version': 1},
], ],
'usage': [{ 'usage': [{
'url': '/container/i4x://MITx/999/vertical/Test_Unit_0', 'url': '/container/{}'.format(vertical.location),
'label': 'Test Unit 0 / Test Content Experiment 0', 'label': 'Test Unit 0 / Test Content Experiment 0',
'validation': None, 'validation': None,
}, { }, {
'url': '/container/i4x://MITx/999/vertical/Test_Unit_1', 'url': '/container/{}'.format(vertical1.location),
'label': 'Test Unit 1 / Test Content Experiment 1', 'label': 'Test Unit 1 / Test Content Experiment 1',
'validation': None, 'validation': None,
}], }],
...@@ -524,11 +520,15 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods): ...@@ -524,11 +520,15 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
""" """
self._add_user_partitions() self._add_user_partitions()
# Create split test without parent. # Create split test without parent.
ItemFactory.create( with modulestore().branch_setting(ModuleStoreEnum.Branch.published_only):
category='split_test', orphan = modulestore().create_item(
user_partition_id=0, ModuleStoreEnum.UserID.test,
display_name='Test Content Experiment' self.course.id, 'split_test',
) )
orphan.user_partition_id = 0
orphan.display_name = 'Test Content Experiment'
modulestore().update_item(orphan, ModuleStoreEnum.UserID.test)
self.save_course() self.save_course()
actual = GroupConfiguration.get_usage_info(self.course, self.store) actual = GroupConfiguration.get_usage_info(self.course, self.store)
self.assertEqual(actual, {0: []}) self.assertEqual(actual, {0: []})
......
...@@ -5,6 +5,7 @@ Unit tests for helpers.py. ...@@ -5,6 +5,7 @@ Unit tests for helpers.py.
from contentstore.tests.utils import CourseTestCase from contentstore.tests.utils import CourseTestCase
from contentstore.views.helpers import xblock_studio_url, xblock_type_display_name from contentstore.views.helpers import xblock_studio_url, xblock_type_display_name
from xmodule.modulestore.tests.factories import ItemFactory from xmodule.modulestore.tests.factories import ItemFactory
from django.utils import http
class HelpersTestCase(CourseTestCase): class HelpersTestCase(CourseTestCase):
...@@ -15,36 +16,34 @@ class HelpersTestCase(CourseTestCase): ...@@ -15,36 +16,34 @@ class HelpersTestCase(CourseTestCase):
def test_xblock_studio_url(self): def test_xblock_studio_url(self):
# Verify course URL # Verify course URL
self.assertEqual(xblock_studio_url(self.course), course_url = u'/course/{}'.format(unicode(self.course.id))
u'/course/MITx/999/Robot_Super_Course') self.assertEqual(xblock_studio_url(self.course), course_url)
# Verify chapter URL # Verify chapter URL
chapter = ItemFactory.create(parent_location=self.course.location, category='chapter', chapter = ItemFactory.create(parent_location=self.course.location, category='chapter',
display_name="Week 1") display_name="Week 1")
self.assertEqual(xblock_studio_url(chapter), self.assertEqual(
u'/course/MITx/999/Robot_Super_Course?show={escaped_usage_key}'.format( xblock_studio_url(chapter),
escaped_usage_key='i4x%3A//MITx/999/chapter/Week_1' u'{}?show={}'.format(course_url, http.urlquote(chapter.location))
)) )
# Verify sequential URL # Verify sequential URL
sequential = ItemFactory.create(parent_location=chapter.location, category='sequential', sequential = ItemFactory.create(parent_location=chapter.location, category='sequential',
display_name="Lesson 1") display_name="Lesson 1")
self.assertEqual(xblock_studio_url(sequential), self.assertEqual(
u'/course/MITx/999/Robot_Super_Course?show={escaped_usage_key}'.format( xblock_studio_url(sequential),
escaped_usage_key='i4x%3A//MITx/999/sequential/Lesson_1' u'{}?show={}'.format(course_url, http.urlquote(sequential.location))
)) )
# Verify unit URL # Verify unit URL
vertical = ItemFactory.create(parent_location=sequential.location, category='vertical', vertical = ItemFactory.create(parent_location=sequential.location, category='vertical',
display_name='Unit') display_name='Unit')
self.assertEqual(xblock_studio_url(vertical), self.assertEqual(xblock_studio_url(vertical), u'/container/{}'.format(vertical.location))
u'/container/i4x://MITx/999/vertical/Unit')
# Verify child vertical URL # Verify child vertical URL
child_vertical = ItemFactory.create(parent_location=vertical.location, category='vertical', child_vertical = ItemFactory.create(parent_location=vertical.location, category='vertical',
display_name='Child Vertical') display_name='Child Vertical')
self.assertEqual(xblock_studio_url(child_vertical), self.assertEqual(xblock_studio_url(child_vertical), u'/container/{}'.format(child_vertical.location))
u'/container/i4x://MITx/999/vertical/Child_Vertical')
# Verify video URL # Verify video URL
video = ItemFactory.create(parent_location=child_vertical.location, category="video", video = ItemFactory.create(parent_location=child_vertical.location, category="video",
......
...@@ -293,7 +293,7 @@ class ExportTestCase(CourseTestCase): ...@@ -293,7 +293,7 @@ class ExportTestCase(CourseTestCase):
""" """
fake_xblock = ItemFactory.create(parent_location=self.course.location, category='aawefawef') fake_xblock = ItemFactory.create(parent_location=self.course.location, category='aawefawef')
self.store.publish(fake_xblock.location, self.user.id) self.store.publish(fake_xblock.location, self.user.id)
self._verify_export_failure(u'/container/i4x://MITx/999/course/Robot_Super_Course') self._verify_export_failure(u'/container/{}'.format(self.course.location))
def test_export_failure_subsection_level(self): def test_export_failure_subsection_level(self):
""" """
...@@ -305,7 +305,7 @@ class ExportTestCase(CourseTestCase): ...@@ -305,7 +305,7 @@ class ExportTestCase(CourseTestCase):
category='aawefawef' category='aawefawef'
) )
self._verify_export_failure(u'/container/i4x://MITx/999/vertical/foo') self._verify_export_failure(u'/container/{}'.format(vertical.location))
def _verify_export_failure(self, expectedText): def _verify_export_failure(self, expectedText):
""" Export failure helper method. """ """ Export failure helper method. """
......
...@@ -177,8 +177,9 @@ class GetItemTest(ItemTest): ...@@ -177,8 +177,9 @@ class GetItemTest(ItemTest):
html, html,
# The instance of the wrapper class will have an auto-generated ID. Allow any # The instance of the wrapper class will have an auto-generated ID. Allow any
# characters after wrapper. # characters after wrapper.
(r'"/container/i4x://MITx/999/wrapper/\w+" class="action-button">\s*' r'"/container/{}" class="action-button">\s*<span class="action-button-text">View</span>'.format(
'<span class="action-button-text">View</span>') wrapper_usage_key
)
) )
def test_split_test(self): def test_split_test(self):
...@@ -1269,8 +1270,8 @@ class TestXBlockInfo(ItemTest): ...@@ -1269,8 +1270,8 @@ class TestXBlockInfo(ItemTest):
Validate that the xblock info is correct for the test course. Validate that the xblock info is correct for the test course.
""" """
self.assertEqual(xblock_info['category'], 'course') self.assertEqual(xblock_info['category'], 'course')
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/course/Robot_Super_Course') self.assertEqual(xblock_info['id'], unicode(self.course.location))
self.assertEqual(xblock_info['display_name'], 'Robot Super Course') self.assertEqual(xblock_info['display_name'], self.course.display_name)
self.assertTrue(xblock_info['published']) self.assertTrue(xblock_info['published'])
# Finally, validate the entire response for consistency # Finally, validate the entire response for consistency
...@@ -1281,7 +1282,7 @@ class TestXBlockInfo(ItemTest): ...@@ -1281,7 +1282,7 @@ class TestXBlockInfo(ItemTest):
Validate that the xblock info is correct for the test chapter. Validate that the xblock info is correct for the test chapter.
""" """
self.assertEqual(xblock_info['category'], 'chapter') self.assertEqual(xblock_info['category'], 'chapter')
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/chapter/Week_1') self.assertEqual(xblock_info['id'], unicode(self.chapter.location))
self.assertEqual(xblock_info['display_name'], 'Week 1') self.assertEqual(xblock_info['display_name'], 'Week 1')
self.assertTrue(xblock_info['published']) self.assertTrue(xblock_info['published'])
self.assertIsNone(xblock_info.get('edited_by', None)) self.assertIsNone(xblock_info.get('edited_by', None))
...@@ -1299,7 +1300,7 @@ class TestXBlockInfo(ItemTest): ...@@ -1299,7 +1300,7 @@ class TestXBlockInfo(ItemTest):
Validate that the xblock info is correct for the test sequential. Validate that the xblock info is correct for the test sequential.
""" """
self.assertEqual(xblock_info['category'], 'sequential') self.assertEqual(xblock_info['category'], 'sequential')
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/sequential/Lesson_1') self.assertEqual(xblock_info['id'], unicode(self.sequential.location))
self.assertEqual(xblock_info['display_name'], 'Lesson 1') self.assertEqual(xblock_info['display_name'], 'Lesson 1')
self.assertTrue(xblock_info['published']) self.assertTrue(xblock_info['published'])
self.assertIsNone(xblock_info.get('edited_by', None)) self.assertIsNone(xblock_info.get('edited_by', None))
...@@ -1312,7 +1313,7 @@ class TestXBlockInfo(ItemTest): ...@@ -1312,7 +1313,7 @@ class TestXBlockInfo(ItemTest):
Validate that the xblock info is correct for the test vertical. Validate that the xblock info is correct for the test vertical.
""" """
self.assertEqual(xblock_info['category'], 'vertical') self.assertEqual(xblock_info['category'], 'vertical')
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/vertical/Unit_1') self.assertEqual(xblock_info['id'], unicode(self.vertical.location))
self.assertEqual(xblock_info['display_name'], 'Unit 1') self.assertEqual(xblock_info['display_name'], 'Unit 1')
self.assertTrue(xblock_info['published']) self.assertTrue(xblock_info['published'])
self.assertEqual(xblock_info['edited_by'], 'testuser') self.assertEqual(xblock_info['edited_by'], 'testuser')
...@@ -1334,7 +1335,7 @@ class TestXBlockInfo(ItemTest): ...@@ -1334,7 +1335,7 @@ class TestXBlockInfo(ItemTest):
Validate that the xblock info is correct for the test component. Validate that the xblock info is correct for the test component.
""" """
self.assertEqual(xblock_info['category'], 'video') self.assertEqual(xblock_info['category'], 'video')
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/video/My_Video') self.assertEqual(xblock_info['id'], unicode(self.video.location))
self.assertEqual(xblock_info['display_name'], 'My Video') self.assertEqual(xblock_info['display_name'], 'My Video')
self.assertTrue(xblock_info['published']) self.assertTrue(xblock_info['published'])
self.assertIsNone(xblock_info.get('edited_by', None)) self.assertIsNone(xblock_info.get('edited_by', None))
......
...@@ -45,8 +45,9 @@ class GetPreviewHtmlTestCase(TestCase): ...@@ -45,8 +45,9 @@ class GetPreviewHtmlTestCase(TestCase):
html = get_preview_fragment(request, html, context).content html = get_preview_fragment(request, html, context).content
# Verify student view html is returned, and the usage ID is as expected. # Verify student view html is returned, and the usage ID is as expected.
html_pattern = unicode(course.id.make_usage_key('html', 'html_')).replace('html_', r'html_[0-9]*')
self.assertRegexpMatches( self.assertRegexpMatches(
html, html,
'data-usage-id="i4x://MITx/999/html/html_[0-9]*"' 'data-usage-id="{}"'.format(html_pattern)
) )
self.assertRegexpMatches(html, '<html>foobar</html>') self.assertRegexpMatches(html, '<html>foobar</html>')
...@@ -192,13 +192,12 @@ class TabsPageTests(CourseTestCase): ...@@ -192,13 +192,12 @@ class TabsPageTests(CourseTestCase):
self.assertIn('<span data-tooltip="Drag to reorder" class="drag-handle action"></span>', html) self.assertIn('<span data-tooltip="Drag to reorder" class="drag-handle action"></span>', html)
class PrimitiveTabEdit(TestCase): class PrimitiveTabEdit(TestCase):
"""Tests for the primitive tab edit data manipulations""" """Tests for the primitive tab edit data manipulations"""
def test_delete(self): def test_delete(self):
"""Test primitive tab deletion.""" """Test primitive tab deletion."""
course = CourseFactory.create(org='edX', course='999') course = CourseFactory.create()
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
tabs.primitive_delete(course, 0) tabs.primitive_delete(course, 0)
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
...@@ -212,7 +211,7 @@ class PrimitiveTabEdit(TestCase): ...@@ -212,7 +211,7 @@ class PrimitiveTabEdit(TestCase):
def test_insert(self): def test_insert(self):
"""Test primitive tab insertion.""" """Test primitive tab insertion."""
course = CourseFactory.create(org='edX', course='999') course = CourseFactory.create()
tabs.primitive_insert(course, 2, 'notes', 'aname') tabs.primitive_insert(course, 2, 'notes', 'aname')
self.assertEquals(course.tabs[2], {'type': 'notes', 'name': 'aname'}) self.assertEquals(course.tabs[2], {'type': 'notes', 'name': 'aname'})
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
...@@ -222,7 +221,7 @@ class PrimitiveTabEdit(TestCase): ...@@ -222,7 +221,7 @@ class PrimitiveTabEdit(TestCase):
def test_save(self): def test_save(self):
"""Test course saving.""" """Test course saving."""
course = CourseFactory.create(org='edX', course='999') course = CourseFactory.create()
tabs.primitive_insert(course, 3, 'notes', 'aname') tabs.primitive_insert(course, 3, 'notes', 'aname')
course2 = modulestore().get_course(course.id) course2 = modulestore().get_course(course.id)
self.assertEquals(course2.tabs[3], {'type': 'notes', 'name': 'aname'}) self.assertEquals(course2.tabs[3], {'type': 'notes', 'name': 'aname'})
...@@ -5,21 +5,22 @@ from datetime import timedelta, datetime ...@@ -5,21 +5,22 @@ from datetime import timedelta, datetime
import pytz import pytz
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import TestCase
from django.test.utils import override_settings from django.test.utils import override_settings
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from reverification.models import MidcourseReverificationWindow from reverification.models import MidcourseReverificationWindow
from reverification.tests.factories import MidcourseReverificationWindowFactory from reverification.tests.factories import MidcourseReverificationWindowFactory
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class TestMidcourseReverificationWindow(TestCase): class TestMidcourseReverificationWindow(ModuleStoreTestCase):
""" Tests for MidcourseReverificationWindow objects """ """ Tests for MidcourseReverificationWindow objects """
def setUp(self):
course = CourseFactory.create() def setUp(self, **kwargs):
self.course_id = course.id super(TestMidcourseReverificationWindow, self).setUp()
self.course_id = CourseFactory.create().id
def test_window_open_for_course(self): def test_window_open_for_course(self):
# Should return False if no windows exist for a course # Should return False if no windows exist for a course
......
...@@ -177,18 +177,14 @@ class CourseEndingTest(TestCase): ...@@ -177,18 +177,14 @@ class CourseEndingTest(TestCase):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class DashboardTest(TestCase): class DashboardTest(ModuleStoreTestCase):
""" """
Tests for dashboard utility functions Tests for dashboard utility functions
""" """
# arbitrary constant
COURSE_SLUG = "100"
COURSE_NAME = "test_course"
COURSE_ORG = "EDX"
def setUp(self): def setUp(self):
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG) super(DashboardTest, self).setUp()
self.assertIsNotNone(self.course) self.course = CourseFactory.create()
self.user = UserFactory.create(username="jack", email="jack@fake.edx.org", password='test') self.user = UserFactory.create(username="jack", email="jack@fake.edx.org", password='test')
self.client = Client() self.client = Client()
...@@ -671,16 +667,11 @@ class PaidRegistrationTest(ModuleStoreTestCase): ...@@ -671,16 +667,11 @@ class PaidRegistrationTest(ModuleStoreTestCase):
""" """
Tests for paid registration functionality (not verified student), involves shoppingcart Tests for paid registration functionality (not verified student), involves shoppingcart
""" """
# arbitrary constant
COURSE_SLUG = "100"
COURSE_NAME = "test_course"
COURSE_ORG = "EDX"
def setUp(self): def setUp(self):
super(PaidRegistrationTest, self).setUp()
# Create course # Create course
self.course = CourseFactory.create()
self.req_factory = RequestFactory() self.req_factory = RequestFactory()
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG)
self.assertIsNotNone(self.course)
self.user = User.objects.create(username="jack", email="jack@fake.edx.org") self.user = User.objects.create(username="jack", email="jack@fake.edx.org")
@unittest.skipUnless(settings.FEATURES.get('ENABLE_SHOPPING_CART'), "Shopping Cart not enabled in settings") @unittest.skipUnless(settings.FEATURES.get('ENABLE_SHOPPING_CART'), "Shopping Cart not enabled in settings")
...@@ -705,18 +696,13 @@ class PaidRegistrationTest(ModuleStoreTestCase): ...@@ -705,18 +696,13 @@ class PaidRegistrationTest(ModuleStoreTestCase):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class AnonymousLookupTable(TestCase): class AnonymousLookupTable(ModuleStoreTestCase):
""" """
Tests for anonymous_id_functions Tests for anonymous_id_functions
""" """
# arbitrary constant
COURSE_SLUG = "100"
COURSE_NAME = "test_course"
COURSE_ORG = "EDX"
def setUp(self): def setUp(self):
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG) super(AnonymousLookupTable, self).setUp()
self.assertIsNotNone(self.course) self.course = CourseFactory.create()
self.user = UserFactory() self.user = UserFactory()
CourseModeFactory.create( CourseModeFactory.create(
course_id=self.course.id, course_id=self.course.id,
...@@ -739,7 +725,7 @@ class AnonymousLookupTable(TestCase): ...@@ -739,7 +725,7 @@ class AnonymousLookupTable(TestCase):
self.assertEqual(anonymous_id, anonymous_id_for_user(self.user, self.course.id, save=False)) self.assertEqual(anonymous_id, anonymous_id_for_user(self.user, self.course.id, save=False))
def test_roundtrip_with_unicode_course_id(self): def test_roundtrip_with_unicode_course_id(self):
course2 = CourseFactory.create(org=self.COURSE_ORG, display_name=u"Omega Course Ω", number=self.COURSE_SLUG) course2 = CourseFactory.create(display_name=u"Omega Course Ω")
CourseEnrollment.enroll(self.user, course2.id) CourseEnrollment.enroll(self.user, course2.id)
anonymous_id = anonymous_id_for_user(self.user, course2.id) anonymous_id = anonymous_id_for_user(self.user, course2.id)
real_user = user_by_anonymous_id(anonymous_id) real_user = user_by_anonymous_id(anonymous_id)
......
...@@ -54,7 +54,6 @@ from verify_student.models import SoftwareSecurePhotoVerification, MidcourseReve ...@@ -54,7 +54,6 @@ from verify_student.models import SoftwareSecurePhotoVerification, MidcourseReve
from certificates.models import CertificateStatuses, certificate_status_for_student from certificates.models import CertificateStatuses, certificate_status_for_student
from dark_lang.models import DarkLangConfig from dark_lang.models import DarkLangConfig
from xmodule.modulestore.exceptions import ItemNotFoundError
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from opaque_keys import InvalidKeyError from opaque_keys import InvalidKeyError
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -697,6 +696,13 @@ def change_enrollment(request, auto_register=False, check_access=True): ...@@ -697,6 +696,13 @@ def change_enrollment(request, auto_register=False, check_access=True):
del request.session['auto_register'] del request.session['auto_register']
if action == "enroll": if action == "enroll":
# Make sure the course exists
# We don't do this check on unenroll, or a bad course id can't be unenrolled from
if not modulestore().has_course(course_id):
log.warning("User {0} tried to enroll in non-existent course {1}"
.format(user.username, course_id))
return HttpResponseBadRequest(_("Course id is invalid"))
# We use this flag to determine which condition of an AB-test # We use this flag to determine which condition of an AB-test
# for auto-registration we're currently in. # for auto-registration we're currently in.
# (We have two URLs that both point to this view, but vary the # (We have two URLs that both point to this view, but vary the
......
...@@ -6,13 +6,15 @@ from factory.containers import CyclicDefinitionError ...@@ -6,13 +6,15 @@ from factory.containers import CyclicDefinitionError
from uuid import uuid4 from uuid import uuid4
from xmodule.modulestore import prefer_xmodules, ModuleStoreEnum from xmodule.modulestore import prefer_xmodules, ModuleStoreEnum
from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey from opaque_keys.edx.locations import Location
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey
from xblock.core import XBlock from xblock.core import XBlock
from xmodule.tabs import StaticTab from xmodule.tabs import StaticTab
from decorator import contextmanager from decorator import contextmanager
from mock import Mock, patch from mock import Mock, patch
from nose.tools import assert_less_equal, assert_greater_equal, assert_equal from nose.tools import assert_less_equal, assert_greater_equal
import factory
import threading
class Dummy(object): class Dummy(object):
...@@ -35,13 +37,16 @@ class XModuleFactory(Factory): ...@@ -35,13 +37,16 @@ class XModuleFactory(Factory):
return modulestore() return modulestore()
last_course = threading.local()
class CourseFactory(XModuleFactory): class CourseFactory(XModuleFactory):
""" """
Factory for XModule courses. Factory for XModule courses.
""" """
org = 'MITx' org = factory.Sequence(lambda n: 'org.%d' % n)
number = '999' number = factory.Sequence(lambda n: 'course_%d' % n)
display_name = 'Robot Super Course' display_name = factory.Sequence(lambda n: 'Run %d' % n)
# pylint: disable=unused-argument # pylint: disable=unused-argument
@classmethod @classmethod
...@@ -61,11 +66,8 @@ class CourseFactory(XModuleFactory): ...@@ -61,11 +66,8 @@ class CourseFactory(XModuleFactory):
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred): with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
# Write the data to the mongo datastore # Write the data to the mongo datastore
kwargs.update(kwargs.get('metadata', {})) kwargs.update(kwargs.get('metadata', {}))
course_key = SlashSeparatedCourseKey(org, number, run) new_course = store.create_course(org, number, run, user_id, fields=kwargs)
# TODO - We really should call create_course here. However, since create_course verifies there are no last_course.loc = new_course.location
# duplicates, this breaks several tests that do not clean up properly in between tests.
new_course = store.create_xblock(None, course_key, 'course', block_id=run, fields=kwargs)
store.update_item(new_course, user_id, allow_not_found=True)
return new_course return new_course
...@@ -96,7 +98,7 @@ class ItemFactory(XModuleFactory): ...@@ -96,7 +98,7 @@ class ItemFactory(XModuleFactory):
@lazy_attribute @lazy_attribute
def parent_location(self): def parent_location(self):
default_location = Location('MITx', '999', 'Robot_Super_Course', 'course', 'Robot_Super_Course', None) default_location = getattr(last_course, 'loc', None)
try: try:
parent = self.parent parent = self.parent
# This error is raised if the caller hasn't provided either parent or parent_location # This error is raised if the caller hasn't provided either parent or parent_location
......
...@@ -177,7 +177,7 @@ class AboutWithInvitationOnly(ModuleStoreTestCase): ...@@ -177,7 +177,7 @@ class AboutWithInvitationOnly(ModuleStoreTestCase):
url = reverse('about_course', args=[self.course.id.to_deprecated_string()]) url = reverse('about_course', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn("Register for 999", resp.content) self.assertIn(u"Register for {}".format(self.course.id.course), resp.content)
# Check that registration button is present # Check that registration button is present
self.assertIn(REG_STR, resp.content) self.assertIn(REG_STR, resp.content)
...@@ -206,7 +206,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase): ...@@ -206,7 +206,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase):
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn("OOGIE BLOOGIE", resp.content) self.assertIn("OOGIE BLOOGIE", resp.content)
self.assertIn("Register for 999", resp.content) self.assertIn(u"Register for {}".format(self.course.id.course), resp.content)
self.assertIn(SHIB_ERROR_STR, resp.content) self.assertIn(SHIB_ERROR_STR, resp.content)
self.assertIn(REG_STR, resp.content) self.assertIn(REG_STR, resp.content)
...@@ -218,7 +218,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase): ...@@ -218,7 +218,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase):
resp = self.client.get(url) resp = self.client.get(url)
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
self.assertIn("OOGIE BLOOGIE", resp.content) self.assertIn("OOGIE BLOOGIE", resp.content)
self.assertIn("Register for 999", resp.content) self.assertIn(u"Register for {}".format(self.course.id.course), resp.content)
self.assertIn(SHIB_ERROR_STR, resp.content) self.assertIn(SHIB_ERROR_STR, resp.content)
self.assertIn(REG_STR, resp.content) self.assertIn(REG_STR, resp.content)
......
...@@ -558,6 +558,7 @@ class ViewInStudioTest(ModuleStoreTestCase): ...@@ -558,6 +558,7 @@ class ViewInStudioTest(ModuleStoreTestCase):
descriptor = ItemFactory.create( descriptor = ItemFactory.create(
category='vertical', category='vertical',
parent_location=course.location,
) )
child_descriptor = ItemFactory.create( child_descriptor = ItemFactory.create(
......
...@@ -25,9 +25,9 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -25,9 +25,9 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
STUDENT_INFO = [('view@test.com', 'foo'), ('view2@test.com', 'foo')] STUDENT_INFO = [('view@test.com', 'foo'), ('view2@test.com', 'foo')]
def setUp(self): def setUp(self):
super(TestNavigation, self).setUp()
self.test_course = CourseFactory.create(display_name='Robot_Sub_Course') self.test_course = CourseFactory.create()
self.course = CourseFactory.create(display_name='Robot_Super_Course') self.course = CourseFactory.create()
self.chapter0 = ItemFactory.create(parent=self.course, self.chapter0 = ItemFactory.create(parent=self.course,
display_name='Overview') display_name='Overview')
self.chapter9 = ItemFactory.create(parent=self.course, self.chapter9 = ItemFactory.create(parent=self.course,
...@@ -57,7 +57,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -57,7 +57,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
chrome='accordion,tabs') chrome='accordion,tabs')
self.tabtest = ItemFactory.create(parent=self.chapterchrome, self.tabtest = ItemFactory.create(parent=self.chapterchrome,
display_name='progress_tab', display_name='progress_tab',
default_tab = 'progress') default_tab='progress')
# Create student accounts and activate them. # Create student accounts and activate them.
for i in range(len(self.STUDENT_INFO)): for i in range(len(self.STUDENT_INFO)):
...@@ -73,7 +73,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -73,7 +73,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
for line in response.content.split('\n'): for line in response.content.split('\n'):
if tabname in line and 'active' in line: if tabname in line and 'active' in line:
return return
raise AssertionError("assertTabActive failed: "+tabname+" not active") raise AssertionError("assertTabActive failed: {} not active".format(tabname))
def assertTabInactive(self, tabname, response): def assertTabInactive(self, tabname, response):
''' Check if the progress tab is active in the tab set ''' ''' Check if the progress tab is active in the tab set '''
...@@ -98,7 +98,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -98,7 +98,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
('fullchrome', True, True), ('fullchrome', True, True),
('accordion', True, False), ('accordion', True, False),
('fullchrome', True, True) ('fullchrome', True, True)
) )
for (displayname, accordion, tabs) in test_data: for (displayname, accordion, tabs) in test_data:
response = self.client.get(reverse('courseware_section', kwargs={ response = self.client.get(reverse('courseware_section', kwargs={
'course_id': self.course.id.to_deprecated_string(), 'course_id': self.course.id.to_deprecated_string(),
......
...@@ -101,7 +101,9 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase): ...@@ -101,7 +101,9 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase):
problem_location = self.problem_location(problem_url_name) problem_location = self.problem_location(problem_url_name)
modx_url = self.modx_url(problem_location, 'problem_check') modx_url = self.modx_url(problem_location, 'problem_check')
answer_key_prefix = 'input_i4x-' + self.course.org + '-{}-problem-{}_'.format(self.COURSE_SLUG, problem_url_name) answer_key_prefix = 'input_i4x-{}-{}-problem-{}_'.format(
self.course.org, self.course.id.course, problem_url_name
)
# format the response dictionary to be sent in the post request by adding the above prefix to each key # format the response dictionary to be sent in the post request by adding the above prefix to each key
response_dict = {(answer_key_prefix + k): v for k, v in responses.items()} response_dict = {(answer_key_prefix + k): v for k, v in responses.items()}
......
...@@ -82,11 +82,11 @@ class ViewsTestCase(TestCase): ...@@ -82,11 +82,11 @@ class ViewsTestCase(TestCase):
Tests for views.py methods. Tests for views.py methods.
""" """
def setUp(self): def setUp(self):
self.course = CourseFactory() self.course = CourseFactory.create()
self.chapter = ItemFactory(category='chapter', parent_location=self.course.location) # pylint: disable=no-member self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) # pylint: disable=no-member
self.section = ItemFactory(category='sequential', parent_location=self.chapter.location, due=datetime(2013, 9, 18, 11, 30, 00)) self.section = ItemFactory.create(category='sequential', parent_location=self.chapter.location, due=datetime(2013, 9, 18, 11, 30, 00))
self.vertical = ItemFactory(category='vertical', parent_location=self.section.location) self.vertical = ItemFactory.create(category='vertical', parent_location=self.section.location)
self.component = ItemFactory(category='problem', parent_location=self.vertical.location) self.component = ItemFactory.create(category='problem', parent_location=self.vertical.location)
self.course_key = self.course.id self.course_key = self.course.id
self.user = User.objects.create(username='dummy', password='123456', self.user = User.objects.create(username='dummy', password='123456',
...@@ -383,11 +383,11 @@ class BaseDueDateTests(ModuleStoreTestCase): ...@@ -383,11 +383,11 @@ class BaseDueDateTests(ModuleStoreTestCase):
:param course_kwargs: All kwargs are passed to through to the :class:`CourseFactory` :param course_kwargs: All kwargs are passed to through to the :class:`CourseFactory`
""" """
course = CourseFactory(**course_kwargs) course = CourseFactory.create(**course_kwargs)
chapter = ItemFactory(category='chapter', parent_location=course.location) # pylint: disable=no-member chapter = ItemFactory.create(category='chapter', parent_location=course.location) # pylint: disable=no-member
section = ItemFactory(category='sequential', parent_location=chapter.location, due=datetime(2013, 9, 18, 11, 30, 00)) section = ItemFactory.create(category='sequential', parent_location=chapter.location, due=datetime(2013, 9, 18, 11, 30, 00))
vertical = ItemFactory(category='vertical', parent_location=section.location) vertical = ItemFactory.create(category='vertical', parent_location=section.location)
ItemFactory(category='problem', parent_location=vertical.location) ItemFactory.create(category='problem', parent_location=vertical.location)
course = modulestore().get_course(course.id) # pylint: disable=no-member course = modulestore().get_course(course.id) # pylint: disable=no-member
self.assertIsNotNone(course.get_children()[0].get_children()[0].due) self.assertIsNotNone(course.get_children()[0].get_children()[0].due)
...@@ -499,7 +499,7 @@ class StartDateTests(ModuleStoreTestCase): ...@@ -499,7 +499,7 @@ class StartDateTests(ModuleStoreTestCase):
:param course_kwargs: All kwargs are passed to through to the :class:`CourseFactory` :param course_kwargs: All kwargs are passed to through to the :class:`CourseFactory`
""" """
course = CourseFactory(start=datetime(2013, 9, 16, 7, 17, 28)) course = CourseFactory.create(start=datetime(2013, 9, 16, 7, 17, 28))
course = modulestore().get_course(course.id) # pylint: disable=no-member course = modulestore().get_course(course.id) # pylint: disable=no-member
return course return course
...@@ -548,18 +548,18 @@ class ProgressPageTests(ModuleStoreTestCase): ...@@ -548,18 +548,18 @@ class ProgressPageTests(ModuleStoreTestCase):
MakoMiddleware().process_request(self.request) MakoMiddleware().process_request(self.request)
course = CourseFactory( course = CourseFactory.create(
start=datetime(2013, 9, 16, 7, 17, 28), start=datetime(2013, 9, 16, 7, 17, 28),
grade_cutoffs={u'çü†øƒƒ': 0.75, 'Pass': 0.5}, grade_cutoffs={u'çü†øƒƒ': 0.75, 'Pass': 0.5},
) )
self.course = modulestore().get_course(course.id) # pylint: disable=no-member self.course = modulestore().get_course(course.id) # pylint: disable=no-member
self.chapter = ItemFactory(category='chapter', parent_location=self.course.location) # pylint: disable=no-member self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) # pylint: disable=no-member
self.section = ItemFactory(category='sequential', parent_location=self.chapter.location) self.section = ItemFactory.create(category='sequential', parent_location=self.chapter.location)
self.vertical = ItemFactory(category='vertical', parent_location=self.section.location) self.vertical = ItemFactory.create(category='vertical', parent_location=self.section.location)
def test_pure_ungraded_xblock(self): def test_pure_ungraded_xblock(self):
ItemFactory(category='acid', parent_location=self.vertical.location) ItemFactory.create(category='acid', parent_location=self.vertical.location)
resp = views.progress(self.request, course_id=self.course.id.to_deprecated_string()) resp = views.progress(self.request, course_id=self.course.id.to_deprecated_string())
self.assertEqual(resp.status_code, 200) self.assertEqual(resp.status_code, 200)
......
...@@ -42,7 +42,7 @@ class DictionaryTestCase(TestCase): ...@@ -42,7 +42,7 @@ class DictionaryTestCase(TestCase):
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class AccessUtilsTestCase(TestCase): class AccessUtilsTestCase(ModuleStoreTestCase):
def setUp(self): def setUp(self):
self.course = CourseFactory.create() self.course = CourseFactory.create()
self.course_id = self.course.id self.course_id = self.course.id
......
...@@ -26,6 +26,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey ...@@ -26,6 +26,7 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
from submissions import api as sub_api from submissions import api as sub_api
from student.models import anonymous_id_for_user from student.models import anonymous_id_for_user
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
class TestSettableEnrollmentState(TestCase): class TestSettableEnrollmentState(TestCase):
...@@ -431,7 +432,7 @@ class TestSendBetaRoleEmail(TestCase): ...@@ -431,7 +432,7 @@ class TestSendBetaRoleEmail(TestCase):
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
class TestGetEmailParams(TestCase): class TestGetEmailParams(ModuleStoreTestCase):
""" """
Test what URLs the function get_email_params returns under different Test what URLs the function get_email_params returns under different
production-like conditions. production-like conditions.
......
...@@ -218,34 +218,36 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -218,34 +218,36 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
self.assertEqual(len(mail.outbox), 3) self.assertEqual(len(mail.outbox), 3)
self.assertEqual( self.assertEqual(
mail.outbox[0].subject, mail.outbox[0].subject,
'You have been enrolled in Robot Super Course' 'You have been enrolled in {}'.format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear Autoenrolled Test\n\nYou have been enrolled in Robot Super Course " "Dear Autoenrolled Test\n\nYou have been enrolled in {} "
"at edx.org by a member of the course staff. " "at edx.org by a member of the course staff. "
"The course should now appear on your edx.org dashboard.\n\n" "The course should now appear on your edx.org dashboard.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n" "{}://edx.org/courses/{}/\n\n"
"----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(protocol) "----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(
course.display_name, protocol, unicode(course.id)
)
) )
self.assertEqual( self.assertEqual(
mail.outbox[1].subject, mail.outbox[1].subject,
'You have been invited to register for Robot Super Course' 'You have been invited to register for {}'.format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[1].body, mail.outbox[1].body,
"Dear student,\n\nYou have been invited to join " "Dear student,\n\nYou have been invited to join "
"Robot Super Course at edx.org by a member of the " "{display_name} at edx.org by a member of the "
"course staff.\n\n" "course staff.\n\n"
"To finish your registration, please visit " "To finish your registration, please visit "
"{}://edx.org/register and fill out the registration form " "{}://edx.org/register and fill out the registration form "
"making sure to use student3_1@test.com in the E-mail field.\n" "making sure to use student3_1@test.com in the E-mail field.\n"
"Once you have registered and activated your account, you will " "Once you have registered and activated your account, you will "
"see Robot Super Course listed on your dashboard.\n\n" "see {display_name} listed on your dashboard.\n\n"
"----\nThis email was automatically sent from edx.org to " "----\nThis email was automatically sent from edx.org to "
"student3_1@test.com".format(protocol) "student3_1@test.com".format(protocol, display_name=course.display_name)
) )
def test_unenrollment_email_on(self): def test_unenrollment_email_on(self):
...@@ -271,19 +273,19 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -271,19 +273,19 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
self.assertEqual(len(mail.outbox), 3) self.assertEqual(len(mail.outbox), 3)
self.assertEqual( self.assertEqual(
mail.outbox[0].subject, mail.outbox[0].subject,
'You have been un-enrolled from Robot Super Course' 'You have been un-enrolled from {}'.format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear Student,\n\nYou have been un-enrolled from course " "Dear Student,\n\nYou have been un-enrolled from course "
"Robot Super Course by a member of the course staff. " "{} by a member of the course staff. "
"Please disregard the invitation previously sent.\n\n" "Please disregard the invitation previously sent.\n\n"
"----\nThis email was automatically sent from edx.org " "----\nThis email was automatically sent from edx.org "
"to student4_0@test.com" "to student4_0@test.com".format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[1].subject, mail.outbox[1].subject,
'You have been un-enrolled from Robot Super Course' 'You have been un-enrolled from {}'.format(course.display_name)
) )
def test_send_mail_to_student(self): def test_send_mail_to_student(self):
...@@ -322,28 +324,32 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase) ...@@ -322,28 +324,32 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
self.assertEqual(len(mail.outbox), 2) self.assertEqual(len(mail.outbox), 2)
self.assertEqual( self.assertEqual(
mail.outbox[0].subject, mail.outbox[0].subject,
'You have been enrolled in Robot Super Course' 'You have been enrolled in {}'.format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[0].body, mail.outbox[0].body,
"Dear ShibTest Enrolled\n\nYou have been enrolled in Robot Super Course " "Dear ShibTest Enrolled\n\nYou have been enrolled in {} "
"at edx.org by a member of the course staff. " "at edx.org by a member of the course staff. "
"The course should now appear on your edx.org dashboard.\n\n" "The course should now appear on your edx.org dashboard.\n\n"
"To start accessing course materials, please visit " "To start accessing course materials, please visit "
"{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n" "{}://edx.org/courses/{}/\n\n"
"----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(protocol) "----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(
course.display_name, protocol, unicode(course.id)
)
) )
self.assertEqual( self.assertEqual(
mail.outbox[1].subject, mail.outbox[1].subject,
'You have been invited to register for Robot Super Course' 'You have been invited to register for {}'.format(course.display_name)
) )
self.assertEqual( self.assertEqual(
mail.outbox[1].body, mail.outbox[1].body,
"Dear student,\n\nYou have been invited to join " "Dear student,\n\nYou have been invited to join "
"Robot Super Course at edx.org by a member of the " "{} at edx.org by a member of the "
"course staff.\n\n" "course staff.\n\n"
"To access the course visit {}://edx.org/courses/MITx/999/Robot_Super_Course/ and login.\n\n" "To access the course visit {}://edx.org/courses/{}/ and login.\n\n"
"----\nThis email was automatically sent from edx.org to " "----\nThis email was automatically sent from edx.org to "
"student5_1@test.com".format(protocol) "student5_1@test.com".format(
course.display_name, protocol, course.id
)
) )
...@@ -103,10 +103,12 @@ class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase): ...@@ -103,10 +103,12 @@ class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase):
class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase): class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
""" Test basic course registration codes analytics functions. """ """ Test basic course registration codes analytics functions. """
def setUp(self): def setUp(self):
""" """
Fixtures. Fixtures.
""" """
super(TestCourseRegistrationCodeAnalyticsBasic, self).setUp()
self.course = CourseFactory.create() self.course = CourseFactory.create()
self.instructor = InstructorFactory(course_key=self.course.id) self.instructor = InstructorFactory(course_key=self.course.id)
self.client.login(username=self.instructor.username, password='test') self.client.login(username=self.instructor.username, password='test')
......
...@@ -4,7 +4,7 @@ Tests for the Shopping Cart Models ...@@ -4,7 +4,7 @@ Tests for the Shopping Cart Models
import smtplib import smtplib
from boto.exception import BotoServerError # this is a super-class of SESError and catches connection errors from boto.exception import BotoServerError # this is a super-class of SESError and catches connection errors
from mock import patch, MagicMock, sentinel from mock import patch, MagicMock
from django.core import mail from django.core import mail
from django.conf import settings from django.conf import settings
from django.db import DatabaseError from django.db import DatabaseError
...@@ -13,7 +13,6 @@ from django.test.utils import override_settings ...@@ -13,7 +13,6 @@ from django.test.utils import override_settings
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from shoppingcart.models import (Order, OrderItem, CertificateItem, InvalidCartItem, PaidCourseRegistration, from shoppingcart.models import (Order, OrderItem, CertificateItem, InvalidCartItem, PaidCourseRegistration,
OrderItemSubclassPK) OrderItemSubclassPK)
...@@ -23,16 +22,18 @@ from course_modes.models import CourseMode ...@@ -23,16 +22,18 @@ from course_modes.models import CourseMode
from shoppingcart.exceptions import PurchasedCallbackException from shoppingcart.exceptions import PurchasedCallbackException
import pytz import pytz
import datetime import datetime
from opaque_keys.edx.locations import SlashSeparatedCourseKey
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE) @override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
class OrderTest(ModuleStoreTestCase): class OrderTest(ModuleStoreTestCase):
def setUp(self): def setUp(self):
self.user = UserFactory.create() self.user = UserFactory.create()
course = CourseFactory.create(org='org', number='test', display_name='Test Course') course = CourseFactory.create()
self.course_key = course.id self.course_key = course.id
self.other_course_keys = []
for i in xrange(1, 5): for i in xrange(1, 5):
CourseFactory.create(org='org', number='test', display_name='Test Course {0}'.format(i)) self.other_course_keys.append(CourseFactory.create())
self.cost = 40 self.cost = 40
def test_get_cart_for_user(self): def test_get_cart_for_user(self):
...@@ -71,7 +72,7 @@ class OrderTest(ModuleStoreTestCase): ...@@ -71,7 +72,7 @@ class OrderTest(ModuleStoreTestCase):
def test_cart_clear(self): def test_cart_clear(self):
cart = Order.get_cart_for_user(user=self.user) cart = Order.get_cart_for_user(user=self.user)
CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor') CertificateItem.add_to_order(cart, self.course_key, self.cost, 'honor')
CertificateItem.add_to_order(cart, SlashSeparatedCourseKey('org', 'test', 'Test_Course_1'), self.cost, 'honor') CertificateItem.add_to_order(cart, self.other_course_keys[0], self.cost, 'honor')
self.assertEquals(cart.orderitem_set.count(), 2) self.assertEquals(cart.orderitem_set.count(), 2)
self.assertTrue(cart.has_items()) self.assertTrue(cart.has_items())
cart.clear() cart.clear()
...@@ -93,12 +94,12 @@ class OrderTest(ModuleStoreTestCase): ...@@ -93,12 +94,12 @@ class OrderTest(ModuleStoreTestCase):
def test_total_cost(self): def test_total_cost(self):
cart = Order.get_cart_for_user(user=self.user) cart = Order.get_cart_for_user(user=self.user)
# add items to the order # add items to the order
course_costs = [('org/test/Test_Course_1', 30), course_costs = [(self.other_course_keys[0], 30),
('org/test/Test_Course_2', 40), (self.other_course_keys[1], 40),
('org/test/Test_Course_3', 10), (self.other_course_keys[2], 10),
('org/test/Test_Course_4', 20)] (self.other_course_keys[3], 20)]
for course, cost in course_costs: for course, cost in course_costs:
CertificateItem.add_to_order(cart, SlashSeparatedCourseKey.from_deprecated_string(course), cost, 'honor') CertificateItem.add_to_order(cart, course, cost, 'honor')
self.assertEquals(cart.orderitem_set.count(), len(course_costs)) self.assertEquals(cart.orderitem_set.count(), len(course_costs))
self.assertEquals(cart.total_cost, sum(cost for _course, cost in course_costs)) self.assertEquals(cart.total_cost, sum(cost for _course, cost in course_costs))
...@@ -290,7 +291,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -290,7 +291,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
def setUp(self): def setUp(self):
self.user = UserFactory.create() self.user = UserFactory.create()
self.cost = 40 self.cost = 40
self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course') self.course = CourseFactory.create()
self.course_key = self.course.id self.course_key = self.course.id
self.course_mode = CourseMode(course_id=self.course_key, self.course_mode = CourseMode(course_id=self.course_key,
mode_slug="honor", mode_slug="honor",
...@@ -309,7 +310,9 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -309,7 +310,9 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
self.assertEqual(reg1.user, self.user) self.assertEqual(reg1.user, self.user)
self.assertEqual(reg1.status, "cart") self.assertEqual(reg1.status, "cart")
self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_key)) self.assertTrue(PaidCourseRegistration.contained_in_order(self.cart, self.course_key))
self.assertFalse(PaidCourseRegistration.contained_in_order(self.cart, SlashSeparatedCourseKey("MITx", "999", "Robot_Super_Course_abcd"))) self.assertFalse(PaidCourseRegistration.contained_in_order(
self.cart, SlashSeparatedCourseKey("MITx", "999", "Robot_Super_Course_abcd"))
)
self.assertEqual(self.cart.total_cost, self.cost) self.assertEqual(self.cart.total_cost, self.cost)
...@@ -339,7 +342,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase): ...@@ -339,7 +342,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
""" """
Add 2 courses to the order and make sure the instruction_set only contains 1 element (no dups) Add 2 courses to the order and make sure the instruction_set only contains 1 element (no dups)
""" """
course2 = CourseFactory.create(org='MITx', number='998', display_name='Robot Duper Course') course2 = CourseFactory.create()
course_mode2 = CourseMode(course_id=course2.id, course_mode2 = CourseMode(course_id=course2.id,
mode_slug="honor", mode_slug="honor",
mode_display_name="honor cert", mode_display_name="honor cert",
...@@ -388,7 +391,7 @@ class CertificateItemTest(ModuleStoreTestCase): ...@@ -388,7 +391,7 @@ class CertificateItemTest(ModuleStoreTestCase):
def setUp(self): def setUp(self):
self.user = UserFactory.create() self.user = UserFactory.create()
self.cost = 40 self.cost = 40
course = CourseFactory.create(org='org', number='test', display_name='Test Course') course = CourseFactory.create()
self.course_key = course.id self.course_key = course.id
course_mode = CourseMode(course_id=self.course_key, course_mode = CourseMode(course_id=self.course_key,
mode_slug="honor", mode_slug="honor",
...@@ -444,7 +447,7 @@ class CertificateItemTest(ModuleStoreTestCase): ...@@ -444,7 +447,7 @@ class CertificateItemTest(ModuleStoreTestCase):
# If the expiration date has not yet passed on a verified mode, the user can be refunded # If the expiration date has not yet passed on a verified mode, the user can be refunded
many_days = datetime.timedelta(days=60) many_days = datetime.timedelta(days=60)
course = CourseFactory.create(org='refund_before_expiration', number='test', display_name='one') course = CourseFactory.create()
course_key = course.id course_key = course.id
course_mode = CourseMode(course_id=course_key, course_mode = CourseMode(course_id=course_key,
mode_slug="verified", mode_slug="verified",
...@@ -466,7 +469,7 @@ class CertificateItemTest(ModuleStoreTestCase): ...@@ -466,7 +469,7 @@ class CertificateItemTest(ModuleStoreTestCase):
def test_refund_cert_callback_before_expiration_email(self): def test_refund_cert_callback_before_expiration_email(self):
""" Test that refund emails are being sent correctly. """ """ Test that refund emails are being sent correctly. """
course = CourseFactory.create(org='refund_before_expiration', number='test', run='course', display_name='one') course = CourseFactory.create()
course_key = course.id course_key = course.id
many_days = datetime.timedelta(days=60) many_days = datetime.timedelta(days=60)
...@@ -496,7 +499,7 @@ class CertificateItemTest(ModuleStoreTestCase): ...@@ -496,7 +499,7 @@ class CertificateItemTest(ModuleStoreTestCase):
# If there's an error sending an email to billing, we need to log this error # If there's an error sending an email to billing, we need to log this error
many_days = datetime.timedelta(days=60) many_days = datetime.timedelta(days=60)
course = CourseFactory.create(org='refund_before_expiration', number='test', display_name='one') course = CourseFactory.create()
course_key = course.id course_key = course.id
course_mode = CourseMode(course_id=course_key, course_mode = CourseMode(course_id=course_key,
...@@ -519,7 +522,7 @@ class CertificateItemTest(ModuleStoreTestCase): ...@@ -519,7 +522,7 @@ class CertificateItemTest(ModuleStoreTestCase):
# If the expiration date has passed, the user cannot get a refund # If the expiration date has passed, the user cannot get a refund
many_days = datetime.timedelta(days=60) many_days = datetime.timedelta(days=60)
course = CourseFactory.create(org='refund_after_expiration', number='test', display_name='two') course = CourseFactory.create()
course_key = course.id course_key = course.id
course_mode = CourseMode(course_id=course_key, course_mode = CourseMode(course_id=course_key,
mode_slug="verified", mode_slug="verified",
......
...@@ -10,7 +10,6 @@ from django.test import TestCase ...@@ -10,7 +10,6 @@ from django.test import TestCase
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
from django.test.utils import override_settings from django.test.utils import override_settings
from django.conf import settings from django.conf import settings
import requests
import requests.exceptions import requests.exceptions
from student.tests.factories import UserFactory from student.tests.factories import UserFactory
...@@ -18,10 +17,11 @@ from verify_student.models import ( ...@@ -18,10 +17,11 @@ from verify_student.models import (
SoftwareSecurePhotoVerification, VerificationException, SoftwareSecurePhotoVerification, VerificationException,
) )
from reverification.tests.factories import MidcourseReverificationWindowFactory from reverification.tests.factories import MidcourseReverificationWindowFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
FAKE_SETTINGS = { FAKE_SETTINGS = {
"SOFTWARE_SECURE": { "SOFTWARE_SECURE": {
"FACE_IMAGE_AES_KEY" : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "FACE_IMAGE_AES_KEY": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"API_ACCESS_KEY": "BBBBBBBBBBBBBBBBBBBB", "API_ACCESS_KEY": "BBBBBBBBBBBBBBBBBBBB",
"API_SECRET_KEY": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "API_SECRET_KEY": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
"RSA_PUBLIC_KEY": """-----BEGIN PUBLIC KEY----- "RSA_PUBLIC_KEY": """-----BEGIN PUBLIC KEY-----
...@@ -420,10 +420,12 @@ class TestPhotoVerification(TestCase): ...@@ -420,10 +420,12 @@ class TestPhotoVerification(TestCase):
@patch('verify_student.models.S3Connection', new=MockS3Connection) @patch('verify_student.models.S3Connection', new=MockS3Connection)
@patch('verify_student.models.Key', new=MockKey) @patch('verify_student.models.Key', new=MockKey)
@patch('verify_student.models.requests.post', new=mock_software_secure_post) @patch('verify_student.models.requests.post', new=mock_software_secure_post)
class TestMidcourseReverification(TestCase): class TestMidcourseReverification(ModuleStoreTestCase):
""" Tests for methods that are specific to midcourse SoftwareSecurePhotoVerification objects """ """ Tests for methods that are specific to midcourse SoftwareSecurePhotoVerification objects """
def setUp(self): def setUp(self):
self.course = CourseFactory.create(org='MITx', number='999', display_name='Robot Super Course') super(TestMidcourseReverification, self).setUp()
self.course = CourseFactory.create()
self.user = UserFactory.create() self.user = UserFactory.create()
def test_user_is_reverified_for_all(self): def test_user_is_reverified_for_all(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