Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
run: cat Aptfile | sudo xargs apt-get install

- name: Install uv
uses: astral-sh/setup-uv@v7
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
enable-cache: true

Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ repos:
- --exclude-files
- "_test.js$"
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.15.11"
rev: "v0.15.12"
hooks:
- id: ruff-format
- id: ruff
Expand Down
8 changes: 4 additions & 4 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
".yarn/",
"_test.py$",
"test_.*.py",
"poetry.lock",
"uv.lock",
"yarn.lock",
"compliance/test_data/cybersource/",
"_test.js$"
Expand Down Expand Up @@ -189,14 +189,14 @@
"filename": "pytest.ini",
"hashed_secret": "c0d7ae39ad8e0e46cdbac4c3fb44a6bc1a17105d",
"is_verified": false,
"line_number": 19
"line_number": 18
},
{
"type": "Secret Keyword",
"filename": "pytest.ini",
"hashed_secret": "b235838f76594bf21886c6eec9c06a207e9ec5ce",
"is_verified": false,
"line_number": 35
"line_number": 34
}
],
"sheets/dev-setup.md": [
Expand Down Expand Up @@ -245,5 +245,5 @@
}
]
},
"generated_at": "2025-06-19T09:18:19Z"
"generated_at": "2026-04-13T13:24:33Z"
}
8 changes: 8 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
Release Notes
=============

Version 0.194.0
---------------

- chore(deps): update astral-sh/setup-uv action to v8 (#3896)
- fix(deps): update dependency beautifulsoup4 to v4.14.3 (#3510)
- Wagtail and django upgrade (#3876)
- [pre-commit.ci] pre-commit autoupdate (#3898)

Version 0.193.2 (Released April 30, 2026)
---------------

Expand Down
3 changes: 2 additions & 1 deletion b2b_ecommerce/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ def _generate_b2b_cybersource_sa_payload(*, order, receipt_url, cancel_url):

product_version = order.product_version
content_object = product_version.product.content_object
content_type = str(product_version.product.content_type)
_ct = product_version.product.content_type
content_type = f"{_ct.app_label} | {_ct.name}"
price = order.total_price

return {
Expand Down
2 changes: 1 addition & 1 deletion b2b_ecommerce/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def test_signed_payload(mocker, contract_number):
"item_0_code": "enrollment_code",
"item_0_name": f"Enrollment codes for {product_version.description}"[:254],
"item_0_quantity": order.num_seats,
"item_0_sku": f"enrollment_code-{str(product.content_type)}-{product.content_object.id}", # noqa: RUF010
"item_0_sku": f"enrollment_code-{product.content_type.app_label} | {product.content_type.name}-{product.content_object.id}",
"item_0_tax_amount": "0",
"item_0_unit_price": str(total_price),
"line_item_count": 1,
Expand Down
5 changes: 3 additions & 2 deletions b2b_ecommerce/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ def to_dict(self):
**serialize_model_object(self.product_version),
"product_info": {
**serialize_model_object(self.product_version.product),
"content_type_string": str(
self.product_version.product.content_type
"content_type_string": "{} | {}".format(
self.product_version.product.content_type.app_label,
self.product_version.product.content_type.name,
),
"content_object": serialize_model_object(
self.product_version.product.content_object
Expand Down
2 changes: 1 addition & 1 deletion b2b_ecommerce/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def test_b2b_order_audit():
**serialize_model_object(order.product_version),
"product_info": {
**serialize_model_object(order.product_version.product),
"content_type_string": str(order.product_version.product.content_type),
"content_type_string": f"{order.product_version.product.content_type.app_label} | {order.product_version.product.content_type.name}",
"content_object": serialize_model_object(
order.product_version.product.content_object
),
Expand Down
15 changes: 0 additions & 15 deletions cms/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,6 @@ class Meta:
],
blank=True,
help_text="The content of this tab on the program page",
use_json_field=True,
)

content_panels = Page.content_panels + [ # noqa: RUF005
Expand Down Expand Up @@ -1726,7 +1725,6 @@ class UserTestimonialsPage(CourseProgramChildPage):
[("testimonial", UserTestimonialBlock())],
blank=False,
help_text="Add testimonials to display in this section.",
use_json_field=True,
)
content_panels = [
FieldPanel("heading"),
Expand Down Expand Up @@ -1767,7 +1765,6 @@ class NewsAndEventsPage(DisableSitemapURLMixin, Page):
[("news_and_events", NewsAndEventsBlock())],
blank=False,
help_text="Add news and events updates to display in this section.",
use_json_field=True,
)
content_panels = [FieldPanel("heading"), FieldPanel("items")]
api_fields = [
Expand Down Expand Up @@ -1825,7 +1822,6 @@ class LearningOutcomesPage(CourseProgramChildPage):
[("outcome", TextBlock(icon="plus"))],
blank=False,
help_text="Detail about What you'll learn as learning outcome.",
use_json_field=True,
)

content_panels = [
Expand All @@ -1851,7 +1847,6 @@ class LearningTechniquesPage(CourseProgramChildPage):
[("techniques", LearningTechniqueBlock())],
blank=False,
help_text="Enter detail about how you'll learn.",
use_json_field=True,
)

content_panels = [FieldPanel("title"), FieldPanel("technique_items")]
Expand Down Expand Up @@ -2035,7 +2030,6 @@ class WhoShouldEnrollPage(CourseProgramChildPage):
],
blank=False,
help_text='Contents of the "Who Should Enroll" section.',
use_json_field=True,
)
switch_layout = models.BooleanField(
blank=True,
Expand Down Expand Up @@ -2095,7 +2089,6 @@ class CoursesInProgramPage(CourseProgramChildPage):
],
help_text="The courseware to display in this carousel",
blank=True,
use_json_field=True,
)

@property
Expand Down Expand Up @@ -2155,7 +2148,6 @@ class FacultyMembersPage(CourseProgramChildPage):
members = StreamField(
[("member", FacultyBlock())],
help_text="The faculty members to display on this page",
use_json_field=True,
)
content_panels = [
FieldPanel("heading"),
Expand All @@ -2180,7 +2172,6 @@ class AbstractImageCarousel(Page):
[("image", ImageChooserBlock(help_text="Choose an image to upload."))],
blank=False,
help_text="Add images for this section.",
use_json_field=True,
)

content_panels = [FieldPanel("title"), FieldPanel("images")]
Expand Down Expand Up @@ -2240,7 +2231,6 @@ class ResourcePage(Page):
[("content", ResourceBlock())],
blank=False,
help_text="Enter details of content.",
use_json_field=True,
)

content_panels = Page.content_panels + [ # noqa: RUF005
Expand Down Expand Up @@ -2395,15 +2385,13 @@ class PartnerLogoPlacement(models.IntegerChoices):
),
blank=True,
help_text="You can choose upto 5 signatories.",
use_json_field=True,
)

overrides = StreamField(
[("course_run", CourseRunCertificateOverrides())],
blank=True,
help_text="Overrides for specific runs of this Course/Program",
validators=[validate_unique_readable_ids],
use_json_field=True,
)

display_mit_seal = models.BooleanField(
Expand Down Expand Up @@ -2659,7 +2647,6 @@ class LearningJourneySection(EnterpriseChildPage):
[("journey", TextBlock(icon="plus"))],
blank=False,
help_text="Enter the text for this learning journey item.",
use_json_field=True,
)
call_to_action = models.CharField(
max_length=30,
Expand Down Expand Up @@ -2735,7 +2722,6 @@ class SuccessStoriesSection(EnterpriseChildPage):
[("success_story", SuccessStoriesBlock())],
blank=False,
help_text="Manage the individual success stories. Each story is a separate block.",
use_json_field=True,
)

content_panels = [
Expand Down Expand Up @@ -2794,7 +2780,6 @@ class EnterprisePage(WagtailCachedPageMixin, Page):
headings = StreamField(
[("heading", BannerHeadingBlock())],
help_text="Add banner headings for this page.",
use_json_field=True,
)
background_image = models.ForeignKey(
Image,
Expand Down
13 changes: 7 additions & 6 deletions courses/utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
Tests for signals
"""

from datetime import timedelta, datetime
import pytz
from datetime import timedelta, datetime, timezone
import re

import factory
Expand Down Expand Up @@ -34,8 +33,8 @@

pytestmark = pytest.mark.django_db

START_DT = datetime(2098, 1, 1, tzinfo=pytz.UTC)
END_DT = datetime(2099, 2, 1, tzinfo=pytz.UTC)
START_DT = datetime(2098, 1, 1, tzinfo=timezone.utc)
END_DT = datetime(2099, 2, 1, tzinfo=timezone.utc)


def make_api_course(course_id, name):
Expand Down Expand Up @@ -352,11 +351,13 @@ def test_sync_course_runs(
if re.match(COURSE_KEY_PATTERN, data["courseware_id"])
]
mock_course_list.get_courses.assert_called_once_with(
course_keys=valid_course_keys, username=None
course_keys=valid_course_keys,
username=settings.OPENEDX_SERVICE_WORKER_USERNAME,
)
elif not api_error:
mock_course_list.get_courses.assert_called_once_with(
course_keys=[data["courseware_id"] for data in local_data], username=None
course_keys=[data["courseware_id"] for data in local_data],
username=settings.OPENEDX_SERVICE_WORKER_USERNAME,
)
else:
mock_course_list.get_courses.assert_called_once()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 4.2.30 on 2026-04-10 10:50

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("courseware", "0004_add_courseware_related_names"),
]

operations = [
migrations.RenameIndex(
model_name="openedxapiauth",
new_name="courseware__user_id_7b66fa_idx",
old_fields=("user", "access_token_expires_on"),
),
]
4 changes: 3 additions & 1 deletion courseware/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ def __str__(self):
return f"OpenEdxApiAuth for {self.user}"

class Meta:
index_together = ("user", "access_token_expires_on")
indexes = [
models.Index(fields=["user", "access_token_expires_on"]),
]
5 changes: 3 additions & 2 deletions ecommerce/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,8 @@ def _generate_cybersource_sa_payload(*, order, receipt_url, cancel_url, ip_addre
product_version=product_version,
tax_rate=order.tax_rate,
)
line_items[f"item_{i}_code"] = str(product_version.product.content_type)
ct = product_version.product.content_type
line_items[f"item_{i}_code"] = f"{ct.app_label} | {ct.name}"
line_items[f"item_{i}_name"] = str(product_version.description)[:254]
line_items[f"item_{i}_quantity"] = line.quantity
line_items[f"item_{i}_sku"] = product_version.product.content_object.id
Expand All @@ -296,7 +297,7 @@ def _generate_cybersource_sa_payload(*, order, receipt_url, cancel_url, ip_addre
readable_id = get_readable_id(content_object)

merchant_fields = {
"merchant_defined_data1": str(product.content_type),
"merchant_defined_data1": f"{product.content_type.app_label} | {product.content_type.name}",
"merchant_defined_data2": readable_id,
"merchant_defined_data3": "1",
}
Expand Down
5 changes: 3 additions & 2 deletions ecommerce/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,9 @@ def to_dict(self):
**serialize_model_object(line.product_version),
"product_info": {
**serialize_model_object(line.product_version.product),
"content_type_string": str(
line.product_version.product.content_type
"content_type_string": "{} | {}".format(
line.product_version.product.content_type.app_label,
line.product_version.product.content_type.name,
),
"content_object": serialize_model_object(
line.product_version.product.content_object
Expand Down
4 changes: 1 addition & 3 deletions ecommerce/models_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ def test_order_audit(has_user, has_lines):
**serialize_model_object(line.product_version),
"product_info": {
**serialize_model_object(line.product_version.product),
"content_type_string": str(
line.product_version.product.content_type
),
"content_type_string": f"{line.product_version.product.content_type.app_label} | {line.product_version.product.content_type.name}",
"content_object": serialize_model_object(
line.product_version.product.content_object
),
Expand Down
3 changes: 2 additions & 1 deletion mail/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ def test_send_message(mailoutbox):

send_messages(messages)

messages_to = [m.to for m in messages]
for message in mailoutbox:
assert message in messages
assert message.to in messages_to


def test_send_message_failure(mocker):
Expand Down
4 changes: 3 additions & 1 deletion mail/templatetags/timezone_converter_url.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""custom template tag to convert a DateTimeField object to a URL for timezone conversion"""

from datetime import timezone as dt_timezone

from django import template
from django.utils import timezone

Expand All @@ -21,7 +23,7 @@ def timezone_converter_url(datetime_obj):
return ""

if timezone.is_naive(datetime_obj):
datetime_obj = timezone.make_aware(datetime_obj, timezone.utc)
datetime_obj = timezone.make_aware(datetime_obj, dt_timezone.utc)

time_param = datetime_obj.strftime("%H%M")
date_param = datetime_obj.strftime("%Y-%m-%d")
Expand Down
2 changes: 1 addition & 1 deletion maxmind/migrations/0001_add_geoname_and_netblock_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class Migration(migrations.Migration):
migrations.AddConstraint(
model_name="netblock",
constraint=models.CheckConstraint(
check=models.Q(
condition=models.Q(
("geoname_id__isnull", False),
("registered_country_geoname_id__isnull", False),
("represented_country_geoname_id__isnull", False),
Expand Down
2 changes: 1 addition & 1 deletion maxmind/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class NetBlock(models.Model):
class Meta:
constraints = [
models.CheckConstraint(
check=models.Q(geoname_id__isnull=False)
condition=models.Q(geoname_id__isnull=False)
| models.Q(registered_country_geoname_id__isnull=False)
| models.Q(represented_country_geoname_id__isnull=False),
name="at_least_one_geoname_id",
Expand Down
Loading
Loading