class UserMessagesTestCase(TestCase): """ Unit tests for page level user messages. """ def setUp(self): super(UserMessagesTestCase, self).setUp() self.student = UserFactory.create() self.request = RequestFactory().request() self.request.session = {} self.request.user = self.student MessageMiddleware().process_request(self.request) @ddt.data( ('Rock & Roll', '<div class="message-content">Rock & Roll</div>'), (Text('Rock & Roll'), '<div class="message-content">Rock & Roll</div>'), (HTML('<p>Hello, world!</p>'), '<div class="message-content"><p>Hello, world!</p></div>') ) @ddt.unpack def test_message_escaping(self, message, expected_message_html): """ Verifies that a user message is escaped correctly. """ PageLevelMessages.register_user_message(self.request, UserMessageType.INFO, message) messages = list(PageLevelMessages.user_messages(self.request)) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].message_html, expected_message_html) @ddt.data( (UserMessageType.ERROR, 'alert-danger', 'fa fa-warning'), (UserMessageType.INFO, 'alert-info', 'fa fa-bullhorn'), (UserMessageType.SUCCESS, 'alert-success', 'fa fa-check-circle'), (UserMessageType.WARNING, 'alert-warning', 'fa fa-warning'), ) @ddt.unpack def test_message_icon(self, message_type, expected_css_class, expected_icon_class): """ Verifies that a user message returns the correct CSS and icon classes. """ PageLevelMessages.register_user_message(self.request, message_type, TEST_MESSAGE) messages = list(PageLevelMessages.user_messages(self.request)) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].css_class, expected_css_class) self.assertEqual(messages[0].icon_class, expected_icon_class) @ddt.data( (normalize_repr(PageLevelMessages.register_error_message), UserMessageType.ERROR), (normalize_repr(PageLevelMessages.register_info_message), UserMessageType.INFO), (normalize_repr(PageLevelMessages.register_success_message), UserMessageType.SUCCESS), (normalize_repr(PageLevelMessages.register_warning_message), UserMessageType.WARNING), ) @ddt.unpack def test_message_type(self, register_message_function, expected_message_type): """ Verifies that each user message function returns the correct type. """ register_message_function(self.request, TEST_MESSAGE) messages = list(PageLevelMessages.user_messages(self.request)) self.assertEqual(len(messages), 1) self.assertEqual(messages[0].type, expected_message_type)
class UserMessagesTestCase(TestCase): """ Unit tests for page level user messages. """ def setUp(self): super().setUp() self.student = UserFactory.create() self.request = RequestFactory().request() self.request.session = {} self.request.user = self.student MessageMiddleware().process_request(self.request) @ddt.data( ('Rock & Roll', '<div class="message-content">Rock & Roll</div>'), (Text('Rock & Roll'), '<div class="message-content">Rock & Roll</div>'), (HTML('<p>Hello, world!</p>'), '<div class="message-content"><p>Hello, world!</p></div>')) @ddt.unpack def test_message_escaping(self, message, expected_message_html): """ Verifies that a user message is escaped correctly. """ PageLevelMessages.register_user_message(self.request, UserMessageType.INFO, message) messages = list(PageLevelMessages.user_messages(self.request)) assert len(messages) == 1 assert messages[0].message_html == expected_message_html @ddt.data( (UserMessageType.ERROR, 'alert-danger', 'fa fa-warning'), (UserMessageType.INFO, 'alert-info', 'fa fa-bullhorn'), (UserMessageType.SUCCESS, 'alert-success', 'fa fa-check-circle'), (UserMessageType.WARNING, 'alert-warning', 'fa fa-warning'), ) @ddt.unpack def test_message_icon(self, message_type, expected_css_class, expected_icon_class): """ Verifies that a user message returns the correct CSS and icon classes. """ PageLevelMessages.register_user_message(self.request, message_type, TEST_MESSAGE) messages = list(PageLevelMessages.user_messages(self.request)) assert len(messages) == 1 assert messages[0].css_class == expected_css_class assert messages[0].icon_class == expected_icon_class @ddt.data( (normalize_repr( PageLevelMessages.register_error_message), UserMessageType.ERROR), (normalize_repr( PageLevelMessages.register_info_message), UserMessageType.INFO), (normalize_repr(PageLevelMessages.register_success_message), UserMessageType.SUCCESS), (normalize_repr(PageLevelMessages.register_warning_message), UserMessageType.WARNING), ) @ddt.unpack def test_message_type(self, register_message_function, expected_message_type): """ Verifies that each user message function returns the correct type. """ register_message_function(self.request, TEST_MESSAGE) messages = list(PageLevelMessages.user_messages(self.request)) assert len(messages) == 1 assert messages[0].type == expected_message_type def global_message_count(self): """ Count the number of times the global message appears in the user messages. """ expected_html = """<div class="message-content">I <3 HTML-escaping</div>""" messages = list(PageLevelMessages.user_messages(self.request)) return len( list(msg for msg in messages if expected_html in msg.message_html)) def test_global_message_off_by_default(self): """Verifies feature toggle.""" with self.settings(GLOBAL_NOTICE_ENABLED=False, GLOBAL_NOTICE_MESSAGE="I <3 HTML-escaping", GLOBAL_NOTICE_TYPE='WARNING'): # Missing when feature disabled assert self.global_message_count() == 0 def test_global_message_persistent(self): """Verifies global message is always included, when enabled.""" with self.settings(GLOBAL_NOTICE_ENABLED=True, GLOBAL_NOTICE_MESSAGE="I <3 HTML-escaping", GLOBAL_NOTICE_TYPE='WARNING'): # Present with no other setup assert self.global_message_count() == 1 # Present when other messages are present PageLevelMessages.register_user_message(self.request, UserMessageType.INFO, "something else") assert self.global_message_count() == 1 def test_global_message_error_isolation(self): """Verifies that any setting errors don't break the page, or other messages.""" with self.settings( GLOBAL_NOTICE_ENABLED=True, GLOBAL_NOTICE_MESSAGE=ThrowingMarkup(), # force an error GLOBAL_NOTICE_TYPE='invalid'): PageLevelMessages.register_user_message(self.request, UserMessageType.WARNING, "something else") # Doesn't throw, or even interfere with other messages, # when given invalid settings with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') messages = list(PageLevelMessages.user_messages(self.request)) assert len(w) == 1 assert str( w[0].message ) == "Could not register global notice: Exception('Some random error')" assert len(messages) == 1 assert "something else" in messages[0].message_html
class InstructorTaskModuleSubmitTest(InstructorTaskModuleTestCase): """Tests API methods that involve the submission of module-based background tasks.""" def setUp(self): super().setUp() self.initialize_course() self.student = UserFactory.create(username="******", email="*****@*****.**") self.instructor = UserFactory.create(username="******", email="*****@*****.**") def test_submit_nonexistent_modules(self): # confirm that a rescore of a non-existent module returns an exception problem_url = InstructorTaskModuleTestCase.problem_location( "NonexistentProblem") request = None with pytest.raises(ItemNotFoundError): submit_rescore_problem_for_student(request, problem_url, self.student) with pytest.raises(ItemNotFoundError): submit_rescore_problem_for_all_students(request, problem_url) with pytest.raises(ItemNotFoundError): submit_reset_problem_attempts_for_all_students( request, problem_url) with pytest.raises(ItemNotFoundError): submit_delete_problem_state_for_all_students(request, problem_url) def test_submit_nonrescorable_modules(self): # confirm that a rescore of an existent but unscorable module returns an exception # (Note that it is easier to test a scoreable but non-rescorable module in test_tasks, # where we are creating real modules.) problem_url = self.problem_section.location request = None with pytest.raises(NotImplementedError): submit_rescore_problem_for_student(request, problem_url, self.student) with pytest.raises(NotImplementedError): submit_rescore_problem_for_all_students(request, problem_url) @ddt.data( (normalize_repr(submit_rescore_problem_for_all_students), 'rescore_problem'), (normalize_repr(submit_rescore_problem_for_all_students), 'rescore_problem_if_higher', { 'only_if_higher': True }), (normalize_repr(submit_rescore_problem_for_student), 'rescore_problem', { 'student': True }), (normalize_repr(submit_rescore_problem_for_student), 'rescore_problem_if_higher', { 'student': True, 'only_if_higher': True }), (normalize_repr(submit_reset_problem_attempts_for_all_students), 'reset_problem_attempts'), (normalize_repr(submit_delete_problem_state_for_all_students), 'delete_problem_state'), (normalize_repr(submit_rescore_entrance_exam_for_student), 'rescore_problem', { 'student': True }), ( normalize_repr(submit_rescore_entrance_exam_for_student), 'rescore_problem_if_higher', { 'student': True, 'only_if_higher': True }, ), (normalize_repr(submit_reset_problem_attempts_in_entrance_exam), 'reset_problem_attempts', { 'student': True }), (normalize_repr(submit_delete_entrance_exam_state_for_student), 'delete_problem_state', { 'student': True }), (normalize_repr(submit_override_score), 'override_problem_score', { 'student': True, 'score': 0 })) @ddt.unpack def test_submit_task(self, task_function, expected_task_type, params=None): """ Tests submission of instructor task. """ if params is None: params = {} if params.get('student'): params['student'] = self.student problem_url_name = 'H1P1' self.define_option_problem(problem_url_name) location = InstructorTaskModuleTestCase.problem_location( problem_url_name) # unsuccessful submission, exception raised while submitting. with patch( 'lms.djangoapps.instructor_task.tasks_base.BaseInstructorTask.apply_async' ) as apply_async: error = Exception() apply_async.side_effect = error with pytest.raises(QueueConnectionError): instructor_task = task_function( self.create_task_request(self.instructor), location, **params) most_recent_task = InstructorTask.objects.latest('id') assert most_recent_task.task_state == FAILURE # successful submission instructor_task = task_function( self.create_task_request(self.instructor), location, **params) assert instructor_task.task_type == expected_task_type # test resubmitting, by updating the existing record: instructor_task = InstructorTask.objects.get(id=instructor_task.id) instructor_task.task_state = PROGRESS instructor_task.save() with pytest.raises(AlreadyRunningError): task_function(self.create_task_request(self.instructor), location, **params)