diff --git a/courses/migrations/0022_programrequirements.py b/courses/migrations/0022_programrequirements.py index 1f2eeb750b..c562a556b1 100644 --- a/courses/migrations/0022_programrequirements.py +++ b/courses/migrations/0022_programrequirements.py @@ -107,8 +107,17 @@ class Migration(migrations.Migration): name="courses_programrequirement_root_uniq", ), ), - migrations.AlterIndexTogether( - name="programrequirement", - index_together={("program", "course"), ("course", "program")}, + # Changed to use named indexes for Django 5 compatibility + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["program", "course"], name="courses_pro_program_temp_idx" + ), + ), + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["course", "program"], name="courses_pro_course__temp_idx" + ), ), ] diff --git a/courses/migrations/0055_rename_programrequirement_index.py b/courses/migrations/0055_rename_programrequirement_index.py index 36aa09e8de..cb7cb39b1d 100644 --- a/courses/migrations/0055_rename_programrequirement_index.py +++ b/courses/migrations/0055_rename_programrequirement_index.py @@ -1,6 +1,7 @@ # Generated by Django 4.2 on 2024-09-10 17:28 +# Modified for Django 5.2 compatibility -from django.db import migrations +from django.db import migrations, models class Migration(migrations.Migration): @@ -9,14 +10,26 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RenameIndex( + # Remove temporary indexes from migration 0022 + migrations.RemoveIndex( model_name="programrequirement", - new_name="courses_pro_course__fdcdb6_idx", - old_fields=("course", "program"), + name="courses_pro_program_temp_idx", ), - migrations.RenameIndex( + migrations.RemoveIndex( model_name="programrequirement", - new_name="courses_pro_program_c8ff7c_idx", - old_fields=("program", "course"), + name="courses_pro_course__temp_idx", + ), + # Add properly named indexes + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["course", "program"], name="courses_pro_course__fdcdb6_idx" + ), + ), + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["program", "course"], name="courses_pro_program_c8ff7c_idx" + ), ), ] diff --git a/courses/migrations/0064_rename_programrequirement_program_required_program_courses_pro_program_18e9ef_idx_and_more.py b/courses/migrations/0064_rename_programrequirement_program_required_program_courses_pro_program_18e9ef_idx_and_more.py index 3f14fdacb2..03fa64343c 100644 --- a/courses/migrations/0064_rename_programrequirement_program_required_program_courses_pro_program_18e9ef_idx_and_more.py +++ b/courses/migrations/0064_rename_programrequirement_program_required_program_courses_pro_program_18e9ef_idx_and_more.py @@ -1,6 +1,7 @@ # Generated by Django 4.2.22 on 2025-07-02 18:33 +# Modified for Django 5.2 compatibility -from django.db import migrations +from django.db import migrations, models class Migration(migrations.Migration): @@ -9,18 +10,24 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RenameIndex( - model_name="programrequirement", - new_name="courses_pro_program_18e9ef_idx", - old_fields=("program", "required_program"), - ), - migrations.RenameIndex( - model_name="programrequirement", - new_name="courses_pro_require_99b956_idx", - old_fields=("required_program", "program"), - ), + # Remove the old index_together setting migrations.AlterIndexTogether( name="programrequirement", index_together=set(), ), + # Add named indexes explicitly + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["program", "required_program"], + name="courses_pro_program_18e9ef_idx", + ), + ), + migrations.AddIndex( + model_name="programrequirement", + index=models.Index( + fields=["required_program", "program"], + name="courses_pro_require_99b956_idx", + ), + ), ] diff --git a/courses/models.py b/courses/models.py index 2cea07e5cf..3468c21030 100644 --- a/courses/models.py +++ b/courses/models.py @@ -1996,11 +1996,24 @@ class Meta: ), ) indexes = [ - models.Index(fields=("program", "course")), - models.Index(fields=("course", "program")), - models.Index(fields=("program", "required_program")), - models.Index(fields=("required_program", "program")), - models.Index(fields=("program", "node_type", "depth")), + models.Index( + fields=["program", "course"], name="courses_pro_program_c8ff7c_idx" + ), + models.Index( + fields=["course", "program"], name="courses_pro_course__fdcdb6_idx" + ), + models.Index( + fields=["program", "required_program"], + name="courses_pro_program_18e9ef_idx", + ), + models.Index( + fields=["required_program", "program"], + name="courses_pro_require_99b956_idx", + ), + models.Index( + fields=["program", "node_type", "depth"], + name="courses_pro_program_4f3727_idx", + ), ] diff --git a/ecommerce/migrations/0022_backfill_reference_number.py b/ecommerce/migrations/0022_backfill_reference_number.py index 6a301e2dcc..b36d7ed1c8 100644 --- a/ecommerce/migrations/0022_backfill_reference_number.py +++ b/ecommerce/migrations/0022_backfill_reference_number.py @@ -2,8 +2,8 @@ from django.conf import settings from django.db import migrations -from django.db.models import F, Value -from django.db.models.functions import Concat +from django.db.models import CharField, F, Value +from django.db.models.functions import Cast, Concat from ecommerce.constants import REFERENCE_NUMBER_PREFIX @@ -15,7 +15,8 @@ def backfill_order_reference_number(apps, schema_editor): Value(REFERENCE_NUMBER_PREFIX), Value(settings.ENVIRONMENT), Value("-"), - F("id"), + Cast(F("id"), CharField()), + output_field=CharField(), ) ) diff --git a/main/settings.py b/main/settings.py index 12ee67e741..0b0c0e61bb 100644 --- a/main/settings.py +++ b/main/settings.py @@ -1151,6 +1151,7 @@ OAUTH2_PROVIDER_REFRESH_TOKEN_MODEL = "oauth2_provider.RefreshToken" # noqa: S105 OAUTH2_PROVIDER = { + "PKCE_REQUIRED": False, "OIDC_ENABLED": True, "OIDC_RSA_PRIVATE_KEY": get_string( name="OIDC_RSA_PRIVATE_KEY", diff --git a/poetry.lock b/poetry.lock index fb74baaff2..ebb73512f6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1022,18 +1022,18 @@ files = [ [[package]] name = "django" -version = "4.2.25" +version = "5.2.1" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main", "dev"] files = [ - {file = "django-4.2.25-py3-none-any.whl", hash = "sha256:9584cf26b174b35620e53c2558b09d7eb180a655a3470474f513ff9acb494f8c"}, - {file = "django-4.2.25.tar.gz", hash = "sha256:2391ab3d78191caaae2c963c19fd70b99e9751008da22a0adcc667c5a4f8d311"}, + {file = "django-5.2.1-py3-none-any.whl", hash = "sha256:a9b680e84f9a0e71da83e399f1e922e1ab37b2173ced046b541c72e1589a5961"}, + {file = "django-5.2.1.tar.gz", hash = "sha256:57fe1f1b59462caed092c80b3dd324fd92161b620d59a9ba9181c34746c97284"}, ] [package.dependencies] -asgiref = ">=3.6.0,<4" +asgiref = ">=3.8.1" sqlparse = ">=0.3.1" tzdata = {version = "*", markers = "sys_platform == \"win32\""} @@ -1211,22 +1211,25 @@ taggit = ["django-taggit (>=3.1)"] [[package]] name = "django-oauth-toolkit" -version = "1.7.1" +version = "3.1.0" description = "OAuth2 Provider for Django" optional = false -python-versions = "*" +python-versions = ">=3.8" groups = ["main"] files = [ - {file = "django-oauth-toolkit-1.7.1.tar.gz", hash = "sha256:37b690fa53f340c7391bdbc0fdbb32fd9ef8a7c012e72ee8754c331a2d7b4adb"}, - {file = "django_oauth_toolkit-1.7.1-py3-none-any.whl", hash = "sha256:756e44421d0993f27705736b6c33a3d89018393859a31ac926296950f76e4433"}, + {file = "django_oauth_toolkit-3.1.0-py3-none-any.whl", hash = "sha256:10ddc90804297d913dfb958edd58d5fac541eb1ca912f47893ca1e482bb2a11f"}, + {file = "django_oauth_toolkit-3.1.0.tar.gz", hash = "sha256:d5a59d07588cfefa8818e99d65040a252eb2ede22512483e2240c91d0b885c8e"}, ] [package.dependencies] -django = ">=2.2,<4.0.0 || >4.0.0" -jwcrypto = ">=0.8.0" -oauthlib = ">=3.1.0" +django = ">=4.2" +jwcrypto = ">=1.5.0" +oauthlib = ">=3.2.2" requests = ">=2.13.0" +[package.extras] +dev = ["m2r", "pytest", "pytest-cov", "sphinx-rtd-theme"] + [[package]] name = "django-object-actions" version = "5.0.0" @@ -1499,14 +1502,14 @@ files = [ [[package]] name = "djangorestframework" -version = "3.16.0" +version = "3.16.1" description = "Web APIs for Django, made easy." optional = false python-versions = ">=3.9" groups = ["main", "dev"] files = [ - {file = "djangorestframework-3.16.0-py3-none-any.whl", hash = "sha256:bea7e9f6b96a8584c5224bfb2e4348dfb3f8b5e34edbecb98da258e892089361"}, - {file = "djangorestframework-3.16.0.tar.gz", hash = "sha256:f022ff46613584de994c0c6a4aebbace5fd700555fbe9d33b865ebf173eba6c9"}, + {file = "djangorestframework-3.16.1-py3-none-any.whl", hash = "sha256:33a59f47fb9c85ede792cbf88bde71893bcda0667bc573f784649521f1102cec"}, + {file = "djangorestframework-3.16.1.tar.gz", hash = "sha256:166809528b1aced0a17dc66c24492af18049f2c9420dbd0be29422029cfc3ff7"}, ] [package.dependencies] @@ -6038,4 +6041,4 @@ cffi = ["cffi (>=1.17,<2.0) ; platform_python_implementation != \"PyPy\" and pyt [metadata] lock-version = "2.1" python-versions = "^3.10" -content-hash = "8cb0b37ab063ac0cd946abac719c50c4ce7534f752cae54214d8b507b3f25340" +content-hash = "f079dc9b140e398e2f628eaa1921978dac753069be8f704d902469c1c1d00b9c" diff --git a/pyproject.toml b/pyproject.toml index 8b10d97368..3379e4e2c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ celery-redbeat = "^2.0.0" click = ">=8.1,!=8.2.0" deepdiff = "^8.0.0" dj-database-url = "^0.5.0" -django = "4.2.25" +django = "5.2.1" django-anymail = {extras = ["mailgun"], version = "^11.1"} django-cors-headers = "^4.0.0" django-countries = "^7.2.1" @@ -29,7 +29,7 @@ django-filter = "^24.3" django-health-check = { git = "https://github.com/revsys/django-health-check", rev="53f9bdc3a7acc8a577319987fef0bd3040eef4b4" } # pragma: allowlist secret django-hijack = "^3.6.0" django-ipware = "^7.0.0" -django-oauth-toolkit = "^1.7.0" +django-oauth-toolkit = "^3.1.0" django-redis = "^5.0.0" django-reversion = "^5.1.0" django-robots = "6.1" @@ -38,7 +38,7 @@ django-treebeard = "^4.5.1" django-user-agents = "^0.4.0" django-viewflow = "^2.2.7" django-webpack-loader = "^3.0.0" -djangorestframework = "^3.12.4" +djangorestframework = "^3.16.1" djoser = "^2.1.0" drf-extensions = "^0.8.0" drf-spectacular = "^0.28.0" diff --git a/pytest.ini b/pytest.ini index 97cbb9b657..f3aabee736 100644 --- a/pytest.ini +++ b/pytest.ini @@ -11,6 +11,8 @@ env = CELERY_TASK_ALWAYS_EAGER=True DEBUG=False DJANGO_SETTINGS_MODULE=main.settings + SECRET_KEY=test-secret-key-for-testing + MITX_ONLINE_ADMIN_EMAIL=admin@test.local GOOGLE_DOMAIN_VERIFICATION_TAG_VALUE= KEYCLOAK_BASE_URL=http://keycloak/ KEYCLOAK_REALM_NAME=ol-test diff --git a/users/views_test.py b/users/views_test.py index 9f8fc1bd93..5739bde6b7 100644 --- a/users/views_test.py +++ b/users/views_test.py @@ -24,10 +24,12 @@ def test_cannot_create_user(client): assert resp.status_code == status.HTTP_404_NOT_FOUND -def test_cannot_update_user(user_client, user): - """Verify the api to update a user is doesn't accept the verb""" - resp = user_client.patch( - reverse("users_api-detail", kwargs={"pk": user.id}), data={"name": "Name"} +def test_cannot_update_user(staff_client, user): + """Verify the api to update a user doesn't accept the verb""" + resp = staff_client.patch( + reverse("users_api-detail", kwargs={"pk": user.id}), + data={"name": "Name"}, + content_type="application/json", ) assert resp.status_code == status.HTTP_405_METHOD_NOT_ALLOWED