If a course is deleted or unpublished, the CourseEnrollment list serializer was causing a AttributeErrors when called for a learner who had been enrolled in the formerly-existing course.
Why no test? Because cache invalidation is the worst problem. tl;dr I could create a mock response for the `course_overview` property, but if I mocked up a response to the queryset filter in `CourseEnrollmentsApiListView`, I was effectively guessing that my code worked correctly and then creating a mock response that was an assertion of correctness. That would make any mocked test deceptive; it would appear to test behavior but it would actually just test that I had constructed a mock that passed the test.
I wanted to make an actual test for what would happen if a Course was deleted, so I made one character code fix, and then spent two days unsuccessfully attempting to completely clear out the ModuleStore so I could actually test what would happen in this instance.
IMO an actual verification by hand (which I performed, and it works) was the better part of valor.
in short, cache invalidation aaaaaaaaargh.
FIXES: APER-3913
* fix: Redirect non-enterprise SAML to authn MFE
The original request was that enterprise users with tpa hint and SAML should not be redirected to MFE. The current condition also excludes regular non-enterprise users with SAML authentication from the MFE.
* test: Add test for enterprise SAML authentication MFE redirection logic
This test validates the conditional redirection to the authentication
microfrontend (MFE) for enterprise and SAML authentication scenarios.
The test covers different combinations of:
- Enterprise customer presence
- Third-party authentication provider
- SAML provider status
- Redirection setting
Ensures that enterprise customers with SAML providers are not redirected
to the authentication MFE, while other scenarios follow the standard
redirection rules.
* fix: change spaced between line codes in test_logistration.py
---------
Co-authored-by: Andrés González <andres@aulasneo.com>
- Introduced `remove_special_characters_from_name` and `generate_username_suggestions` functions to enhance username handling.
- Added comprehensive test cases for username generation, including ASCII validation and uniqueness checks.
- Implemented tests for special character removal and suggestion generation based on various input scenarios, including edge cases.
- Updated `generate_username_suggestions` function to include validation for non-ASCII characters.
- Improved function documentation to clarify arguments, return types, and username generation logic.
- Added type hints for better code clarity and maintainability.
The get_service_user method used to do a local call to the
get_user_model function because it was not guaranteed to be properly
initialized at the time of import. This was partly due to how we did
custom initialization using lms/startup.py, but it was also because
when it was implemented (commit f318661), the platform was still
running on Django 1.8.18. At that time, get_user_model was guaranteed to
work only after Django has imported all models.
In Django 1.11, the behavior of get_user_model was changed:
https://docs.djangoproject.com/en/1.11/releases/1.11/#django-contrib-auth
> get_user_model() can now be called at import time,
> even in modules that define models.
Now that lms/startup.py is gone and get_user_model is safe to call at
the module level, I'm refactoring the catalog app's models.py file to
follow the convention we use everywhere else in edx-platform with
respect to get_user_model.
The cms/startup.py and lms/startup.py files were created to
allow us to do a lot of custom initialization around things
like the ModuleStore, monkey-patching, adding MIME types to
our process, etc. As far back as 2017, we recognized that
this was a bad thing, marked these modules as "deprecated",
and started removing things or putting them in the standard
Django locations for them (0279181).
In its current state, these startup modules no longer do any
custom work, and just invoke django.startup(). But this is
meant for running Django code in "standalone" usage, e.g. if
you have a script that isn't a management command but needs
some Django functionality.
The "runserver" command used during development normally
launches a child process to serve requests and knows how to
kill and respawn that process when files are modified, so
that changes are reflected. It can also normally handle the
case where there's a SyntaxError in the child process, and
fixing that error will reload the code again.
Something about running django.startup() manually interferes
with this functionality in "runserver". It still reloads the
code in response to changes, but if the code gets into a
broken state for any reason (like a syntax error), the master
process itself dies. That causes the container to restart,
only to die again shortly afterwards in a loop until the
error is fixed. The container restarts will break any shell
you had opened into the container, as well as any IDE
integrations that connected to that container to access the
files and Python instance.
Getting rid of the custom startup code fixes this and moves
us one small step closer to being a more normal Django
project.
* Add error handler on save video to avoid creating sjson
* Support transcripts without edx_video_id in definition_to_xml
* When copying a video from a library to a course: Create a new edx_video_id
* Save transcripts as static assets in a video in a library when adding a new transcript.
* Delete transcripts as static assets in a video in a library when deleting transcripts.
* Support download transcript in a video in a library.
* Support replace transcript in a video in a library.
* Support updating transcripts in video in a library.
* Refactor the code of downloading YouTube transcripts to enable this feature in libraries.
* Support copy from a library to a course and a course to a library.
When deleting an upstream library block, ensure that any tags that may have been copied to downstream blocks are made editable again. This is achieved by un-setting the `is_copied` flag on the downstream tags.
now that the legacy profile and account pages have been removed, we need to make sure that all of the links point to the MFE URLs; we were relying on the legacy applications to do redirection before.
FIXES: APER-3884
FIXES: openedx/public-engineering#71
Adds the publish status field to the libraries v2 meilisearch index in order to support filtering by component publish status: published, modified, never.
The Python API for declaring derived settings was confusing to the uninitiated
reader, and also prone to spelling mistakes. This replaces the API with one
that is more readable and more concise, and updates the implementation of
`derive_settings` to properly derive settings declared using the new API.
BREAKING CHANGE: The `derived` and `derived_collection_entry` function are
replaced with the `Derived` class. We do not expect those functions to have
been used outside of edx-platform, but if they are, this commit will cause them
to loudly ImportError.
Note that there should be NO change in behavior to the `derive_settings`
function, which we DO know to be used by some external edx-platform plugins.
Part of: https://github.com/openedx/edx-platform/issues/36215
Fixes the styles for the advanced editors (poll, survey, LTI Provider, etc). Updated the code if `xblock_v2/xblock_iframe.html` to use `course-unit-mfe-iframe-bundle.scss`
The `dump_settings` command currently prints out the raw `repr(...)`s for
defined functions, e.g.:
"WIKI_CAN_ASSIGN": "<function CAN_ASSIGN at 0x74ce5e9b2020>",
In addition to being uninformative, these `at 0x74ce...` hashes change every
run, so they appear in the diff as having "changed" every time. With this
commit, here's what `dump_settings` will print out for a function instead:
"WIKI_CAN_ASSIGN": {
"module": "lms.djangoapps.course_wiki.settings",
"qualname": "CAN_ASSIGN"
},
`notify_credentials` has 2 ways of running.
1. The manual, one-off method which uses `--args_from_database` to specify what should be sent.
2. [The automated method](7316111b35/openedx/core/djangoapps/credentials/management/commands/notify_credentials.py (L157-L159)), which runs on a regular schedule, to catch anything which fell through the cracks.
The automated method does a certain amount of time/date math in order to calculate the entry point of the window based on the current runtime. This is, I assume, why it has some hardcoded logic; it's not at all simple to have a `cron`-run management command running on a regular cadence that can do the same time logic.
```py
if options['auto']:
options['end_date'] = datetime.now().replace(minute=0, second=0, microsecond=0)
options['start_date'] = options['end_date'] - timedelta(hours=4)
```
However, it is not ideal that the actual time window of 4 hours is hardcoded directly into `edx-platform`.
This fix
* creates an overridable `NOTIFY_CREDENTIALS_FREQUENCY` that defaults to 14400 seconds (4 hours).
* pulls that frequency into the quoted code
Using seconds allows maximum flexibility.
FIXES: APER-3383
This command dumps the current Django settings to JSON for
debugging/diagnostics. The output of this command is for *humans*... it
is NOT suitable for consumption by production systems.
In particular, we are introducing this command as part of a series of
refactorings to the Django settings files lms/envs/* and cms/envs/*.
We want to ensure that these refactorings do not introduce any
unexpected breaking changes, so the dump_settings command will both help
us manually verify our refactorings and help operators verify that our
refactorings behave expectedly when using their custom python/yaml
settings files.
Related to: https://github.com/openedx/edx-platform/pull/36131
Updates to support studio_view (editors) in xblock_v2 iframe.
- Send a message when cancel button is clicked on xblock_v2 iframe only in studio_view
- Send a message when save.end event is notified on xblock_v2 iframe.
- Send notify function in runtime. This is to avoid errors when saving the Xblock
Updates the StudioHome API's allow_to_create_new_org to require both organization-creation permissions and ORGANIZATION_AUTOCREATE to be enabled. It also adds the list of "allowed organizations for libraries" to the Studio Home API so that the Authoring MFE can use it.