Use split to test views
This commit is contained in:
@@ -1,52 +0,0 @@
|
||||
"""
|
||||
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'))
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
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
|
||||
from contentstore.tests.utils import get_url
|
||||
from course_action_state.models import CourseRerunState, CourseRerunUIStateManager
|
||||
|
||||
from unittest import skipIf
|
||||
|
||||
from course_action_state.managers import CourseActionStateItemNotFoundError
|
||||
|
||||
|
||||
@@ -63,7 +61,7 @@ class ContentStoreTestCase(CourseTestCase):
|
||||
"""
|
||||
Base class for Content Store Test Cases
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class ContentStoreToyCourseTest(ContentStoreTestCase):
|
||||
"""
|
||||
@@ -317,7 +315,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
|
||||
|
||||
def test_delete(self):
|
||||
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
|
||||
ItemFactory.create(parent_location=chapterloc, category='sequential', display_name="Sequential")
|
||||
@@ -567,7 +565,7 @@ class ContentStoreToyCourseTest(ContentStoreTestCase):
|
||||
def test_illegal_draft_crud_ops(self):
|
||||
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')
|
||||
# Ensure draft mongo store does not create drafts for things that shouldn't be draft
|
||||
@@ -1186,7 +1184,7 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
def test_course_index_view_with_course(self):
|
||||
"""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/')
|
||||
self.assertContains(
|
||||
resp,
|
||||
@@ -1197,13 +1195,14 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
def test_course_overview_view_with_course(self):
|
||||
"""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)
|
||||
self.assertContains(
|
||||
resp,
|
||||
'<article class="outline outline-complex outline-course" data-locator="{locator}" data-course-key="{course_key}">'.format(
|
||||
locator='i4x://MITx/999/course/Robot_Super_Course',
|
||||
course_key='MITx/999/Robot_Super_Course',
|
||||
locator=unicode(course.location),
|
||||
course_key=unicode(course.id),
|
||||
),
|
||||
status_code=200,
|
||||
html=True
|
||||
@@ -1211,7 +1210,7 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
def test_create_item(self):
|
||||
"""Test creating a new xblock instance."""
|
||||
course = _course_factory_create_course()
|
||||
course = CourseFactory.create()()
|
||||
|
||||
section_data = {
|
||||
'parent_locator': unicode(course.location),
|
||||
@@ -1223,14 +1222,12 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
data = parse_json(resp)
|
||||
self.assertRegexpMatches(
|
||||
data['locator'],
|
||||
r"MITx/999/chapter/([0-9]|[a-f]){3,}$"
|
||||
)
|
||||
retarget = unicode(course.id.make_usage_key('chapter', 'REPLACE')).replace('REPLACE', r'([0-9]|[a-f]){3,}')
|
||||
self.assertRegexpMatches(data['locator'], retarget)
|
||||
|
||||
def test_capa_module(self):
|
||||
"""Test that a problem treats markdown specially."""
|
||||
course = _course_factory_create_course()
|
||||
course = CourseFactory.create()()
|
||||
|
||||
problem_data = {
|
||||
'parent_locator': unicode(course.location),
|
||||
@@ -1382,7 +1379,7 @@ class ContentStoreTest(ContentStoreTestCase):
|
||||
self.assertTrue(did_load_item)
|
||||
|
||||
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
|
||||
new_discussion_item = self.store.create_item(self.user.id, course.id, 'discussion', 'new_component')
|
||||
@@ -1501,8 +1498,7 @@ class MetadataSaveTestCase(ContentStoreTestCase):
|
||||
def setUp(self):
|
||||
super(MetadataSaveTestCase, self).setUp()
|
||||
|
||||
course = CourseFactory.create(
|
||||
org='edX', course='999', display_name='Robot Super Course')
|
||||
course = CourseFactory.create()
|
||||
|
||||
video_sample_xml = '''
|
||||
<video display_name="Test Video"
|
||||
@@ -1640,7 +1636,6 @@ class RerunCourseTest(ContentStoreTestCase):
|
||||
self.assertInCourseListing(source_course_key)
|
||||
self.assertInCourseListing(destination_course_key)
|
||||
|
||||
|
||||
def test_rerun_course_success(self):
|
||||
source_course = CourseFactory.create()
|
||||
destination_course_key = self.post_rerun_request(source_course.id)
|
||||
@@ -1755,13 +1750,6 @@ def _create_course(test, course_key, course_data):
|
||||
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):
|
||||
"""Returns the course ID (org/number/run)."""
|
||||
return key_class(course_data['org'], course_data['number'], course_data['run'])
|
||||
|
||||
@@ -210,57 +210,6 @@ class TestCourseListing(ModuleStoreTestCase):
|
||||
with check_mongo_calls(3):
|
||||
_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):
|
||||
"""
|
||||
Create good courses, courses that won't load, and deleted courses which still have
|
||||
|
||||
@@ -441,19 +441,19 @@ class CourseMetadataEditingTest(CourseTestCase):
|
||||
"""
|
||||
def 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.fullcourse_setting_url = get_url(self.fullcourse.id, 'advanced_settings_handler')
|
||||
|
||||
def test_fetch_initial_fields(self):
|
||||
test_model = CourseMetadata.fetch(self.course)
|
||||
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)
|
||||
self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in')
|
||||
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('showanswer', test_model, 'showanswer field ')
|
||||
self.assertIn('xqa_key', test_model, 'xqa_key field ')
|
||||
@@ -554,7 +554,7 @@ class CourseMetadataEditingTest(CourseTestCase):
|
||||
checks that updates were made
|
||||
"""
|
||||
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.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')
|
||||
@@ -564,13 +564,13 @@ class CourseMetadataEditingTest(CourseTestCase):
|
||||
response = self.client.get_json(self.course_setting_url)
|
||||
test_model = json.loads(response.content)
|
||||
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)
|
||||
test_model = json.loads(response.content)
|
||||
self.assertNotIn('graceperiod', test_model, 'blacklisted field leaked in')
|
||||
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('showanswer', test_model, 'showanswer field ')
|
||||
self.assertIn('xqa_key', test_model, 'xqa_key field ')
|
||||
|
||||
@@ -12,7 +12,7 @@ from contentstore import utils
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
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 opaque_keys.edx.locator import CourseLocator
|
||||
@@ -168,27 +168,26 @@ class CourseImageTestCase(TestCase):
|
||||
|
||||
def test_get_image_url(self):
|
||||
"""Test image URL formatting."""
|
||||
course = CourseFactory.create(org='edX', course='999')
|
||||
course = CourseFactory.create()
|
||||
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):
|
||||
# Verify that non-ascii image names are cleaned
|
||||
course = CourseFactory.create(course_image=u'before_\N{SNOWMAN}_after.jpg')
|
||||
""" Verify that non-ascii image names are cleaned """
|
||||
course_image = u'before_\N{SNOWMAN}_after.jpg'
|
||||
course = CourseFactory.create(course_image=course_image)
|
||||
self.assertEquals(
|
||||
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):
|
||||
# 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')
|
||||
self.assertEquals(
|
||||
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(" ", "_")))
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -77,11 +77,7 @@ class CourseTestCase(ModuleStoreTestCase):
|
||||
self.client = AjaxEnabledTestClient()
|
||||
self.client.login(username=self.user.username, password=user_password)
|
||||
|
||||
self.course = CourseFactory.create(
|
||||
org='MITx',
|
||||
number='999',
|
||||
display_name='Robot Super Course',
|
||||
)
|
||||
self.course = CourseFactory.create()
|
||||
|
||||
def create_non_staff_authed_user_client(self, authenticate=True):
|
||||
"""
|
||||
|
||||
@@ -8,6 +8,7 @@ from pytz import UTC
|
||||
from contentstore.views.tests.utils import StudioPageTestCase
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.factories import ItemFactory
|
||||
from django.utils import http
|
||||
|
||||
|
||||
class ContainerPageTestCase(StudioPageTestCase):
|
||||
@@ -59,8 +60,8 @@ class ContainerPageTestCase(StudioPageTestCase):
|
||||
course=re.escape(unicode(self.course.id)),
|
||||
unit=re.escape(unicode(self.vertical.location)),
|
||||
classes='navigation-item navigation-link navigation-parent',
|
||||
section_parameters=re.escape(u'?show=i4x%3A//MITx/999/chapter/Week_1'),
|
||||
subsection_parameters=re.escape(u'?show=i4x%3A//MITx/999/sequential/Lesson_1'),
|
||||
section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
|
||||
subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -89,8 +90,8 @@ class ContainerPageTestCase(StudioPageTestCase):
|
||||
unit=re.escape(unicode(self.vertical.location)),
|
||||
split_test=re.escape(unicode(self.child_container.location)),
|
||||
classes='navigation-item navigation-link navigation-parent',
|
||||
section_parameters=re.escape(u'?show=i4x%3A//MITx/999/chapter/Week_1'),
|
||||
subsection_parameters=re.escape(u'?show=i4x%3A//MITx/999/sequential/Lesson_1'),
|
||||
section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
|
||||
subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
@@ -106,8 +106,8 @@ class TestCourseIndex(CourseTestCase):
|
||||
|
||||
# First spot check some values in the root response
|
||||
self.assertEqual(json_response['category'], 'course')
|
||||
self.assertEqual(json_response['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
self.assertEqual(json_response['display_name'], 'Robot Super Course')
|
||||
self.assertEqual(json_response['id'], unicode(self.course.location))
|
||||
self.assertEqual(json_response['display_name'], self.course.display_name)
|
||||
self.assertTrue(json_response['published'])
|
||||
self.assertIsNone(json_response['visibility_state'])
|
||||
|
||||
@@ -116,7 +116,7 @@ class TestCourseIndex(CourseTestCase):
|
||||
self.assertTrue(len(children) > 0)
|
||||
first_child_response = children[0]
|
||||
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.assertTrue(json_response['published'])
|
||||
self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled)
|
||||
@@ -227,8 +227,8 @@ class TestCourseOutline(CourseTestCase):
|
||||
|
||||
# First spot check some values in the root response
|
||||
self.assertEqual(json_response['category'], 'course')
|
||||
self.assertEqual(json_response['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
self.assertEqual(json_response['display_name'], 'Robot Super Course')
|
||||
self.assertEqual(json_response['id'], unicode(self.course.location))
|
||||
self.assertEqual(json_response['display_name'], self.course.display_name)
|
||||
self.assertTrue(json_response['published'])
|
||||
self.assertIsNone(json_response['visibility_state'])
|
||||
|
||||
@@ -237,7 +237,7 @@ class TestCourseOutline(CourseTestCase):
|
||||
self.assertTrue(len(children) > 0)
|
||||
first_child_response = children[0]
|
||||
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.assertTrue(json_response['published'])
|
||||
self.assertEqual(first_child_response['visibility_state'], VisibilityState.unscheduled)
|
||||
|
||||
@@ -10,6 +10,8 @@ from contentstore.tests.utils import CourseTestCase
|
||||
from xmodule.partitions.partitions import Group, UserPartition
|
||||
from xmodule.modulestore.tests.factories import ItemFactory
|
||||
from xmodule.split_test_module import ValidationMessage, ValidationMessageType
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
|
||||
GROUP_CONFIGURATION_JSON = {
|
||||
u'name': u'Test name',
|
||||
@@ -266,12 +268,6 @@ class GroupConfigurationsDetailHandlerTestCase(CourseTestCase, GroupConfiguratio
|
||||
|
||||
ID = 0
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up GroupConfigurationsDetailHandlerTestCase.
|
||||
"""
|
||||
super(GroupConfigurationsDetailHandlerTestCase, self).setUp()
|
||||
|
||||
def _url(self, cid=-1):
|
||||
"""
|
||||
Return url for the handler.
|
||||
@@ -450,7 +446,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
|
||||
Test if group configurations json updated successfully with usage information.
|
||||
"""
|
||||
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')
|
||||
|
||||
actual = GroupConfiguration.add_usage_info(self.course, self.store)
|
||||
@@ -466,7 +462,7 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
|
||||
{'id': 2, 'name': 'Group C', 'version': 1},
|
||||
],
|
||||
'usage': [{
|
||||
'url': '/container/i4x://MITx/999/vertical/Test_Unit_0',
|
||||
'url': '/container/{}'.format(vertical.location),
|
||||
'label': 'Test Unit 0 / Test Content Experiment 0',
|
||||
'validation': None,
|
||||
}],
|
||||
@@ -491,8 +487,8 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
|
||||
group configuration.
|
||||
"""
|
||||
self._add_user_partitions()
|
||||
self._create_content_experiment(cid=0, name_suffix='0')
|
||||
self._create_content_experiment(cid=0, name_suffix='1')
|
||||
vertical, __ = self._create_content_experiment(cid=0, name_suffix='0')
|
||||
vertical1, __ = self._create_content_experiment(cid=0, name_suffix='1')
|
||||
|
||||
actual = GroupConfiguration.add_usage_info(self.course, self.store)
|
||||
|
||||
@@ -507,11 +503,11 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
|
||||
{'id': 2, 'name': 'Group C', 'version': 1},
|
||||
],
|
||||
'usage': [{
|
||||
'url': '/container/i4x://MITx/999/vertical/Test_Unit_0',
|
||||
'url': '/container/{}'.format(vertical.location),
|
||||
'label': 'Test Unit 0 / Test Content Experiment 0',
|
||||
'validation': None,
|
||||
}, {
|
||||
'url': '/container/i4x://MITx/999/vertical/Test_Unit_1',
|
||||
'url': '/container/{}'.format(vertical1.location),
|
||||
'label': 'Test Unit 1 / Test Content Experiment 1',
|
||||
'validation': None,
|
||||
}],
|
||||
@@ -524,11 +520,15 @@ class GroupConfigurationsUsageInfoTestCase(CourseTestCase, HelperMethods):
|
||||
"""
|
||||
self._add_user_partitions()
|
||||
# Create split test without parent.
|
||||
ItemFactory.create(
|
||||
category='split_test',
|
||||
user_partition_id=0,
|
||||
display_name='Test Content Experiment'
|
||||
)
|
||||
with modulestore().branch_setting(ModuleStoreEnum.Branch.published_only):
|
||||
orphan = modulestore().create_item(
|
||||
ModuleStoreEnum.UserID.test,
|
||||
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()
|
||||
actual = GroupConfiguration.get_usage_info(self.course, self.store)
|
||||
self.assertEqual(actual, {0: []})
|
||||
|
||||
@@ -5,6 +5,7 @@ Unit tests for helpers.py.
|
||||
from contentstore.tests.utils import CourseTestCase
|
||||
from contentstore.views.helpers import xblock_studio_url, xblock_type_display_name
|
||||
from xmodule.modulestore.tests.factories import ItemFactory
|
||||
from django.utils import http
|
||||
|
||||
|
||||
class HelpersTestCase(CourseTestCase):
|
||||
@@ -15,36 +16,34 @@ class HelpersTestCase(CourseTestCase):
|
||||
def test_xblock_studio_url(self):
|
||||
|
||||
# Verify course URL
|
||||
self.assertEqual(xblock_studio_url(self.course),
|
||||
u'/course/MITx/999/Robot_Super_Course')
|
||||
course_url = u'/course/{}'.format(unicode(self.course.id))
|
||||
self.assertEqual(xblock_studio_url(self.course), course_url)
|
||||
|
||||
# Verify chapter URL
|
||||
chapter = ItemFactory.create(parent_location=self.course.location, category='chapter',
|
||||
display_name="Week 1")
|
||||
self.assertEqual(xblock_studio_url(chapter),
|
||||
u'/course/MITx/999/Robot_Super_Course?show={escaped_usage_key}'.format(
|
||||
escaped_usage_key='i4x%3A//MITx/999/chapter/Week_1'
|
||||
))
|
||||
self.assertEqual(
|
||||
xblock_studio_url(chapter),
|
||||
u'{}?show={}'.format(course_url, http.urlquote(chapter.location))
|
||||
)
|
||||
|
||||
# Verify sequential URL
|
||||
sequential = ItemFactory.create(parent_location=chapter.location, category='sequential',
|
||||
display_name="Lesson 1")
|
||||
self.assertEqual(xblock_studio_url(sequential),
|
||||
u'/course/MITx/999/Robot_Super_Course?show={escaped_usage_key}'.format(
|
||||
escaped_usage_key='i4x%3A//MITx/999/sequential/Lesson_1'
|
||||
))
|
||||
self.assertEqual(
|
||||
xblock_studio_url(sequential),
|
||||
u'{}?show={}'.format(course_url, http.urlquote(sequential.location))
|
||||
)
|
||||
|
||||
# Verify unit URL
|
||||
vertical = ItemFactory.create(parent_location=sequential.location, category='vertical',
|
||||
display_name='Unit')
|
||||
self.assertEqual(xblock_studio_url(vertical),
|
||||
u'/container/i4x://MITx/999/vertical/Unit')
|
||||
self.assertEqual(xblock_studio_url(vertical), u'/container/{}'.format(vertical.location))
|
||||
|
||||
# Verify child vertical URL
|
||||
child_vertical = ItemFactory.create(parent_location=vertical.location, category='vertical',
|
||||
display_name='Child Vertical')
|
||||
self.assertEqual(xblock_studio_url(child_vertical),
|
||||
u'/container/i4x://MITx/999/vertical/Child_Vertical')
|
||||
self.assertEqual(xblock_studio_url(child_vertical), u'/container/{}'.format(child_vertical.location))
|
||||
|
||||
# Verify video URL
|
||||
video = ItemFactory.create(parent_location=child_vertical.location, category="video",
|
||||
|
||||
@@ -293,7 +293,7 @@ class ExportTestCase(CourseTestCase):
|
||||
"""
|
||||
fake_xblock = ItemFactory.create(parent_location=self.course.location, category='aawefawef')
|
||||
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):
|
||||
"""
|
||||
@@ -305,7 +305,7 @@ class ExportTestCase(CourseTestCase):
|
||||
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):
|
||||
""" Export failure helper method. """
|
||||
|
||||
@@ -177,8 +177,9 @@ class GetItemTest(ItemTest):
|
||||
html,
|
||||
# The instance of the wrapper class will have an auto-generated ID. Allow any
|
||||
# characters after wrapper.
|
||||
(r'"/container/i4x://MITx/999/wrapper/\w+" class="action-button">\s*'
|
||||
'<span class="action-button-text">View</span>')
|
||||
r'"/container/{}" class="action-button">\s*<span class="action-button-text">View</span>'.format(
|
||||
wrapper_usage_key
|
||||
)
|
||||
)
|
||||
|
||||
def test_split_test(self):
|
||||
@@ -1269,8 +1270,8 @@ class TestXBlockInfo(ItemTest):
|
||||
Validate that the xblock info is correct for the test course.
|
||||
"""
|
||||
self.assertEqual(xblock_info['category'], 'course')
|
||||
self.assertEqual(xblock_info['id'], 'i4x://MITx/999/course/Robot_Super_Course')
|
||||
self.assertEqual(xblock_info['display_name'], 'Robot Super Course')
|
||||
self.assertEqual(xblock_info['id'], unicode(self.course.location))
|
||||
self.assertEqual(xblock_info['display_name'], self.course.display_name)
|
||||
self.assertTrue(xblock_info['published'])
|
||||
|
||||
# Finally, validate the entire response for consistency
|
||||
@@ -1281,7 +1282,7 @@ class TestXBlockInfo(ItemTest):
|
||||
Validate that the xblock info is correct for the test 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.assertTrue(xblock_info['published'])
|
||||
self.assertIsNone(xblock_info.get('edited_by', None))
|
||||
@@ -1299,7 +1300,7 @@ class TestXBlockInfo(ItemTest):
|
||||
Validate that the xblock info is correct for the test 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.assertTrue(xblock_info['published'])
|
||||
self.assertIsNone(xblock_info.get('edited_by', None))
|
||||
@@ -1312,7 +1313,7 @@ class TestXBlockInfo(ItemTest):
|
||||
Validate that the xblock info is correct for the test 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.assertTrue(xblock_info['published'])
|
||||
self.assertEqual(xblock_info['edited_by'], 'testuser')
|
||||
@@ -1334,7 +1335,7 @@ class TestXBlockInfo(ItemTest):
|
||||
Validate that the xblock info is correct for the test component.
|
||||
"""
|
||||
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.assertTrue(xblock_info['published'])
|
||||
self.assertIsNone(xblock_info.get('edited_by', None))
|
||||
|
||||
@@ -45,8 +45,9 @@ class GetPreviewHtmlTestCase(TestCase):
|
||||
html = get_preview_fragment(request, html, context).content
|
||||
|
||||
# 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(
|
||||
html,
|
||||
'data-usage-id="i4x://MITx/999/html/html_[0-9]*"'
|
||||
'data-usage-id="{}"'.format(html_pattern)
|
||||
)
|
||||
self.assertRegexpMatches(html, '<html>foobar</html>')
|
||||
|
||||
@@ -192,13 +192,12 @@ class TabsPageTests(CourseTestCase):
|
||||
self.assertIn('<span data-tooltip="Drag to reorder" class="drag-handle action"></span>', html)
|
||||
|
||||
|
||||
|
||||
class PrimitiveTabEdit(TestCase):
|
||||
"""Tests for the primitive tab edit data manipulations"""
|
||||
|
||||
def test_delete(self):
|
||||
"""Test primitive tab deletion."""
|
||||
course = CourseFactory.create(org='edX', course='999')
|
||||
course = CourseFactory.create()
|
||||
with self.assertRaises(ValueError):
|
||||
tabs.primitive_delete(course, 0)
|
||||
with self.assertRaises(ValueError):
|
||||
@@ -212,7 +211,7 @@ class PrimitiveTabEdit(TestCase):
|
||||
|
||||
def test_insert(self):
|
||||
"""Test primitive tab insertion."""
|
||||
course = CourseFactory.create(org='edX', course='999')
|
||||
course = CourseFactory.create()
|
||||
tabs.primitive_insert(course, 2, 'notes', 'aname')
|
||||
self.assertEquals(course.tabs[2], {'type': 'notes', 'name': 'aname'})
|
||||
with self.assertRaises(ValueError):
|
||||
@@ -222,7 +221,7 @@ class PrimitiveTabEdit(TestCase):
|
||||
|
||||
def test_save(self):
|
||||
"""Test course saving."""
|
||||
course = CourseFactory.create(org='edX', course='999')
|
||||
course = CourseFactory.create()
|
||||
tabs.primitive_insert(course, 3, 'notes', 'aname')
|
||||
course2 = modulestore().get_course(course.id)
|
||||
self.assertEquals(course2.tabs[3], {'type': 'notes', 'name': 'aname'})
|
||||
|
||||
@@ -5,21 +5,22 @@ from datetime import timedelta, datetime
|
||||
import pytz
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
|
||||
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
|
||||
from reverification.models import MidcourseReverificationWindow
|
||||
from reverification.tests.factories import MidcourseReverificationWindowFactory
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class TestMidcourseReverificationWindow(TestCase):
|
||||
class TestMidcourseReverificationWindow(ModuleStoreTestCase):
|
||||
""" Tests for MidcourseReverificationWindow objects """
|
||||
def setUp(self):
|
||||
course = CourseFactory.create()
|
||||
self.course_id = course.id
|
||||
|
||||
def setUp(self, **kwargs):
|
||||
super(TestMidcourseReverificationWindow, self).setUp()
|
||||
self.course_id = CourseFactory.create().id
|
||||
|
||||
def test_window_open_for_course(self):
|
||||
# Should return False if no windows exist for a course
|
||||
|
||||
@@ -177,18 +177,14 @@ class CourseEndingTest(TestCase):
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
||||
class DashboardTest(TestCase):
|
||||
class DashboardTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for dashboard utility functions
|
||||
"""
|
||||
# arbitrary constant
|
||||
COURSE_SLUG = "100"
|
||||
COURSE_NAME = "test_course"
|
||||
COURSE_ORG = "EDX"
|
||||
|
||||
def setUp(self):
|
||||
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG)
|
||||
self.assertIsNotNone(self.course)
|
||||
super(DashboardTest, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.user = UserFactory.create(username="jack", email="jack@fake.edx.org", password='test')
|
||||
self.client = Client()
|
||||
|
||||
@@ -671,16 +667,11 @@ class PaidRegistrationTest(ModuleStoreTestCase):
|
||||
"""
|
||||
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):
|
||||
super(PaidRegistrationTest, self).setUp()
|
||||
# Create course
|
||||
self.course = CourseFactory.create()
|
||||
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")
|
||||
|
||||
@unittest.skipUnless(settings.FEATURES.get('ENABLE_SHOPPING_CART'), "Shopping Cart not enabled in settings")
|
||||
@@ -705,18 +696,13 @@ class PaidRegistrationTest(ModuleStoreTestCase):
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
||||
class AnonymousLookupTable(TestCase):
|
||||
class AnonymousLookupTable(ModuleStoreTestCase):
|
||||
"""
|
||||
Tests for anonymous_id_functions
|
||||
"""
|
||||
# arbitrary constant
|
||||
COURSE_SLUG = "100"
|
||||
COURSE_NAME = "test_course"
|
||||
COURSE_ORG = "EDX"
|
||||
|
||||
def setUp(self):
|
||||
self.course = CourseFactory.create(org=self.COURSE_ORG, display_name=self.COURSE_NAME, number=self.COURSE_SLUG)
|
||||
self.assertIsNotNone(self.course)
|
||||
super(AnonymousLookupTable, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.user = UserFactory()
|
||||
CourseModeFactory.create(
|
||||
course_id=self.course.id,
|
||||
@@ -739,7 +725,7 @@ class AnonymousLookupTable(TestCase):
|
||||
self.assertEqual(anonymous_id, anonymous_id_for_user(self.user, self.course.id, save=False))
|
||||
|
||||
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)
|
||||
anonymous_id = anonymous_id_for_user(self.user, course2.id)
|
||||
real_user = user_by_anonymous_id(anonymous_id)
|
||||
|
||||
@@ -54,7 +54,6 @@ from verify_student.models import SoftwareSecurePhotoVerification, MidcourseReve
|
||||
from certificates.models import CertificateStatuses, certificate_status_for_student
|
||||
from dark_lang.models import DarkLangConfig
|
||||
|
||||
from xmodule.modulestore.exceptions import ItemNotFoundError
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
@@ -697,6 +696,13 @@ def change_enrollment(request, auto_register=False, check_access=True):
|
||||
del request.session['auto_register']
|
||||
|
||||
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
|
||||
# for auto-registration we're currently in.
|
||||
# (We have two URLs that both point to this view, but vary the
|
||||
|
||||
@@ -6,13 +6,15 @@ from factory.containers import CyclicDefinitionError
|
||||
from uuid import uuid4
|
||||
|
||||
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 xblock.core import XBlock
|
||||
from xmodule.tabs import StaticTab
|
||||
from decorator import contextmanager
|
||||
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):
|
||||
@@ -35,13 +37,16 @@ class XModuleFactory(Factory):
|
||||
return modulestore()
|
||||
|
||||
|
||||
last_course = threading.local()
|
||||
|
||||
|
||||
class CourseFactory(XModuleFactory):
|
||||
"""
|
||||
Factory for XModule courses.
|
||||
"""
|
||||
org = 'MITx'
|
||||
number = '999'
|
||||
display_name = 'Robot Super Course'
|
||||
org = factory.Sequence(lambda n: 'org.%d' % n)
|
||||
number = factory.Sequence(lambda n: 'course_%d' % n)
|
||||
display_name = factory.Sequence(lambda n: 'Run %d' % n)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
@classmethod
|
||||
@@ -61,11 +66,8 @@ class CourseFactory(XModuleFactory):
|
||||
with store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
|
||||
# Write the data to the mongo datastore
|
||||
kwargs.update(kwargs.get('metadata', {}))
|
||||
course_key = SlashSeparatedCourseKey(org, number, run)
|
||||
# TODO - We really should call create_course here. However, since create_course verifies there are no
|
||||
# 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)
|
||||
new_course = store.create_course(org, number, run, user_id, fields=kwargs)
|
||||
last_course.loc = new_course.location
|
||||
return new_course
|
||||
|
||||
|
||||
@@ -96,7 +98,7 @@ class ItemFactory(XModuleFactory):
|
||||
|
||||
@lazy_attribute
|
||||
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:
|
||||
parent = self.parent
|
||||
# This error is raised if the caller hasn't provided either parent or parent_location
|
||||
|
||||
@@ -177,7 +177,7 @@ class AboutWithInvitationOnly(ModuleStoreTestCase):
|
||||
url = reverse('about_course', args=[self.course.id.to_deprecated_string()])
|
||||
resp = self.client.get(url)
|
||||
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
|
||||
self.assertIn(REG_STR, resp.content)
|
||||
@@ -206,7 +206,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
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(REG_STR, resp.content)
|
||||
|
||||
@@ -218,7 +218,7 @@ class AboutTestCaseShibCourse(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
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(REG_STR, resp.content)
|
||||
|
||||
|
||||
@@ -558,6 +558,7 @@ class ViewInStudioTest(ModuleStoreTestCase):
|
||||
|
||||
descriptor = ItemFactory.create(
|
||||
category='vertical',
|
||||
parent_location=course.location,
|
||||
)
|
||||
|
||||
child_descriptor = ItemFactory.create(
|
||||
|
||||
@@ -25,9 +25,9 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
STUDENT_INFO = [('view@test.com', 'foo'), ('view2@test.com', 'foo')]
|
||||
|
||||
def setUp(self):
|
||||
|
||||
self.test_course = CourseFactory.create(display_name='Robot_Sub_Course')
|
||||
self.course = CourseFactory.create(display_name='Robot_Super_Course')
|
||||
super(TestNavigation, self).setUp()
|
||||
self.test_course = CourseFactory.create()
|
||||
self.course = CourseFactory.create()
|
||||
self.chapter0 = ItemFactory.create(parent=self.course,
|
||||
display_name='Overview')
|
||||
self.chapter9 = ItemFactory.create(parent=self.course,
|
||||
@@ -57,7 +57,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
chrome='accordion,tabs')
|
||||
self.tabtest = ItemFactory.create(parent=self.chapterchrome,
|
||||
display_name='progress_tab',
|
||||
default_tab = 'progress')
|
||||
default_tab='progress')
|
||||
|
||||
# Create student accounts and activate them.
|
||||
for i in range(len(self.STUDENT_INFO)):
|
||||
@@ -73,7 +73,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
for line in response.content.split('\n'):
|
||||
if tabname in line and 'active' in line:
|
||||
return
|
||||
raise AssertionError("assertTabActive failed: "+tabname+" not active")
|
||||
raise AssertionError("assertTabActive failed: {} not active".format(tabname))
|
||||
|
||||
def assertTabInactive(self, tabname, response):
|
||||
''' Check if the progress tab is active in the tab set '''
|
||||
@@ -98,7 +98,7 @@ class TestNavigation(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
('fullchrome', True, True),
|
||||
('accordion', True, False),
|
||||
('fullchrome', True, True)
|
||||
)
|
||||
)
|
||||
for (displayname, accordion, tabs) in test_data:
|
||||
response = self.client.get(reverse('courseware_section', kwargs={
|
||||
'course_id': self.course.id.to_deprecated_string(),
|
||||
|
||||
@@ -101,7 +101,9 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
problem_location = self.problem_location(problem_url_name)
|
||||
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
|
||||
response_dict = {(answer_key_prefix + k): v for k, v in responses.items()}
|
||||
|
||||
@@ -82,11 +82,11 @@ class ViewsTestCase(TestCase):
|
||||
Tests for views.py methods.
|
||||
"""
|
||||
def setUp(self):
|
||||
self.course = CourseFactory()
|
||||
self.chapter = ItemFactory(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.vertical = ItemFactory(category='vertical', parent_location=self.section.location)
|
||||
self.component = ItemFactory(category='problem', parent_location=self.vertical.location)
|
||||
self.course = CourseFactory.create()
|
||||
self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) # pylint: disable=no-member
|
||||
self.section = ItemFactory.create(category='sequential', parent_location=self.chapter.location, due=datetime(2013, 9, 18, 11, 30, 00))
|
||||
self.vertical = ItemFactory.create(category='vertical', parent_location=self.section.location)
|
||||
self.component = ItemFactory.create(category='problem', parent_location=self.vertical.location)
|
||||
|
||||
self.course_key = self.course.id
|
||||
self.user = User.objects.create(username='dummy', password='123456',
|
||||
@@ -383,11 +383,11 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
|
||||
:param course_kwargs: All kwargs are passed to through to the :class:`CourseFactory`
|
||||
"""
|
||||
course = CourseFactory(**course_kwargs)
|
||||
chapter = ItemFactory(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))
|
||||
vertical = ItemFactory(category='vertical', parent_location=section.location)
|
||||
ItemFactory(category='problem', parent_location=vertical.location)
|
||||
course = CourseFactory.create(**course_kwargs)
|
||||
chapter = ItemFactory.create(category='chapter', parent_location=course.location) # pylint: disable=no-member
|
||||
section = ItemFactory.create(category='sequential', parent_location=chapter.location, due=datetime(2013, 9, 18, 11, 30, 00))
|
||||
vertical = ItemFactory.create(category='vertical', parent_location=section.location)
|
||||
ItemFactory.create(category='problem', parent_location=vertical.location)
|
||||
|
||||
course = modulestore().get_course(course.id) # pylint: disable=no-member
|
||||
self.assertIsNotNone(course.get_children()[0].get_children()[0].due)
|
||||
@@ -499,7 +499,7 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
|
||||
: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
|
||||
return course
|
||||
|
||||
@@ -548,18 +548,18 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
|
||||
MakoMiddleware().process_request(self.request)
|
||||
|
||||
course = CourseFactory(
|
||||
course = CourseFactory.create(
|
||||
start=datetime(2013, 9, 16, 7, 17, 28),
|
||||
grade_cutoffs={u'çü†øƒƒ': 0.75, 'Pass': 0.5},
|
||||
)
|
||||
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.section = ItemFactory(category='sequential', parent_location=self.chapter.location)
|
||||
self.vertical = ItemFactory(category='vertical', parent_location=self.section.location)
|
||||
self.chapter = ItemFactory.create(category='chapter', parent_location=self.course.location) # pylint: disable=no-member
|
||||
self.section = ItemFactory.create(category='sequential', parent_location=self.chapter.location)
|
||||
self.vertical = ItemFactory.create(category='vertical', parent_location=self.section.location)
|
||||
|
||||
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())
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@@ -42,7 +42,7 @@ class DictionaryTestCase(TestCase):
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class AccessUtilsTestCase(TestCase):
|
||||
class AccessUtilsTestCase(ModuleStoreTestCase):
|
||||
def setUp(self):
|
||||
self.course = CourseFactory.create()
|
||||
self.course_id = self.course.id
|
||||
|
||||
@@ -17,7 +17,7 @@ from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django_comment_common.models import FORUM_ROLE_COMMUNITY_TA, Role
|
||||
from django_comment_common.models import FORUM_ROLE_COMMUNITY_TA
|
||||
from django_comment_common.utils import seed_permissions_roles
|
||||
from django.core import mail
|
||||
from django.utils.timezone import utc
|
||||
@@ -39,7 +39,6 @@ from courseware.models import StudentModule
|
||||
|
||||
# modules which are mocked in test cases.
|
||||
import instructor_task.api
|
||||
from instructor.access import allow_access
|
||||
import instructor.views.api
|
||||
from instructor.views.api import _split_input_list, common_exceptions_400
|
||||
from instructor_task.api_helper import AlreadyRunningError
|
||||
@@ -56,6 +55,7 @@ from ..views.tools import get_extended_due
|
||||
EXPECTED_CSV_HEADER = '"code","course_id","company_name","created_by","redeemed_by","invoice_id","purchaser","customer_reference_number","internal_reference"'
|
||||
EXPECTED_COUPON_CSV_HEADER = '"course_id","percentage_discount","code_redeemed_count","description"'
|
||||
|
||||
|
||||
@common_exceptions_400
|
||||
def view_success(request): # pylint: disable=W0613
|
||||
"A dummy view for testing that returns a simple HTTP response"
|
||||
@@ -486,16 +486,17 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been enrolled in Robot Super Course'
|
||||
u'You have been enrolled in {}'.format(self.course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear NotEnrolled Student\n\nYou have been enrolled in Robot Super Course "
|
||||
"Dear NotEnrolled Student\n\nYou have been enrolled in {} "
|
||||
"at edx.org by a member of the course staff. "
|
||||
"The course should now appear on your edx.org dashboard.\n\n"
|
||||
"To start accessing course materials, please visit "
|
||||
"{proto}://{site}{course_path}\n\n----\n"
|
||||
"This email was automatically sent from edx.org to NotEnrolled Student".format(
|
||||
self.course.display_name,
|
||||
proto=protocol, site=self.site_name, course_path=self.course_path
|
||||
)
|
||||
)
|
||||
@@ -512,17 +513,17 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to register for Robot Super Course'
|
||||
u'You have been invited to register for {}'.format(self.course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"Dear student,\n\nYou have been invited to join {} at edx.org by a member of the course staff.\n\n"
|
||||
"To finish your registration, please visit {proto}://{site}/register and fill out the "
|
||||
"registration form making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
|
||||
"Once you have registered and activated your account, "
|
||||
"visit {proto}://{site}{about_path} to join the course.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
proto=protocol, site=self.site_name, about_path=self.about_path
|
||||
self.course.display_name, proto=protocol, site=self.site_name, about_path=self.about_path
|
||||
)
|
||||
)
|
||||
|
||||
@@ -537,12 +538,12 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"Dear student,\n\nYou have been invited to join {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"To finish your registration, please visit {proto}://{site}/register and fill out the registration form "
|
||||
"making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
|
||||
"You can then enroll in Robot Super Course.\n\n----\n"
|
||||
"You can then enroll in {display_name}.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
proto=protocol, site=self.site_name
|
||||
display_name=self.course.display_name, proto=protocol, site=self.site_name
|
||||
)
|
||||
)
|
||||
|
||||
@@ -560,16 +561,16 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to register for Robot Super Course'
|
||||
u'You have been invited to register for {}'.format(self.course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"Dear student,\n\nYou have been invited to join {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"To finish your registration, please visit {proto}://{site}/register and fill out the registration form "
|
||||
"making sure to use robot-not-an-email-yet@robot.org in the E-mail field.\n"
|
||||
"Once you have registered and activated your account, you will see Robot Super Course listed on your dashboard.\n\n----\n"
|
||||
"Once you have registered and activated your account, you will see {display_name} listed on your dashboard.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
proto=protocol, site=self.site_name
|
||||
proto=protocol, site=self.site_name, display_name=self.course.display_name
|
||||
)
|
||||
)
|
||||
|
||||
@@ -652,15 +653,17 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been un-enrolled from Robot Super Course'
|
||||
'You have been un-enrolled from {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear Enrolled Student\n\nYou have been un-enrolled in Robot Super Course "
|
||||
"Dear Enrolled Student\n\nYou have been un-enrolled in {display_name} "
|
||||
"at edx.org by a member of the course staff. "
|
||||
"The course will no longer appear on your edx.org dashboard.\n\n"
|
||||
"Your other courses have not been affected.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to Enrolled Student"
|
||||
"This email was automatically sent from edx.org to Enrolled Student".format(
|
||||
display_name=self.course.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
def test_unenroll_with_email_allowed_student(self):
|
||||
@@ -699,13 +702,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been un-enrolled from Robot Super Course'
|
||||
'You have been un-enrolled from {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear Student,\n\nYou have been un-enrolled from course Robot Super Course by a member of the course staff. "
|
||||
"Dear Student,\n\nYou have been un-enrolled from course {display_name} by a member of the course staff. "
|
||||
"Please disregard the invitation previously sent.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-allowed@robot.org"
|
||||
"This email was automatically sent from edx.org to robot-allowed@robot.org".format(
|
||||
display_name=self.course.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
@ddt.data('http', 'https')
|
||||
@@ -723,15 +728,16 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to register for Robot Super Course'
|
||||
'You have been invited to register for {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"Dear student,\n\nYou have been invited to join {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"To access the course visit {proto}://{site}{about_path} and register for the course.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
proto=protocol, site=self.site_name, about_path=self.about_path
|
||||
proto=protocol, site=self.site_name, about_path=self.about_path,
|
||||
display_name=self.course.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -749,8 +755,10 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org"
|
||||
"Dear student,\n\nYou have been invited to join {} at edx.org by a member of the course staff.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
display_name=self.course.display_name,
|
||||
)
|
||||
)
|
||||
|
||||
@ddt.data('http', 'https')
|
||||
@@ -770,14 +778,15 @@ class TestInstructorAPIEnrollment(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to register for Robot Super Course'
|
||||
'You have been invited to register for {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear student,\n\nYou have been invited to join Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"Dear student,\n\nYou have been invited to join {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"To access the course visit {proto}://{site}{course_path} and login.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to robot-not-an-email-yet@robot.org".format(
|
||||
display_name=self.course.display_name,
|
||||
proto=protocol, site=self.site_name, course_path=self.course_path
|
||||
)
|
||||
)
|
||||
@@ -917,16 +926,17 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to a beta test for Robot Super Course'
|
||||
'You have been invited to a beta test for {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
u"Dear {student_name}\n\nYou have been invited to be a beta tester "
|
||||
"for Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"for {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"Visit {proto}://{site}{about_path} to join "
|
||||
"the course and begin the beta test.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to {student_email}".format(
|
||||
display_name=self.course.display_name,
|
||||
student_name=self.notenrolled_student.profile.name,
|
||||
student_email=self.notenrolled_student.email,
|
||||
proto=protocol,
|
||||
@@ -963,16 +973,17 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been invited to a beta test for Robot Super Course'
|
||||
'You have been invited to a beta test for {}'.format(display_name=self.course.display_name)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
u"Dear {student_name}\n\nYou have been invited to be a beta tester "
|
||||
"for Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
"for {display_name} at edx.org by a member of the course staff.\n\n"
|
||||
"To start accessing course materials, please visit "
|
||||
"{proto}://{site}{course_path}\n\n----\n"
|
||||
"This email was automatically sent from edx.org to {student_email}".format(
|
||||
display_name=self.course.display_name,
|
||||
student_name=self.notenrolled_student.profile.name,
|
||||
student_email=self.notenrolled_student.email,
|
||||
proto=protocol,
|
||||
@@ -990,11 +1001,12 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
u"Dear {0}\n\nYou have been invited to be a beta tester "
|
||||
"for Robot Super Course at edx.org by a member of the course staff.\n\n"
|
||||
u"Dear {}\n\nYou have been invited to be a beta tester "
|
||||
"for {} at edx.org by a member of the course staff.\n\n"
|
||||
"Visit edx.org to enroll in the course and begin the beta test.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to {1}".format(
|
||||
"This email was automatically sent from edx.org to {}".format(
|
||||
self.notenrolled_student.profile.name,
|
||||
self.course.display_name,
|
||||
self.notenrolled_student.email,
|
||||
)
|
||||
)
|
||||
@@ -1077,16 +1089,17 @@ class TestInstructorAPIBulkBetaEnrollment(ModuleStoreTestCase, LoginEnrollmentTe
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been removed from a beta test for Robot Super Course'
|
||||
u'You have been removed from a beta test for {}'.format(display_name=self.course.display_name,)
|
||||
)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].body,
|
||||
"Dear {full_name}\n\nYou have been removed as a beta tester for "
|
||||
"Robot Super Course at edx.org by a member of the course staff. "
|
||||
"{display_name} at edx.org by a member of the course staff. "
|
||||
"The course will remain on your dashboard, but you will no longer "
|
||||
"be part of the beta testing group.\n\n"
|
||||
"Your other courses have not been affected.\n\n----\n"
|
||||
"This email was automatically sent from edx.org to {email_address}".format(
|
||||
display_name=self.course.display_name,
|
||||
full_name=self.beta_tester.profile.name,
|
||||
email_address=self.beta_tester.email
|
||||
)
|
||||
|
||||
@@ -26,6 +26,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
|
||||
|
||||
|
||||
class TestSettableEnrollmentState(TestCase):
|
||||
@@ -431,7 +432,7 @@ class TestSendBetaRoleEmail(TestCase):
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE)
|
||||
class TestGetEmailParams(TestCase):
|
||||
class TestGetEmailParams(ModuleStoreTestCase):
|
||||
"""
|
||||
Test what URLs the function get_email_params returns under different
|
||||
production-like conditions.
|
||||
|
||||
@@ -218,34 +218,36 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
self.assertEqual(len(mail.outbox), 3)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been enrolled in Robot Super Course'
|
||||
'You have been enrolled in {}'.format(course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
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. "
|
||||
"The course should now appear on your edx.org dashboard.\n\n"
|
||||
"To start accessing course materials, please visit "
|
||||
"{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n"
|
||||
"----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(protocol)
|
||||
"{}://edx.org/courses/{}/\n\n"
|
||||
"----\nThis email was automatically sent from edx.org to Autoenrolled Test".format(
|
||||
course.display_name, protocol, unicode(course.id)
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
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(
|
||||
mail.outbox[1].body,
|
||||
"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"
|
||||
"To finish your registration, please visit "
|
||||
"{}://edx.org/register and fill out the registration form "
|
||||
"making sure to use student3_1@test.com in the E-mail field.\n"
|
||||
"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 "
|
||||
"student3_1@test.com".format(protocol)
|
||||
"student3_1@test.com".format(protocol, display_name=course.display_name)
|
||||
)
|
||||
|
||||
def test_unenrollment_email_on(self):
|
||||
@@ -271,19 +273,19 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
self.assertEqual(len(mail.outbox), 3)
|
||||
self.assertEqual(
|
||||
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(
|
||||
mail.outbox[0].body,
|
||||
"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"
|
||||
"----\nThis email was automatically sent from edx.org "
|
||||
"to student4_0@test.com"
|
||||
"to student4_0@test.com".format(course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
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):
|
||||
@@ -322,28 +324,32 @@ class TestInstructorEnrollsStudent(ModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
self.assertEqual(len(mail.outbox), 2)
|
||||
self.assertEqual(
|
||||
mail.outbox[0].subject,
|
||||
'You have been enrolled in Robot Super Course'
|
||||
'You have been enrolled in {}'.format(course.display_name)
|
||||
)
|
||||
self.assertEqual(
|
||||
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. "
|
||||
"The course should now appear on your edx.org dashboard.\n\n"
|
||||
"To start accessing course materials, please visit "
|
||||
"{}://edx.org/courses/MITx/999/Robot_Super_Course/\n\n"
|
||||
"----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(protocol)
|
||||
"{}://edx.org/courses/{}/\n\n"
|
||||
"----\nThis email was automatically sent from edx.org to ShibTest Enrolled".format(
|
||||
course.display_name, protocol, unicode(course.id)
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
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(
|
||||
mail.outbox[1].body,
|
||||
"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"
|
||||
"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 "
|
||||
"student5_1@test.com".format(protocol)
|
||||
"student5_1@test.com".format(
|
||||
course.display_name, protocol, course.id
|
||||
)
|
||||
)
|
||||
|
||||
@@ -103,10 +103,12 @@ class TestCourseSaleRecordsAnalyticsBasic(ModuleStoreTestCase):
|
||||
|
||||
class TestCourseRegistrationCodeAnalyticsBasic(ModuleStoreTestCase):
|
||||
""" Test basic course registration codes analytics functions. """
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Fixtures.
|
||||
"""
|
||||
super(TestCourseRegistrationCodeAnalyticsBasic, self).setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.client.login(username=self.instructor.username, password='test')
|
||||
|
||||
@@ -4,7 +4,7 @@ Tests for the Shopping Cart Models
|
||||
import smtplib
|
||||
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.conf import settings
|
||||
from django.db import DatabaseError
|
||||
@@ -13,7 +13,6 @@ from django.test.utils import override_settings
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
|
||||
from shoppingcart.models import (Order, OrderItem, CertificateItem, InvalidCartItem, PaidCourseRegistration,
|
||||
OrderItemSubclassPK)
|
||||
@@ -23,16 +22,18 @@ from course_modes.models import CourseMode
|
||||
from shoppingcart.exceptions import PurchasedCallbackException
|
||||
import pytz
|
||||
import datetime
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
@override_settings(MODULESTORE=TEST_DATA_MONGO_MODULESTORE)
|
||||
class OrderTest(ModuleStoreTestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory.create()
|
||||
course = CourseFactory.create(org='org', number='test', display_name='Test Course')
|
||||
course = CourseFactory.create()
|
||||
self.course_key = course.id
|
||||
self.other_course_keys = []
|
||||
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
|
||||
|
||||
def test_get_cart_for_user(self):
|
||||
@@ -71,7 +72,7 @@ class OrderTest(ModuleStoreTestCase):
|
||||
def test_cart_clear(self):
|
||||
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, 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.assertTrue(cart.has_items())
|
||||
cart.clear()
|
||||
@@ -93,12 +94,12 @@ class OrderTest(ModuleStoreTestCase):
|
||||
def test_total_cost(self):
|
||||
cart = Order.get_cart_for_user(user=self.user)
|
||||
# add items to the order
|
||||
course_costs = [('org/test/Test_Course_1', 30),
|
||||
('org/test/Test_Course_2', 40),
|
||||
('org/test/Test_Course_3', 10),
|
||||
('org/test/Test_Course_4', 20)]
|
||||
course_costs = [(self.other_course_keys[0], 30),
|
||||
(self.other_course_keys[1], 40),
|
||||
(self.other_course_keys[2], 10),
|
||||
(self.other_course_keys[3], 20)]
|
||||
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.total_cost, sum(cost for _course, cost in course_costs))
|
||||
|
||||
@@ -290,7 +291,7 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory.create()
|
||||
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_mode = CourseMode(course_id=self.course_key,
|
||||
mode_slug="honor",
|
||||
@@ -309,7 +310,9 @@ class PaidCourseRegistrationTest(ModuleStoreTestCase):
|
||||
self.assertEqual(reg1.user, self.user)
|
||||
self.assertEqual(reg1.status, "cart")
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
"""
|
||||
course2 = CourseFactory.create(org='MITx', number='998', display_name='Robot Duper Course')
|
||||
course2 = CourseFactory.create()
|
||||
course_mode2 = CourseMode(course_id=course2.id,
|
||||
mode_slug="honor",
|
||||
mode_display_name="honor cert",
|
||||
@@ -388,7 +391,7 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
def setUp(self):
|
||||
self.user = UserFactory.create()
|
||||
self.cost = 40
|
||||
course = CourseFactory.create(org='org', number='test', display_name='Test Course')
|
||||
course = CourseFactory.create()
|
||||
self.course_key = course.id
|
||||
course_mode = CourseMode(course_id=self.course_key,
|
||||
mode_slug="honor",
|
||||
@@ -444,7 +447,7 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
# If the expiration date has not yet passed on a verified mode, the user can be refunded
|
||||
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_mode = CourseMode(course_id=course_key,
|
||||
mode_slug="verified",
|
||||
@@ -466,7 +469,7 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
|
||||
def test_refund_cert_callback_before_expiration_email(self):
|
||||
""" 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
|
||||
many_days = datetime.timedelta(days=60)
|
||||
|
||||
@@ -496,7 +499,7 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
# If there's an error sending an email to billing, we need to log this error
|
||||
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_mode = CourseMode(course_id=course_key,
|
||||
@@ -519,7 +522,7 @@ class CertificateItemTest(ModuleStoreTestCase):
|
||||
# If the expiration date has passed, the user cannot get a refund
|
||||
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_mode = CourseMode(course_id=course_key,
|
||||
mode_slug="verified",
|
||||
|
||||
@@ -10,7 +10,6 @@ from django.test import TestCase
|
||||
from courseware.tests.tests import TEST_DATA_MONGO_MODULESTORE
|
||||
from django.test.utils import override_settings
|
||||
from django.conf import settings
|
||||
import requests
|
||||
import requests.exceptions
|
||||
|
||||
from student.tests.factories import UserFactory
|
||||
@@ -18,10 +17,11 @@ from verify_student.models import (
|
||||
SoftwareSecurePhotoVerification, VerificationException,
|
||||
)
|
||||
from reverification.tests.factories import MidcourseReverificationWindowFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
|
||||
FAKE_SETTINGS = {
|
||||
"SOFTWARE_SECURE": {
|
||||
"FACE_IMAGE_AES_KEY" : "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"FACE_IMAGE_AES_KEY": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
|
||||
"API_ACCESS_KEY": "BBBBBBBBBBBBBBBBBBBB",
|
||||
"API_SECRET_KEY": "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC",
|
||||
"RSA_PUBLIC_KEY": """-----BEGIN PUBLIC KEY-----
|
||||
@@ -420,10 +420,12 @@ class TestPhotoVerification(TestCase):
|
||||
@patch('verify_student.models.S3Connection', new=MockS3Connection)
|
||||
@patch('verify_student.models.Key', new=MockKey)
|
||||
@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 """
|
||||
|
||||
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()
|
||||
|
||||
def test_user_is_reverified_for_all(self):
|
||||
|
||||
Reference in New Issue
Block a user