Skip to content

DO NOT MERGE - DO NOT CLOSE - Dummy PR to track upstream master - #824

Draft
kaustavb12 wants to merge 725 commits into
open-craft:kaustav/downstream_pr_targetfrom
openedx:master
Draft

DO NOT MERGE - DO NOT CLOSE - Dummy PR to track upstream master#824
kaustavb12 wants to merge 725 commits into
open-craft:kaustav/downstream_pr_targetfrom
openedx:master

Conversation

@kaustavb12

@kaustavb12 kaustavb12 commented Feb 6, 2026

Copy link
Copy Markdown
Member

Settings

AN_IMPORTANT_NOTICE: |
  ##########################################
  This is the OpenCraft Sandbox (sandbox.opencraft.com) tracking upstream master.
  Please do not delete or modify this instance without checking with Fox first.
  ##########################################
PLATFORM_NAME: OpenCraft Sandbox
LMS_HOST: sandbox.opencraft.com
CMS_HOST: studio.sandbox.opencraft.com
PREVIEW_LMS_HOST: preview.sandbox.opencraft.com
GROVE_NEW_MFES:
  catalog:
    port: 1998
    repository: https://github.com/openedx/frontend-app-catalog.git
    version: master
GROVE_SIMPLE_THEME_BRANCH: fox/sandbox-fixes
GROVE_SIMPLE_THEME_REPO: https://github.com/open-craft/brand-openedx.git
GROVE_COMMON_SETTINGS: |
  CATALOG_MICROFRONTEND_URL = 'https://apps.sandbox.opencraft.com/catalog'
  ENABLE_CATALOG_MICROFRONTEND = True
  DEFAULT_COURSE_VISIBILITY_IN_CATALOG = 'about'
GROVE_MFE_LMS_COMMON_SETTINGS: |
  MFE_CONFIG['LOGO_URL'] = 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo.png'
  MFE_CONFIG['LOGO_TRADEMARK_URL'] = 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-trademark.png'
  MFE_CONFIG['LOGO_WHITE_URL'] = 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-white.png'
  MFE_CONFIG['FAVICON_URL'] = 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/favicon.ico'
  MFE_CONFIG_OVERRIDES['learner-dashboard'] = {'LOGO_URL': 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-white.png'}
  MFE_CONFIG_OVERRIDES['catalog'] = {'LOGO_URL': 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-white.png'}
  MFE_CONFIG_OVERRIDES['profile'] = {'LOGO_URL': 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-white.png'}
  MFE_CONFIG_OVERRIDES['account'] = {'LOGO_URL': 'https://raw.githubusercontent.com/open-craft/brand-openedx/refs/heads/sandbox/logo-white.png'}
OPENEDX_EXTRA_PIP_REQUIREMENTS:
- git+https://gitlab.com/opencraft/dev/openedx-auto-studio.git@master
- git+https://github.com/open-craft/openedx-edit-links.git@main
- xblock-problem-builder
CONTACT_EMAIL: help@opencraft.com

Tutor requirements

tutor plugins enable sandbox
tutor plugins enable grove-simple-theme
tutor generate-tokens

@kaustavb12
kaustavb12 marked this pull request as draft February 6, 2026 08:34
@open-craft open-craft locked and limited conversation to collaborators Feb 10, 2026
@kaustavb12 kaustavb12 changed the title test: DO NOT MERGE - Dummy PR to track upstream master DO NOT MERGE - DO NOT DELETE - Dummy PR to track upstream master Apr 7, 2026
@kaustavb12 kaustavb12 changed the title DO NOT MERGE - DO NOT DELETE - Dummy PR to track upstream master DO NOT MERGE - DO NOT CLOSE - Dummy PR to track upstream master Apr 7, 2026
pdpinch and others added 15 commits June 15, 2026 08:27
fix: int channels safe dict lookup

Commit generated by workflow `openedx/openedx-platform/.github/workflows/upgrade-one-python-dependency.yml@refs/heads/master`
Commit generated by workflow `openedx/openedx-platform/.github/workflows/upgrade-one-python-dependency.yml@refs/heads/master`

Co-authored-by: bcitro <67378070+bcitro@users.noreply.github.com>
django-countries 9.0.0 changed nullable CountryField semantics: a NULL
database value now returns None instead of Country(code=None). Update
all UserProfile.country call sites that previously relied on the old
behavior:

- Replace `country.code is None` checks with `country is None`
  (embargo/api.py, credit/api/provider.py).
- Guard `.code`/`.name` attribute accesses against None
  (credit/tests/factories.py, user_api/accounts/serializers.py,
  courseware/views/views.py).
- Emit "" instead of str(None) == "None" for Segment traits when
  country is null (student/models/user.py, user_authn/views/register.py)
  to preserve existing serialized output and matching test assertions.

Release notes: https://github.com/SmileyChris/django-countries/blob/main/CHANGES.rst#900-10-june-2026

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 'render the volume control' spec asserted only that *some* element
with class `.volume` existed in the global DOM. It never referenced the
`volumeControl` instance set up in `beforeEach`, so it would pass as
long as any `.volume`-classed element was rendered anywhere — and it ran
synchronously, so it didn't tolerate the rendering completing on a later
tick.

Wait for VideoVolumeControl's own element to attach to its
`.secondary-controls` parent using the `jasmine.waitUntil` pattern
already established in neighboring specs (video_poster_spec.js,
video_progress_slider_spec.js), then assert the element is in the DOM.
Add an explicit `.fail()` branch so the next timeout produces an
actionable error instead of a generic Jasmine timeout.
Before this change, the Student Profile Information CSV that
instructors download from the instructor dashboard showed the literal
text "None" in the city column for users who had not set a city. The
country column for the same users showed up as an empty cell instead.

The cause was a quirk in how the report extracted values: any field
whose Python value was None ended up stringified to "None", but
country was a special object that stringified to "" instead. A 2016
code comment flagged this as "somewhat inconsistent" but it was never
fixed.

The django-countries 9.0.0 upgrade removes the country special case:
an unset country is now plain None, just like city. That made the
country column also show "None", which broke the test that documented
the old quirk.

Rather than accept "None" cells in two columns, this commit fixes the
underlying behaviour so any unset field shows as an empty cell.

BREAKING CHANGE: In the Student Profile Information CSV report, cells
for unset fields (city, country, language, mailing address, etc.)
that used to read the literal text "None" are now empty cells.
Country cells that used to be empty stay empty.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
openedx-authz 1.18.0 added validation that rejects the bare global
scope wildcard '*'. content_libraries calls authz_api.is_user_allowed
with that wildcard from user_can_create_library, so the upgrade broke
LibraryRestoreViewTestCase::test_restore_library_unauthorized (and
likely other code paths exercised at runtime).

Roll openedx-authz back to 1.16.0 until the team owning the
authz migration lands the call-site updates.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
datetime.utcnow() is deprecated in Python 3.12 and scheduled for
removal. Replaces both call sites with datetime.now(UTC) and
updates the session-inactivity middleware tests to mock
datetime.now instead of datetime.utcnow accordingly.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
XBlock.location is deprecated; the documented replacement is
.scope_ids.usage_id. Updates the upstream tag copier to use the
new accessor on both upstream and downstream blocks.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The block_serializer's __init__ accessed self.orig_block_key.course_key,
which emits a DeprecationWarning. .context_key is the documented
replacement and returns the same value for course-block keys, while
also working for library-block keys.

Renames the local variable from course_key to context_key to match.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
models.CheckConstraint.check is deprecated in favor of .condition
(removal scheduled for Django 6.0). Updates the agreement model's
constraint to use the new keyword.

The migration file already uses condition=, so only the model
needed updating.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Django 6.0 will require save()'s force_insert, force_update, using,
and update_fields to be passed as keyword arguments only (positional
support deprecated in 5.1). Updates CourseMode.save() to pass them
by keyword when delegating to super().

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feanil and others added 30 commits July 30, 2026 11:32
…parameters (#38934)

Since this redaction is happening immediately before delete,
the override of redaction values adds complexity that is not
worth maintaining.
Co-authored-by: Kyle McCormick <kyle@axim.org>
The Studio Maintenance dashboard (and its Announcements and Force
Publish tools) was removed in #37432 (feat!: Remove Studio Maintenance
& Announcements).  That removal left one orphaned Underscore template
behind: cms/templates/js/maintenance/force-published-course-response.underscore.

Nothing references it -- no JS, RequireJS build entry, Python view, or
URL loads it -- so it is dead code.  Removing it completes the cleanup.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The renaming is causing some conflicts and causing tests to fail.
Pulling the update from this generic upgrade PR.
The google_analytics_tracking_pixel tag wrapped the image URL in HTML()
and mark_safe(), marking it safe without escaping. Use format_html() so
the interpolated URL is HTML-escaped, resolving pylint W5151
(mark-safe-interpolation).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The PUT /api/contentstore/v1/videos/{course_id}/download endpoint
returns a zip of selected course videos -- the operation is a
download. (The original implementation used PUT, which is the wrong
verb for a read; that's tracked as a separate cleanup.) The handler
synchronously fetched each requested video, materialised each
response in RAM and wrote it to a temp file before zipping. A course
author requesting download of many large videos in one request could
tie up a uWSGI worker for many minutes; concurrent requests exhausted
the worker pool.

Stream the zip directly into the response instead -- each video is
fetched with stream=True and piped chunk-by-chunk into a streaming zip
entry, so peak memory is roughly the chunk size and no temp files are
written to disk. Rate-limit the endpoint per user via the new
VIDEO_DOWNLOAD_RATE_LIMIT setting (default 12/hour, via a
UserRateThrottle subclass on the view). Per-request wall-clock is
bounded by the WSGI server's request timeout.

Closes GHSA-g266-6v7f-j465.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The flag was only ever read via settings.FEATURES.get with an inline
default and was never defined in any envs file. Add an annotated flat
DjangoSetting definition (default False, matching the old inline default)
to cms/envs/common.py so the CMS-only reader can use settings.X directly.
The flag had no envs definition and was only read via settings.FEATURES.get
(with lms/envs/test.py already setting the flat value, routed through the
FeaturesProxy bridge). Add an annotated flat DjangoSetting definition
(default False) to lms/envs/common.py and migrate the two LMS-only readers.
In course_tools.py this also drops the now-unnecessary 'FEATURES is None'
(Edge) guard, since the flat setting always resolves to its default.
The two test classes are plain unittest.TestCase, so @override_settings
can't decorate them; patch.object the flat setting directly instead,
mirroring the prior patch.object(settings, 'FEATURES', ...) approach.
…uested filter (#38109)

Co-authored-by: Kira Miller <31229189+kiram15@users.noreply.github.com>
…38930)

BREAKING CHANGE: Removes the 'library' template from the Studio add-component
strip so that new LegacyLibraryContentBlock instances can no longer be created via the UI.

- Removes 'library' from COMPONENT_TYPES
- Removes 'library' display name entry from component_display_names
- Removes the library block types loop (category == 'library')
- Removes 'library' from component_not_supported_by_library
- Removes the libraries_v1_enabled() filter from _filter_disabled_blocks

Existing library_content blocks continue to work normally, including the
randomized settings editor, "View all" container navigation, and migration
to v2 libraries. Only creation of new blocks via the add-component UI is
prevented.

Refs: #38058
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.