-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Sjang92/advanced settings feedback #4454
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -458,6 +458,69 @@ def test_fetch_initial_fields(self): | |
| self.assertIn('showanswer', test_model, 'showanswer field ') | ||
| self.assertIn('xqa_key', test_model, 'xqa_key field ') | ||
|
|
||
| def test_validate_and_update_from_json_correct_inputs(self): | ||
| is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json( | ||
| self.course, | ||
| { | ||
| "advertised_start": {"value": "start A"}, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test adding "notes" to advanced_modules to make sure tabs property gets updated.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is being done in test_advanced_settings_munge_tabs There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you figure out how to verify that "notes" still works? I recall you were having trouble getting that to work.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It turned out to be my devstack problem. I tested running both release and master, and saw the same behavior. |
||
| "days_early_for_beta": {"value": 2}, | ||
| "advanced_modules": {"value": ['combinedopenended']}, | ||
| }, | ||
| user=self.user | ||
| ) | ||
| self.assertTrue(is_valid) | ||
| self.assertTrue(len(errors) == 0) | ||
| self.update_check(test_model) | ||
|
|
||
| # fresh fetch to ensure persistence | ||
| fresh = modulestore().get_course(self.course.id) | ||
| test_model = CourseMetadata.fetch(fresh) | ||
| self.update_check(test_model) | ||
|
|
||
| # Tab gets tested in test_advanced_settings_munge_tabs | ||
| self.assertIn('advanced_modules', test_model, 'Missing advanced_modules') | ||
| self.assertEqual(test_model['advanced_modules']['value'], ['combinedopenended'], 'advanced_module is not updated') | ||
|
|
||
| def test_validate_and_update_from_json_wrong_inputs(self): | ||
| # input incorrectly formatted data | ||
| is_valid, errors, test_model = CourseMetadata.validate_and_update_from_json( | ||
| self.course, | ||
| { | ||
| "advertised_start": {"value": 1, "display_name": "Course Advertised Start Date", }, | ||
| "days_early_for_beta": {"value": "supposed to be an integer", | ||
| "display_name": "Days Early for Beta Users", }, | ||
| "advanced_modules": {"value": 1, "display_name": "Advanced Module List", }, | ||
| }, | ||
| user=self.user | ||
| ) | ||
|
|
||
| # Check valid results from validate_and_update_from_json | ||
| self.assertFalse(is_valid) | ||
| self.assertEqual(len(errors), 3) | ||
| self.assertFalse(test_model) | ||
|
|
||
| error_keys = set([error_obj['model']['display_name'] for error_obj in errors]) | ||
| test_keys = set(['Advanced Module List', 'Course Advertised Start Date', 'Days Early for Beta Users']) | ||
| self.assertEqual(error_keys, test_keys) | ||
|
|
||
| # try fresh fetch to ensure no update happened | ||
| fresh = modulestore().get_course(self.course.id) | ||
| test_model = CourseMetadata.fetch(fresh) | ||
|
|
||
| self.assertNotEqual(test_model['advertised_start']['value'], 1, 'advertised_start should not be updated to a wrong value') | ||
| self.assertNotEqual(test_model['days_early_for_beta']['value'], "supposed to be an integer", | ||
| 'days_early_for beta should not be updated to a wrong value') | ||
|
|
||
| def test_correct_http_status(self): | ||
| json_data = json.dumps({ | ||
| "advertised_start": {"value": 1, "display_name": "Course Advertised Start Date", }, | ||
| "days_early_for_beta": {"value": "supposed to be an integer", | ||
| "display_name": "Days Early for Beta Users", }, | ||
| "advanced_modules": {"value": 1, "display_name": "Advanced Module List", }, | ||
| }) | ||
| response = self.client.ajax_post(self.course_setting_url, json_data) | ||
| self.assertEqual(400, response.status_code) | ||
|
|
||
| def test_update_from_json(self): | ||
| test_model = CourseMetadata.update_from_json( | ||
| self.course, | ||
|
|
@@ -487,6 +550,9 @@ def test_update_from_json(self): | |
| self.assertEqual(test_model['advertised_start']['value'], 'start B', "advertised_start not expected value") | ||
|
|
||
| def update_check(self, test_model): | ||
| """ | ||
| 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.assertIn('advertised_start', test_model, 'Missing new advertised_start metadata field') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| define(['jquery', 'underscore', 'js/spec_helpers/validation_helpers', 'js/views/modals/validation_error_modal'], | ||
| function ($, _, validation_helpers, ValidationErrorModal) { | ||
|
|
||
| describe('ValidationErrorModal', function() { | ||
| var modal, showModal; | ||
|
|
||
| showModal = function (jsonContent, callback) { | ||
| modal = new ValidationErrorModal(); | ||
| modal.setResetCallback(callback); | ||
| modal.setContent(jsonContent); | ||
| modal.show(); | ||
| }; | ||
|
|
||
| /* Before each, install templates required for the base modal | ||
| and validation error modal. */ | ||
| beforeEach(function () { | ||
| validation_helpers.installValidationTemplates(); | ||
| }); | ||
|
|
||
| afterEach(function() { | ||
| validation_helpers.hideModalIfShowing(modal); | ||
| }); | ||
|
|
||
| it('is visible after show is called', function () { | ||
| showModal([]); | ||
| expect(validation_helpers.isShowingModal(modal)).toBeTruthy(); | ||
| }); | ||
|
|
||
| it('displays none if no error given', function () { | ||
| var errorObjects = []; | ||
|
|
||
| showModal(errorObjects); | ||
| expect(validation_helpers.isShowingModal(modal)).toBeTruthy(); | ||
| validation_helpers.checkErrorContents(modal, errorObjects); | ||
| }); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should test clicking the "reset" button and verifying that resetCallback is called (and the modal hidden).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
|
|
||
| it('correctly displays json error message objects', function () { | ||
| var errorObjects = [ | ||
| { | ||
| model: {display_name: 'test_attribute1'}, | ||
| message: 'Encountered an error while saving test_attribute1' | ||
| }, | ||
| { | ||
| model: {display_name: 'test_attribute2'}, | ||
| message: 'Encountered an error while saving test_attribute2' | ||
| } | ||
| ]; | ||
|
|
||
| showModal(errorObjects); | ||
| expect(validation_helpers.isShowingModal(modal)).toBeTruthy(); | ||
| validation_helpers.checkErrorContents(modal, errorObjects); | ||
| }); | ||
|
|
||
| it('run callback when undo changes button is clicked', function () { | ||
| var errorObjects = [ | ||
| { | ||
| model: {display_name: 'test_attribute1'}, | ||
| message: 'Encountered an error while saving test_attribute1' | ||
| }, | ||
| { | ||
| model: {display_name: 'test_attribute2'}, | ||
| message: 'Encountered an error while saving test_attribute2' | ||
| } | ||
| ]; | ||
|
|
||
| var callback = function() { | ||
| return true; | ||
| }; | ||
|
|
||
| // Show Modal and click undo changes | ||
| showModal(errorObjects, callback); | ||
| expect(validation_helpers.isShowingModal(modal)).toBeTruthy(); | ||
| validation_helpers.undoChanges(modal); | ||
|
|
||
| // Wait for the callback to be fired | ||
| waitsFor(function () { | ||
| return callback(); | ||
| }, 'the callback to be called', 5000); | ||
|
|
||
| // After checking callback fire, check modal hide | ||
| runs(function () { | ||
| expect(validation_helpers.isShowingModal(modal)).toBe(false); | ||
| }); | ||
| }); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /** | ||
| * Provides helper methods for invoking Validation modal in Jasmine tests. | ||
| */ | ||
| define(['jquery', 'js/spec_helpers/modal_helpers', 'js/spec_helpers/view_helpers'], | ||
| function($, modal_helpers, view_helpers) { | ||
| var installValidationTemplates, checkErrorContents, undoChanges; | ||
|
|
||
| installValidationTemplates = function () { | ||
| modal_helpers.installModalTemplates(); | ||
| view_helpers.installTemplate('validation-error-modal'); | ||
| }; | ||
|
|
||
| checkErrorContents = function(validationModal, errorObjects) { | ||
| var errorItems = validationModal.$('.error-item-message'); | ||
| var i, item; | ||
| var num_items = errorItems.length; | ||
| expect(num_items).toBe(errorObjects.length); | ||
|
|
||
| for (i = 0; i < num_items; i++) { | ||
| item = errorItems[i]; | ||
| expect(item.value).toBe(errorObjects[i].message); | ||
| } | ||
| }; | ||
|
|
||
| undoChanges = function(validationModal) { | ||
| modal_helpers.pressModalButton('.action-undo', validationModal); | ||
| }; | ||
|
|
||
| return $.extend(modal_helpers, { | ||
| 'installValidationTemplates': installValidationTemplates, | ||
| 'checkErrorContents': checkErrorContents, | ||
| 'undoChanges': undoChanges, | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand this error message (.*).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The old way of handling error messages prints out something different. Since right now we print out validation error message directly from XBlock fields, I wanted to match the regexp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not following-- does ".*" somehow get replaced with something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.* accepts any string in its place via regexp match. So it can take in errors not only for display name key, but other keys as well
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sjang92 , Alison from the doc team here. Great start, thank you for including the action for the user to take as well as describing the error.
I'd like this message to be a little more informative and a little friendlier. Specifically, I'd like to identify that the errors are the result of a value with the wrong type being supplied, and make it scan better by avoiding values in angle brackets and capitalized letters mid-sentence.
Here's what I'm thinking:
"This setting stores .* type values. A .* type value was found. Replace it with .* . "
so for your first example it would look like this:
"This setting stores string type values. A float type value was found. Replace it with "None" or a string."
(Is it possible for .* to return something other than " < type 'float' > " for the expected value type? and can "String" be lowercase each time it appears mid-sentence?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file above is actually a fix for an existing test due to a problem caused by this new functionality. Actually, the error messages that are being printed out are pulled directly from the xblock repo (field validation for xblocks). I could wrap those default error messages just like the way you suggested. Do you want me to do that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lamagnifica ^^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, @sjang92, there must have been a misunderstanding at this end. I don't think the wrapping is significant, so I withdraw my suggestions.