def setUp(self): """ Add a user and a course """ super(TestUsersDefaultRole, self).setUp() # create and log in a staff user. self.user = UserFactory(is_staff=True) # pylint: disable=no-member self.client = AjaxEnabledTestClient() self.client.login(username=self.user.username, password='******') # create a course via the view handler to create course self.course_key = SlashSeparatedCourseKey('Org_1', 'Course_1', 'Run_1') self._create_course_with_given_location(self.course_key)
def setUp(self): # Load the toy course self.toy = modulestore().get_course(SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')) # Create two accounts self.student = '*****@*****.**' self.instructor = '*****@*****.**' self.password = '******' self.create_account('u1', self.student, self.password) self.create_account('u2', self.instructor, self.password) self.activate_user(self.student) self.activate_user(self.instructor)
def test_get_courses(self): '''Make sure the course objects loaded properly''' courses = self.store.get_courses() assert_equals(len(courses), 5) course_ids = [course.id for course in courses] for course_key in [ SlashSeparatedCourseKey(*fields) for fields in [['edX', 'simple', '2012_Fall'], ['edX', 'simple_with_draft', '2012_Fall'], ['edX', 'test_import_course', '2012_Fall'], ['edX', 'test_unicode', '2012_Fall'], ['edX', 'toy', '2012_Fall']] ]: assert_in(course_key, course_ids) course = self.store.get_course(course_key) assert_not_none(course) assert_true(self.store.has_course(course_key)) mix_cased = SlashSeparatedCourseKey(course_key.org.upper(), course_key.course.upper(), course_key.run.lower()) assert_false(self.store.has_course(mix_cased)) assert_true(self.store.has_course(mix_cased, ignore_case=True))
def test_creation_auth_off(self): course_id = SlashSeparatedCourseKey('blahx', 'blah101', 'ehhhhhhh') # Test that course is authorized by default, since auth is turned off self.assertTrue( CourseAuthorization.instructor_email_enabled(course_id)) # Use the admin interface to unauthorize the course cauth = CourseAuthorization(course_id=course_id, email_enabled=False) cauth.save() # Now, course should STILL be authorized! self.assertTrue( CourseAuthorization.instructor_email_enabled(course_id))
def setUp(self): # Check a staff account because those used to get the Moderator role self.staff_user = User.objects.create_user( "patty", "*****@*****.**", ) self.staff_user.is_staff = True self.student_user = User.objects.create_user("hacky", "*****@*****.**") self.course_key = SlashSeparatedCourseKey("edX", "Fake101", "2012") CourseEnrollment.enroll(self.staff_user, self.course_key) CourseEnrollment.enroll(self.student_user, self.course_key)
def test_course_without_image(self): """ Make sure we elegantly passover our code when there isn't a static image """ course = self.store.get_course(SlashSeparatedCourseKey('edX', 'simple_with_draft', '2012_Fall')) root_dir = path(mkdtemp()) try: export_to_xml(self.store, self.content_store, course.id, root_dir, 'test_export') assert_false(path(root_dir / 'test_export/static/images/course_image.jpg').isfile()) assert_false(path(root_dir / 'test_export/static/images_course_image.jpg').isfile()) finally: shutil.rmtree(root_dir)
def test_creation(self): course_id = SlashSeparatedCourseKey('abc', '123', 'doremi') sender = UserFactory.create() to_option = SEND_TO_STAFF subject = "dummy subject" html_message = "<html>dummy message</html>" email = CourseEmail.create(course_id, sender, to_option, subject, html_message) self.assertEquals(email.course_id, course_id) self.assertEquals(email.to_option, SEND_TO_STAFF) self.assertEquals(email.subject, subject) self.assertEquals(email.html_message, html_message) self.assertEquals(email.sender, sender)
def setUp(self): self.block = Mock() self.block.scope_ids.usage_id.to_deprecated_string.return_value.encode.return_value = 'dummy' self.course_key = SlashSeparatedCourseKey("org", "course", "run") self.runtime = LmsModuleSystem( static_url='/static', track_function=Mock(), get_module=Mock(), render_template=Mock(), replace_urls=str, course_id=self.course_key, descriptor_runtime=Mock(), )
def setUp(self): self.course_key = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall') # Create instructor account instructor = AdminFactory.create() self.client.login(username=instructor.username, password="******") # URL for instructor dash self.url = reverse( 'instructor_dashboard', kwargs={'course_id': self.course_key.to_deprecated_string()}) # URL for email view self.email_link = '<a href="" data-section="send_email">Email</a>'
def test_bad_git_url(self): """ Test several bad URLs for validation """ course_key = SlashSeparatedCourseKey('org', 'course', 'run') with self.assertRaisesRegexp(GitExportError, str(GitExportError.URL_BAD)): git_export_utils.export_to_git(course_key, 'Sillyness') with self.assertRaisesRegexp(GitExportError, str(GitExportError.URL_BAD)): git_export_utils.export_to_git(course_key, 'example.com:edx/notreal') with self.assertRaisesRegexp(GitExportError, str(GitExportError.URL_NO_AUTH)): git_export_utils.export_to_git(course_key, 'http://blah')
def __init__(self, load_error_modules): xmlstore = XMLModuleStore("data_dir", course_dirs=[], load_error_modules=load_error_modules) super(DummySystem, self).__init__( xmlstore=xmlstore, course_id=SlashSeparatedCourseKey(ORG, COURSE, 'test_run'), course_dir='test_dir', error_tracker=Mock(), parent_tracker=Mock(), load_error_modules=load_error_modules, )
def setUp(self): # Clear out the modulestores, causing them to reload clear_existing_modulestores() self.graded_course = modulestore().get_course(SlashSeparatedCourseKey("edX", "graded", "2012_Fall")) # Create staff account self.staff = StaffFactory(course=self.graded_course.id) self.logout() # self.staff.password is the sha hash but login takes the plain text self.login(self.staff.email, 'test') self.enroll(self.graded_course)
def test_course_listing_performance(self): """ Create large number of courses and give access of some of these courses to the user and compare the time to fetch accessible courses for the user through traversing all courses and reversing django groups """ # create and log in a non-staff user self.user = UserFactory() request = self.factory.get('/course') request.user = self.user self.client.login(username=self.user.username, password='******') # create list of random course numbers which will be accessible to the user user_course_ids = random.sample(range(TOTAL_COURSES_COUNT), USER_COURSES_COUNT) # create courses and assign those to the user which have their number in user_course_ids for number in range(TOTAL_COURSES_COUNT): org = 'Org{0}'.format(number) course = 'Course{0}'.format(number) run = 'Run{0}'.format(number) course_location = SlashSeparatedCourseKey(org, course, run) if number in user_course_ids: self._create_course_with_access_groups(course_location, self.user) else: self._create_course_with_access_groups(course_location) # time the get courses by iterating through all courses with Timer() as iteration_over_courses_time_1: courses_list = _accessible_courses_list(request) self.assertEqual(len(courses_list), USER_COURSES_COUNT) # time again the get courses by iterating through all courses with Timer() as iteration_over_courses_time_2: courses_list = _accessible_courses_list(request) self.assertEqual(len(courses_list), USER_COURSES_COUNT) # time the get courses by reversing django groups with Timer() as iteration_over_groups_time_1: courses_list = _accessible_courses_list_from_groups(request) self.assertEqual(len(courses_list), USER_COURSES_COUNT) # time again the get courses by reversing django groups with Timer() as iteration_over_groups_time_2: courses_list = _accessible_courses_list_from_groups(request) self.assertEqual(len(courses_list), USER_COURSES_COUNT) # test that the time taken by getting courses through reversing django groups is lower then the time # taken by traversing through all courses (if accessible courses are relatively small) self.assertGreaterEqual(iteration_over_courses_time_1.elapsed, iteration_over_groups_time_1.elapsed) self.assertGreaterEqual(iteration_over_courses_time_2.elapsed, iteration_over_groups_time_2.elapsed)
def test_course_listing_errored_deleted_courses(self): """ Create good courses, courses that won't load, and deleted courses which still have roles. Test course listing. """ good_location = SlashSeparatedCourseKey('testOrg', 'testCourse', 'RunBabyRun') self._create_course_with_access_groups(good_location) course_location = SlashSeparatedCourseKey('testOrg', 'doomedCourse', 'RunBabyRun') self._create_course_with_access_groups(course_location) modulestore('direct').delete_course(course_location) course_location = SlashSeparatedCourseKey('testOrg', 'erroredCourse', 'RunBabyRun') course = self._create_course_with_access_groups(course_location) course_db_record = modulestore('direct')._find_one(course.location) course_db_record.setdefault('metadata', {}).get('tabs', []).append({ "type": "wiko", "name": "Wiki" }) modulestore('direct').collection.update( {'_id': course_db_record['_id']}, { '$set': { 'metadata.tabs': course_db_record['metadata']['tabs'], } }, ) courses_list = list(get_course_enrollment_pairs( self.student, None, [])) self.assertEqual(len(courses_list), 1, courses_list) self.assertEqual(courses_list[0][0].id, good_location)
def test__has_access_course_desc_can_enroll(self): user = Mock() yesterday = datetime.datetime.now( pytz.utc) - datetime.timedelta(days=1) tomorrow = datetime.datetime.now(pytz.utc) + datetime.timedelta(days=1) course = Mock(enrollment_start=yesterday, enrollment_end=tomorrow, enrollment_domain='') # User can enroll if it is between the start and end dates self.assertTrue(access._has_access_course_desc(user, 'enroll', course)) # User can enroll if authenticated and specifically allowed for that course # even outside the open enrollment period user = Mock(email='*****@*****.**', is_staff=False) user.is_authenticated.return_value = True course = Mock(enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), enrollment_domain='') CourseEnrollmentAllowedFactory(email=user.email, course_id=course.id) self.assertTrue(access._has_access_course_desc(user, 'enroll', course)) # Staff can always enroll even outside the open enrollment period user = Mock(email='*****@*****.**', is_staff=True) user.is_authenticated.return_value = True course = Mock( enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', 'Whenever'), enrollment_domain='', ) self.assertTrue(access._has_access_course_desc(user, 'enroll', course))
def test_export_course_image_nondefault(self): """ Make sure that if a non-default image path is specified that we don't export it to the static default location """ course = self.store.get_course(SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')) assert_true(course.course_image, 'just_a_test.jpg') root_dir = path(mkdtemp()) try: export_to_xml(self.store, self.content_store, course.id, root_dir, 'test_export') assert_true(path(root_dir / 'test_export/static/just_a_test.jpg').isfile()) assert_false(path(root_dir / 'test_export/static/images/course_image.jpg').isfile()) finally: shutil.rmtree(root_dir)
def test_asset_import_nostatic(self): ''' This test validates that an image asset is NOT imported when do_import_static=False ''' content_store = contentstore() module_store = modulestore('direct') import_from_xml(module_store, 'common/test/data/', ['toy'], static_content_store=content_store, do_import_static=False, verbose=True) course = module_store.get_course(SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')) # make sure we have NO assets in our contentstore all_assets, count = content_store.get_all_content_for_course(course.id) self.assertEqual(len(all_assets), 0) self.assertEqual(count, 0)
def test_fetch_photo_id_image(self): user = UserFactory.create() orig_attempt = SoftwareSecurePhotoVerification(user=user, window=None) orig_attempt.save() old_key = orig_attempt.photo_id_key window = MidcourseReverificationWindowFactory( course_id=SlashSeparatedCourseKey("pony", "rainbow", "dash"), start_date=datetime.now(pytz.utc) - timedelta(days=5), end_date=datetime.now(pytz.utc) + timedelta(days=5)) new_attempt = SoftwareSecurePhotoVerification(user=user, window=window) new_attempt.save() new_attempt.fetch_photo_id_image() assert_equals(new_attempt.photo_id_key, old_key)
def test_graphicslidertool_import(self): ''' Check to see if definition_from_xml in gst_module.py works properly. Pulls data from the graphic_slider_tool directory in the test data directory. ''' modulestore = XMLModuleStore(DATA_DIR, course_dirs=['graphic_slider_tool']) sa_id = SlashSeparatedCourseKey("edX", "gst_test", "2012_Fall") location = sa_id.make_usage_key("graphical_slider_tool", "sample_gst") gst_sample = modulestore.get_item(location) render_string_from_sample_gst_xml = """ <slider var="a" style="width:400px;float:left;"/>\ <plot style="margin-top:15px;margin-bottom:15px;"/>""".strip() self.assertIn(render_string_from_sample_gst_xml, gst_sample.data)
def test_errored_course_regular_access(self): """ Test the course list for regular staff when get_course returns an ErrorDescriptor """ course_key = SlashSeparatedCourseKey('Org1', 'Course1', 'Run1') self._create_course_with_access_groups(course_key) with patch('xmodule.modulestore.mongo.base.MongoKeyValueStore', Mock(side_effect=Exception)): self.assertIsInstance( modulestore('direct').get_course(course_key), ErrorDescriptor) # get courses through iterating all courses courses_list = list( get_course_enrollment_pairs(self.student, None, [])) self.assertEqual(courses_list, [])
def test_enrollment_non_existent_user(self): # Testing enrollment of newly unsaved user (i.e. no database entry) user = User(username="******", email="*****@*****.**") course_id = SlashSeparatedCourseKey("edX", "Test101", "2013") self.assertFalse(CourseEnrollment.is_enrolled(user, course_id)) # Unenroll does nothing CourseEnrollment.unenroll(user, course_id) self.assert_no_events_were_emitted() # Implicit save() happens on new User object when enrolling, so this # should still work CourseEnrollment.enroll(user, course_id) self.assertTrue(CourseEnrollment.is_enrolled(user, course_id)) self.assert_enrollment_event_was_emitted(user, course_id)
def test_get_course_list(self): """ Test getting courses with new access group format e.g. 'instructor_edx.course.run' """ course_location = SlashSeparatedCourseKey('Org1', 'Course1', 'Run1') self._create_course_with_access_groups(course_location, 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)
def test_rewrite_reference(self): module_store = modulestore('direct') target_course_id = SlashSeparatedCourseKey('testX', 'peergrading_copy', 'copy_run') import_from_xml( module_store, 'common/test/data/', ['open_ended'], target_course_id=target_course_id ) peergrading_module = module_store.get_item( target_course_id.make_usage_key('peergrading', 'PeerGradingLinked') ) self.assertIsNotNone(peergrading_module) self.assertEqual( target_course_id.make_usage_key('combinedopenended', 'SampleQuestion'), peergrading_module.link_to_location )
def test_get_courses(self): '''Make sure the course objects loaded properly''' courses = self.store.get_courses() assert_equals(len(courses), 5) course_ids = [course.id for course in courses] for course_key in [ SlashSeparatedCourseKey(*fields) for fields in [ ['edX', 'simple', '2012_Fall'], ['edX', 'simple_with_draft', '2012_Fall'], ['edX', 'test_import_course', '2012_Fall'], ['edX', 'test_unicode', '2012_Fall'], ['edX', 'toy', '2012_Fall'] ] ]: assert_in(course_key, course_ids) course = self.store.get_course(course_key) assert_not_none(course)
def test_unicode_chars_in_xml_content(self): # edX/full/6.002_Spring_2012 has non-ASCII chars, and during # uniquification of names, would raise a UnicodeError. It no longer does. # Ensure that there really is a non-ASCII character in the course. with open(os.path.join(DATA_DIR, "toy/sequential/vertical_sequential.xml")) as xmlf: xml = xmlf.read() with self.assertRaises(UnicodeDecodeError): xml.decode('ascii') # Load the course, but don't make error modules. This will succeed, # but will record the errors. modulestore = XMLModuleStore(DATA_DIR, course_dirs=['toy'], load_error_modules=False) # Look up the errors during load. There should be none. errors = modulestore.get_course_errors(SlashSeparatedCourseKey("edX", "toy", "2012_Fall")) assert errors == []
def get_courses(self): ''' Returns a list of course descriptors. ''' return sum( [ self._load_items( SlashSeparatedCourseKey( course['_id']['org'], course['_id']['course'], course['_id']['name']), [course]) for course # I tried to add '$and': [{'_id.org': {'$ne': 'edx'}}, {'_id.course': {'$ne': 'templates'}}] # but it didn't do the right thing (it filtered all edx and all templates out) in self.collection.find({'_id.category': 'course'}) if not ( # TODO kill this course['_id']['org'] == 'edx' and course['_id']['course'] == 'templates') ], [])
def test_get_course_list(self): """ Test getting courses """ course_location = SlashSeparatedCourseKey('Org1', 'Course1', 'Run1') self._create_course_with_access_groups(course_location) # get dashboard courses_list = list(get_course_enrollment_pairs( self.student, None, [])) self.assertEqual(len(courses_list), 1) self.assertEqual(courses_list[0][0].id, course_location) CourseEnrollment.unenroll(self.student, course_location) # get dashboard courses_list = list(get_course_enrollment_pairs( self.student, None, [])) self.assertEqual(len(courses_list), 0)
def setUp(self): self.password = '******' self.student = User.objects.create_user('student', '*****@*****.**', self.password) self.course_key = SlashSeparatedCourseKey('HarvardX', 'CB22x', 'The_Ancient_Greek_Hero') self.note = { 'user': self.student, 'course_id': self.course_key, 'uri': '/', 'text': 'foo', 'quote': 'bar', 'range_start': 0, 'range_start_offset': 0, 'range_end': 100, 'range_end_offset': 0, 'tags': 'a,b,c' }
def test_unicode_chars_in_course_name_import(self): """ # Test that importing course with unicode 'id' and 'display name' doesn't give UnicodeEncodeError """ module_store = modulestore('direct') course_id = SlashSeparatedCourseKey(u'Юникода', u'unicode_course', u'échantillon') import_from_xml( module_store, 'common/test/data/', ['2014_Uni'], target_course_id=course_id ) course = module_store.get_course(course_id) self.assertIsNotNone(course) # test that course 'display_name' same as imported course 'display_name' self.assertEqual(course.display_name, u"Φυσικά το όνομα Unicode")
def setUp(self): self.student = '*****@*****.**' self.instructor = '*****@*****.**' self.password = '******' self.create_account('u1', self.student, self.password) self.create_account('u2', self.instructor, self.password) self.activate_user(self.student) self.activate_user(self.instructor) self.course_id = SlashSeparatedCourseKey("edX", "toy", "2012_Fall") self.location_string = self.course_id.make_usage_key('html', 'TestLocation').to_deprecated_string() self.toy = modulestore().get_course(self.course_id) make_instructor(self.toy, self.instructor) self.mock_service = staff_grading_service.staff_grading_service() self.logout()