class AdvancedSettingsValidationTest(StudioCourseTest): """ Tests for validation feature in Studio's advanced settings tab """ course_name_key = 'Course Display Name' course_name_value = 'Test Name' def setUp(self): super(AdvancedSettingsValidationTest, self).setUp() self.advanced_settings = AdvancedSettingsPage( self.browser, self.course_info['org'], self.course_info['number'], self.course_info['run']) self.type_fields = [ 'Course Display Name', 'Advanced Module List', 'Discussion Topic Mapping', 'Maximum Attempts', 'Course Announcement Date' ] # Before every test, make sure to visit the page first self.advanced_settings.visit() def test_course_author_sees_default_advanced_settings(self): """ Scenario: Test that advanced settings have the default settings Given a staff logs in to studio When this user goes to advanced settings page Then this user sees 'Allow Anonymous Discussion Posts' as true And 'Enable Timed Exams' as false And 'Maximum Attempts' as null """ anonymous_discussion_setting = self.advanced_settings.get( 'Allow Anonymous Discussion Posts') timed_exam_settings = self.advanced_settings.get('Enable Timed Exams') max_attempts = self.advanced_settings.get('Maximum Attempts') page_default_settings = [ anonymous_discussion_setting, timed_exam_settings, max_attempts ] default_anonymous_discussion_setting = 'true' default_timed_exam_settings = 'false' default_max_attempts = 'null' expected_default_settings = [ default_anonymous_discussion_setting, default_timed_exam_settings, default_max_attempts ] self.assertEqual(page_default_settings, expected_default_settings) def test_keys_appear_alphabetically(self): """ Scenario: Test that advanced settings have all the keys in alphabetic order Given a staff logs in to studio When this user goes to advanced settings page Then he sees all the advanced setting keys in alphabetic order """ key_names = self.advanced_settings.key_names self.assertEqual(key_names, sorted(key_names)) def test_cancel_editing_key_value(self): """ Scenario: Test that advanced settings does not save the key value, if cancel is clicked from notification bar Given a staff logs in to studio When this user goes to advanced settings page and enters and new course name Then he clicks 'cancel' buttin when asked to save changes When this user reloads the page And then he does not see any change in the original course name """ original_course_display_name = self.advanced_settings.get( self.course_name_key) new_course_name = 'New Course Name' type_in_codemirror(self.advanced_settings, 16, new_course_name) self.advanced_settings.cancel() self.advanced_settings.refresh_and_wait_for_load() self.assertNotEqual(original_course_display_name, new_course_name, ( 'original course name:{} can not not be equal to unsaved course name {}' .format(original_course_display_name, new_course_name))) self.assertEqual(self.advanced_settings.get( self.course_name_key ), original_course_display_name, ( 'course name from the page should be same as original_course_display_name:{}' .format(original_course_display_name))) def test_editing_key_value(self): """ Scenario: Test that advanced settings saves the key value, if save button is clicked from notification bar after the editing Given a staff logs in to studio When this user goes to advanced settings page and enters a new course name And he clicks 'save' button from the notification bar Then he is able to see the updated course name """ new_course_name = ''.join( random.choice(string.ascii_uppercase) for _ in range(10)) self.advanced_settings.set(self.course_name_key, new_course_name) self.assertEqual( self.advanced_settings.get(self.course_name_key), '"{}"'.format(new_course_name), ('course name from the page should be same as new_course_name:{}'. format(new_course_name))) def test_confirmation_is_shown_on_save(self): """ Scenario: Test that advanced settings shows confirmation after editing a field successfully Given a staff logs in to studio When this user goes to advanced settings page and edits any value And he clicks 'save' button from the notification bar Then he is able to see the confirmation message """ self.advanced_settings.set('Maximum Attempts', 5) confirmation_message = self.advanced_settings.confirmation_message self.assertEqual( confirmation_message, 'Your policy changes have been saved.', 'Settings must be saved successfully in order to have confirmation message' ) def test_deprecated_settings_invisible_by_default(self): """ Scenario: Test that advanced settings does not have deprecated settings by default Given a staff logs in to studio When this user goes to advanced settings page Then the user does not see the deprecated settings And sees 'Show Deprecated Settings' button """ button_text = self.advanced_settings.deprecated_settings_button_text self.assertEqual(button_text, 'Show Deprecated Settings') self.assertFalse( self.advanced_settings.check_deprecated_settings_visibility()) def test_modal_shows_one_validation_error(self): """ Test that advanced settings don't save if there's a single wrong input, and that it shows the correct error message in the modal. """ # Feed an integer value for String field. # .set method saves automatically after setting a value course_display_name = self.advanced_settings.get('Course Display Name') self.advanced_settings.set('Course Display Name', 1) self.advanced_settings.wait_for_modal_load() # Test Modal self.check_modal_shows_correct_contents(['Course Display Name']) self.advanced_settings.refresh_and_wait_for_load() self.assertEquals( self.advanced_settings.get('Course Display Name'), course_display_name, 'Wrong input for Course Display Name must not change its value') def test_modal_shows_multiple_validation_errors(self): """ Test that advanced settings don't save with multiple wrong inputs """ # Save original values and feed wrong inputs original_values_map = self.get_settings_fields_of_each_type() self.set_wrong_inputs_to_fields() self.advanced_settings.wait_for_modal_load() # Test Modal self.check_modal_shows_correct_contents(self.type_fields) self.advanced_settings.refresh_and_wait_for_load() for key, val in original_values_map.iteritems(): self.assertEquals( self.advanced_settings.get(key), val, 'Wrong input for Advanced Settings Fields must not change its value' ) def test_undo_changes(self): """ Test that undo changes button in the modal resets all settings changes """ # Save original values and feed wrong inputs original_values_map = self.get_settings_fields_of_each_type() self.set_wrong_inputs_to_fields() # Let modal popup self.advanced_settings.wait_for_modal_load() # Click Undo Changes button self.advanced_settings.undo_changes_via_modal() # Check that changes are undone for key, val in original_values_map.iteritems(): self.assertEquals(self.advanced_settings.get(key), val, 'Undoing Should revert back to original value') def test_manual_change(self): """ Test that manual changes button in the modal keeps settings unchanged """ inputs = { "Course Display Name": 1, "Advanced Module List": 1, "Discussion Topic Mapping": 1, "Maximum Attempts": '"string"', "Course Announcement Date": '"string"', } self.set_wrong_inputs_to_fields() self.advanced_settings.wait_for_modal_load() self.advanced_settings.trigger_manual_changes() # Check that the validation modal went away. self.assertFalse(self.advanced_settings.is_validation_modal_present()) # Iterate through the wrong values and make sure they're still displayed for key, val in inputs.iteritems(): self.assertEquals( str(self.advanced_settings.get(key)), str(val), 'manual change should keep: ' + str(val) + ', but is: ' + str(self.advanced_settings.get(key))) def check_modal_shows_correct_contents(self, wrong_settings_list): """ Helper function that checks if the validation modal contains correct error messages. """ # Check presence of modal self.assertTrue(self.advanced_settings.is_validation_modal_present()) # List of wrong settings item & what is presented in the modal should be the same error_item_names = self.advanced_settings.get_error_item_names() self.assertEqual(set(wrong_settings_list), set(error_item_names)) error_item_messages = self.advanced_settings.get_error_item_messages() self.assertEqual(len(error_item_names), len(error_item_messages)) def get_settings_fields_of_each_type(self): """ Get one of each field type: - String: Course Display Name - List: Advanced Module List - Dict: Discussion Topic Mapping - Integer: Maximum Attempts - Date: Course Announcement Date """ return { "Course Display Name": self.advanced_settings.get('Course Display Name'), "Advanced Module List": self.advanced_settings.get('Advanced Module List'), "Discussion Topic Mapping": self.advanced_settings.get('Discussion Topic Mapping'), "Maximum Attempts": self.advanced_settings.get('Maximum Attempts'), "Course Announcement Date": self.advanced_settings.get('Course Announcement Date'), } def set_wrong_inputs_to_fields(self): """ Set wrong values for the chosen fields """ self.advanced_settings.set_values({ "Course Display Name": 1, "Advanced Module List": 1, "Discussion Topic Mapping": 1, "Maximum Attempts": '"string"', "Course Announcement Date": '"string"', }) def test_only_expected_fields_are_displayed(self): """ Scenario: The Advanced Settings screen displays settings/fields not specifically hidden from view by a developer. Given I have a set of CourseMetadata fields defined for the course When I view the Advanced Settings screen for the course The total number of fields displayed matches the number I expect And the actual fields displayed match the fields I expect to see """ expected_fields = self.advanced_settings.expected_settings_names displayed_fields = self.advanced_settings.displayed_settings_names self.assertEquals(set(displayed_fields), set(expected_fields))