-
Notifications
You must be signed in to change notification settings - Fork 4.2k
fix: updating advance settings should update corresponding course_app #37625
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
base: master
Are you sure you want to change the base?
Conversation
|
Thanks for the pull request, @marslanabdulrauf! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. Where can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
c3a2979 to
9254e20
Compare
456a2db to
67a8d08
Compare
cms/djangoapps/contentstore/rest_api/v0/views/advanced_settings.py
Outdated
Show resolved
Hide resolved
cms/djangoapps/contentstore/rest_api/v0/views/advanced_settings.py
Outdated
Show resolved
Hide resolved
| raise ValidationError({"id": "Invalid app ID"}) | ||
| is_enabled = set_course_app_enabled(course_key=course_key, app_id=app_id, enabled=enabled, user=request.user) | ||
|
|
||
| is_enabled = set_course_app_status(course_key=course_key, app_id=app_id, enabled=enabled, request=request) |
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.
Why all the named arguments? The set_course_app_status function has only positional arguments.
(same for the other call to set_course_app_status above)
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.
Named arguments are always better specifically when we have 3+ arguments and boolean parameter. Its self-documented, future-proof, and improve readability.
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.
We may have to disagree on this, but you should comply with the current practices in the Open edX codebase, which is not to use keyword arguments when they are declared as positional.
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.
Open edX code that I updated was already using named arguments
| except PluginError: | ||
| course_app = None | ||
| if not course_app or not course_app.is_available(course_key): | ||
| raise ValidationError({"id": "Invalid app ID"}) |
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 suggest the following:
try:
course_app = CourseAppsPluginManager.get_plugin(app_id)
except PluginError:
raise ValidationError({"id": f"Invalid app ID={app_id]"})
if not course_app.is_available(course_key):
raise ValidationError({"id": f"Unavailable app ID={app_id}"})
| if not has_studio_write_access(request.user, course_key): | ||
| self.permission_denied(request) | ||
|
|
||
| course_app_settings_map = CourseAppsPluginManager.get_course_app_settings_mapping() |
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.
There are several issues here:
- Why is there a big piece of code right in the middle of this otherwise simple function for a change that would happen very infrequently? At the very least, this piece of code should be in a separate function.
- But then, this separate function should not modify the
requestobject. This is a side effect that is too hard to understand. - Why are we collecting all advanced settings in a single dictionary? This looks like the wrong API to me. Instead, we could write:
apps_to_toggle:: list[tuple[str, bool]] = []
for advanced_setting, setting_enabled in request.data.items():
# note how get_advanced_app_id returns str | None
if app_id := CourseAppsPluginManager.get_advanced_app_id(advanced_setting):
course_app_enabled = setting_enabled.get("value")
if course_app_enabled is not None:
apps_to_toggle.append((app_id, course_app_enabled))
for app_id, is_enabled in apps_to_toggle:
set_course_app_status(course_key, app_id, is_enabled, request.user)
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.
There is no direct way to find course_app/app_id using advanced_setting.
We need to get all plugins check if any of them have set advanced_setting_field and generate a map for it.
This method get_advanced_app_id looks good to return only app_id for given advanced_setting however it will iterate on all plugins for each advanced_setting.
Let me move it to different function(s) and reduce the nesting 👍
e29699e to
73fa154
Compare
73fa154 to
6eeeb88
Compare
|
@marslanabdulrauf has all the existing feedback been addressed? I still see some comments that might need addressing. |
Related Ticket (Internal):
https://github.com/mitodl/hq/issues/9178
Description
This PR adds bidirectional sync for common settings that can be control from both "Pages & Resources" page and advanced settings page.
It updates:
PATCHrequest to update corresponding course_app status if existsSteps to Reproduce
Pages & Resourcessection of a courseNotesandCalculatoreach to be disabled.NotesandCalculator- both will be disabled.Expected Behavior
The two settings should match - changing the state of the setting in Advanced Settings should update the setting on Pages & Resources.
For a working example, see "Flexible peer grading for ORAs" - which links to "Force Flexible Grading for Peer ORAs" in the advanced settings. Changing the setting on Pages & Resources to disabled or enabled will change the setting in Advanced Settings to true or false.
Actual Behavior
Changing the settings for calculator and notes within Advanced Settings does not change the settings on Pages & Resources. The course will update based on what is in the Advanced Settings, meaning that there can be a mismatch between the two settings but the course will always follow the flag in the Advanced Setting.
Updating the flag in Pages & Resources will update the Advanced Settings.
Testing instructions