def setUp(self): super(InstructorServiceTests, self).setUp() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), )
def run(): """ Executed during django startup """ django_utils_translation.patch() autostartup() add_mimetypes() if settings.FEATURES.get('USE_CUSTOM_THEME', False): enable_theme() if settings.FEATURES.get('USE_MICROSITES', False): enable_microsites() if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False): enable_third_party_auth() # Initialize Segment.io analytics module. Flushes first time a message is received and # every 50 messages thereafter, or if 10 seconds have passed since last flush if settings.FEATURES.get('SEGMENT_IO_LMS') and hasattr( settings, 'SEGMENT_IO_LMS_KEY'): analytics.init(settings.SEGMENT_IO_LMS_KEY, flush_at=50) # register any dependency injections that we need to support in edx_proctoring # right now edx_proctoring is dependent on the openedx.core.djangoapps.credit # as well as the instructor dashboard (for deleting student attempts) if settings.FEATURES.get('ENABLE_PROCTORED_EXAMS'): set_runtime_service('credit', CreditService()) set_runtime_service('instructor', InstructorService())
def run(): """ Executed during django startup """ django_utils_translation.patch() autostartup() add_mimetypes() if settings.FEATURES.get('USE_CUSTOM_THEME', False): enable_stanford_theme() if settings.FEATURES.get('USE_MICROSITES', False): enable_microsites() if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False): enable_third_party_auth() # Initialize Segment analytics module by setting the write_key. if settings.LMS_SEGMENT_KEY: analytics.write_key = settings.LMS_SEGMENT_KEY # register any dependency injections that we need to support in edx_proctoring # right now edx_proctoring is dependent on the openedx.core.djangoapps.credit # as well as the instructor dashboard (for deleting student attempts) if settings.FEATURES.get('ENABLE_PROCTORED_EXAMS'): # Import these here to avoid circular dependencies of the form: # edx-platform app --> DRF --> django translation --> edx-platform app from edx_proctoring.runtime import set_runtime_service from instructor.services import InstructorService from openedx.core.djangoapps.credit.services import CreditService set_runtime_service('credit', CreditService()) set_runtime_service('instructor', InstructorService())
def run(): """ Executed during django startup """ third_party_auth.patch() django_db_models_options.patch() # To override the settings before executing the autostartup() for python-social-auth if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False): enable_third_party_auth() # Comprehensive theming needs to be set up before django startup, # because modifying django template paths after startup has no effect. if is_comprehensive_theming_enabled(): enable_theming() # We currently use 2 template rendering engines, mako and django_templates, # and one of them (django templates), requires the directories be added # before the django.setup(). microsite.enable_microsites_pre_startup(log) django.setup() autostartup() add_mimetypes() # Mako requires the directories to be added after the django setup. microsite.enable_microsites(log) # Initialize Segment analytics module by setting the write_key. if settings.LMS_SEGMENT_KEY: analytics.write_key = settings.LMS_SEGMENT_KEY # register any dependency injections that we need to support in edx_proctoring # right now edx_proctoring is dependent on the openedx.core.djangoapps.credit if settings.FEATURES.get('ENABLE_SPECIAL_EXAMS'): # Import these here to avoid circular dependencies of the form: # edx-platform app --> DRF --> django translation --> edx-platform app from edx_proctoring.runtime import set_runtime_service from instructor.services import InstructorService from openedx.core.djangoapps.credit.services import CreditService set_runtime_service('credit', CreditService()) # register InstructorService (for deleting student attempts and user staff access roles) set_runtime_service('instructor', InstructorService()) # In order to allow modules to use a handler url, we need to # monkey-patch the x_module library. # TODO: Remove this code when Runtimes are no longer created by modulestores # https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes xmodule.x_module.descriptor_global_handler_url = lms_xblock.runtime.handler_url xmodule.x_module.descriptor_global_local_resource_url = lms_xblock.runtime.local_resource_url # validate configurations on startup validate_lms_config(settings)
def setUp(self): super(InstructorServiceTests, self).setUp() self.course = CourseFactory.create() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.problem_location = msk_from_problem_urlname( self.course.id, 'robot-some-problem-urlname') self.other_problem_location = msk_from_problem_urlname( self.course.id, 'robot-some-other_problem-urlname') self.problem_urlname = unicode(self.problem_location) self.other_problem_urlname = unicode(self.other_problem_location) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), )
def run(): """ Executed during django startup """ third_party_auth.patch() # To override the settings before executing the autostartup() for python-social-auth if settings.FEATURES.get('ENABLE_THIRD_PARTY_AUTH', False): enable_third_party_auth() if settings.FEATURES.get('USE_MICROSITES', False): enable_microsites_pre_startup() django.setup() autostartup() add_mimetypes() if settings.FEATURES.get('USE_CUSTOM_THEME', False): enable_stanford_theme() if settings.FEATURES.get('USE_MICROSITES', False): enable_microsites() # Initialize Segment analytics module by setting the write_key. if settings.LMS_SEGMENT_KEY: analytics.write_key = settings.LMS_SEGMENT_KEY # register any dependency injections that we need to support in edx_proctoring # right now edx_proctoring is dependent on the openedx.core.djangoapps.credit if settings.FEATURES.get('ENABLE_SPECIAL_EXAMS'): # Import these here to avoid circular dependencies of the form: # edx-platform app --> DRF --> django translation --> edx-platform app from edx_proctoring.runtime import set_runtime_service from instructor.services import InstructorService from openedx.core.djangoapps.credit.services import CreditService set_runtime_service('credit', CreditService()) # register InstructorService (for deleting student attempts and user staff access roles) set_runtime_service('instructor', InstructorService()) # In order to allow modules to use a handler url, we need to # monkey-patch the x_module library. # TODO: Remove this code when Runtimes are no longer created by modulestores # https://openedx.atlassian.net/wiki/display/PLAT/Convert+from+Storage-centric+runtimes+to+Application-centric+runtimes xmodule.x_module.descriptor_global_handler_url = lms_xblock.runtime.handler_url xmodule.x_module.descriptor_global_local_resource_url = lms_xblock.runtime.local_resource_url
def setUp(self): super(InstructorServiceTests, self).setUp() self.course = CourseFactory.create() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.problem_location = msk_from_problem_urlname(self.course.id, "robot-some-problem-urlname") self.other_problem_location = msk_from_problem_urlname(self.course.id, "robot-some-other_problem-urlname") self.problem_urlname = unicode(self.problem_location) self.other_problem_urlname = unicode(self.other_problem_location) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({"attempts": 2}), )
class InstructorServiceTests(SharedModuleStoreTestCase): """ Tests for the InstructorService """ @classmethod def setUpClass(cls): super(InstructorServiceTests, cls).setUpClass() cls.course = CourseFactory.create() cls.problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-problem-urlname') cls.other_problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-other_problem-urlname') cls.problem_urlname = unicode(cls.problem_location) cls.other_problem_urlname = unicode(cls.other_problem_location) def setUp(self): super(InstructorServiceTests, self).setUp() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), ) @mock.patch('courseware.module_render.SCORE_CHANGED.send') def test_reset_student_attempts_delete(self, _mock_signal): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1) self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.problem_urlname, requesting_user=self.student, ) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( 'bad_student', unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname, requesting_user=self.student, ) self.assertIsNone(result) def test_is_user_staff(self): """ Test to assert that the user is staff or not """ result = self.service.is_course_staff(self.student, unicode(self.course.id)) self.assertFalse(result) # allow staff access to the student allow_access(self.course, self.student, 'staff') result = self.service.is_course_staff(self.student, unicode(self.course.id)) self.assertTrue(result) def test_report_suspicious_attempt(self): """ Test to verify that the create_zendesk_ticket() is called """ requester_name = "edx-proctoring" email = "*****@*****.**" subject = "Proctored Exam Review: {review_status}".format( review_status="Suspicious") body = "A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} was " \ "reviewed as {review_status} by the proctored exam review provider." body = body.format(exam_name="test_exam", course_name=self.course.display_name, student_username="******", review_status="Suspicious") tags = ["proctoring"] with mock.patch("instructor.services.create_zendesk_ticket" ) as mock_create_zendesk_ticket: self.service.send_support_notification( course_id=unicode(self.course.id), exam_name="test_exam", student_username="******", review_status="Suspicious") mock_create_zendesk_ticket.assert_called_with(requester_name, email, subject, body, tags)
class InstructorServiceTests(SharedModuleStoreTestCase): """ Tests for the InstructorService """ @classmethod def setUpClass(cls): super(InstructorServiceTests, cls).setUpClass() cls.course = CourseFactory.create() cls.problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-problem-urlname' ) cls.other_problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-other_problem-urlname' ) cls.problem_urlname = unicode(cls.problem_location) cls.other_problem_urlname = unicode(cls.other_problem_location) def setUp(self): super(InstructorServiceTests, self).setUp() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), ) def test_reset_student_attempts_delete(self): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1 ) self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.problem_urlname, requesting_user=self.student, ) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0 ) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( 'bad_student', unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname, requesting_user=self.student, ) self.assertIsNone(result) def test_is_user_staff(self): """ Test to assert that the user is staff or not """ result = self.service.is_course_staff( self.student, unicode(self.course.id) ) self.assertFalse(result) # allow staff access to the student allow_access(self.course, self.student, 'staff') result = self.service.is_course_staff( self.student, unicode(self.course.id) ) self.assertTrue(result) def test_report_suspicious_attempt(self): """ Test to verify that the create_zendesk_ticket() is called """ requester_name = "edx-proctoring" email = "*****@*****.**" subject = "Proctored Exam Review: {review_status}".format(review_status="Suspicious") body = "A proctored exam attempt for {exam_name} in {course_name} by username: {student_username} was " \ "reviewed as {review_status} by the proctored exam review provider." body = body.format( exam_name="test_exam", course_name=self.course.display_name, student_username="******", review_status="Suspicious" ) tags = ["proctoring"] with mock.patch("instructor.services.create_zendesk_ticket") as mock_create_zendesk_ticket: self.service.send_support_notification( course_id=unicode(self.course.id), exam_name="test_exam", student_username="******", review_status="Suspicious" ) mock_create_zendesk_ticket.assert_called_with(requester_name, email, subject, body, tags)
class InstructorServiceTests(SharedModuleStoreTestCase): """ Tests for the InstructorService """ @classmethod def setUpClass(cls): super(InstructorServiceTests, cls).setUpClass() cls.course = CourseFactory.create() cls.problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-problem-urlname') cls.other_problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-other_problem-urlname') cls.problem_urlname = unicode(cls.problem_location) cls.other_problem_urlname = unicode(cls.other_problem_location) def setUp(self): super(InstructorServiceTests, self).setUp() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), ) def test_reset_student_attempts_delete(self): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1) self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.problem_urlname, requesting_user=self.student, ) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( 'bad_student', unicode(self.course.id), 'foo/bar/baz', requesting_user=self.student, ) self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname, requesting_user=self.student, ) self.assertIsNone(result) def test_is_user_staff(self): """ Test to assert that the usrr is staff or not """ result = self.service.is_course_staff(self.student, unicode(self.course.id)) self.assertFalse(result) # allow staff access to the student allow_access(self.course, self.student, 'staff') result = self.service.is_course_staff(self.student, unicode(self.course.id)) self.assertTrue(result)
class InstructorServiceTests(ModuleStoreTestCase): """ Tests for the InstructorService """ def setUp(self): super(InstructorServiceTests, self).setUp() self.course = CourseFactory.create() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.problem_location = msk_from_problem_urlname(self.course.id, "robot-some-problem-urlname") self.other_problem_location = msk_from_problem_urlname(self.course.id, "robot-some-other_problem-urlname") self.problem_urlname = unicode(self.problem_location) self.other_problem_urlname = unicode(self.other_problem_location) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({"attempts": 2}), ) def test_reset_student_attempts_delete(self): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1, ) self.service.delete_student_attempt(self.student.username, unicode(self.course.id), self.problem_urlname) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0, ) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt(self.student.username, unicode(self.course.id), "foo/bar/baz") self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt("bad_student", unicode(self.course.id), "foo/bar/baz") self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname ) self.assertIsNone(result)
class InstructorServiceTests(SharedModuleStoreTestCase): """ Tests for the InstructorService """ @classmethod def setUpClass(cls): super(InstructorServiceTests, cls).setUpClass() cls.course = CourseFactory.create() cls.problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-problem-urlname' ) cls.other_problem_location = msk_from_problem_urlname( cls.course.id, 'robot-some-other_problem-urlname' ) cls.problem_urlname = unicode(cls.problem_location) cls.other_problem_urlname = unicode(cls.other_problem_location) def setUp(self): super(InstructorServiceTests, self).setUp() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), ) def test_reset_student_attempts_delete(self): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1 ) self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.problem_urlname ) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0 ) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), 'foo/bar/baz' ) self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( 'bad_student', unicode(self.course.id), 'foo/bar/baz' ) self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname ) self.assertIsNone(result) def test_is_user_staff(self): """ Test to assert that the usrr is staff or not """ result = self.service.is_course_staff( self.student, unicode(self.course.id) ) self.assertFalse(result) # allow staff access to the student allow_access(self.course, self.student, 'staff') result = self.service.is_course_staff( self.student, unicode(self.course.id) ) self.assertTrue(result)
class InstructorServiceTests(ModuleStoreTestCase): """ Tests for the InstructorService """ def setUp(self): super(InstructorServiceTests, self).setUp() self.course = CourseFactory.create() self.student = UserFactory() CourseEnrollment.enroll(self.student, self.course.id) self.problem_location = msk_from_problem_urlname( self.course.id, 'robot-some-problem-urlname') self.other_problem_location = msk_from_problem_urlname( self.course.id, 'robot-some-other_problem-urlname') self.problem_urlname = unicode(self.problem_location) self.other_problem_urlname = unicode(self.other_problem_location) self.service = InstructorService() self.module_to_reset = StudentModule.objects.create( student=self.student, course_id=self.course.id, module_state_key=self.problem_location, state=json.dumps({'attempts': 2}), ) def test_reset_student_attempts_delete(self): """ Test delete student state. """ # make sure the attempt is there self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 1) self.service.delete_student_attempt(self.student.username, unicode(self.course.id), self.problem_urlname) # make sure the module has been deleted self.assertEqual( StudentModule.objects.filter( student=self.module_to_reset.student, course_id=self.course.id, module_state_key=self.module_to_reset.module_state_key, ).count(), 0) def test_reset_bad_content_id(self): """ Negative test of trying to reset attempts with bad content_id """ result = self.service.delete_student_attempt(self.student.username, unicode(self.course.id), 'foo/bar/baz') self.assertIsNone(result) def test_reset_bad_user(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt('bad_student', unicode(self.course.id), 'foo/bar/baz') self.assertIsNone(result) def test_reset_non_existing_attempt(self): """ Negative test of trying to reset attempts with bad user identifier """ result = self.service.delete_student_attempt( self.student.username, unicode(self.course.id), self.other_problem_urlname) self.assertIsNone(result)