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
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,6 @@ def test_subsection_does_not_exist(self, login_method):
assert status.HTTP_422_UNPROCESSABLE_ENTITY == resp.status_code
assert expected_data == resp.data

@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=True)
def test_override_for_unattempted_learner_records_competency_status(self):
"""
A staff-entered grade counts toward competency status even though the learner never attempted the subsection.
Expand Down
7 changes: 2 additions & 5 deletions lms/djangoapps/grades/subsection_grade.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from decimal import Decimal
from logging import getLogger

from django.conf import settings
from django.db import transaction
from lazy import lazy
from openedx_learning.api import GradedObjectScore, record_graded_object_statuses
Expand Down Expand Up @@ -43,11 +42,9 @@ def _enqueue_competency_rollup(user_id, object_ids):

def _record_competency_status(student, grades):
"""
Records competency status inside the caller's transaction and returns the object ids to roll up, or an empty
list when tracking is off, nothing is scored, or no rows changed.
Records competency status inside the caller's transaction and returns the object ids to roll up. Returns an
empty list when nothing is scored or no status row changed.
"""
if not settings.ENABLE_COMPETENCY_MASTERY_TRACKING:
return []
scores = [score for score in (grade.graded_object_score() for grade in grades) if score]
if not scores or not record_graded_object_statuses(user_id=student.id, scores=scores):
return []
Expand Down
2 changes: 0 additions & 2 deletions lms/djangoapps/grades/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from unittest.mock import patch

import ddt
from django.test import override_settings
from openedx_learning.api import GradedObjectScore

from common.djangoapps.student.models import CourseEnrollment
Expand Down Expand Up @@ -72,7 +71,6 @@ def tearDown(self):
super().tearDown()
PersistentSubsectionGradeOverride.objects.all().delete()

@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=True)
def test_override_without_existing_grade_records_competency_status(self):
CourseEnrollment.enroll(self.user, self.course.id)
new_subsection = BlockFactory.create(parent=self.course, category="sequential", display_name="New Subsection")
Expand Down
4 changes: 2 additions & 2 deletions lms/djangoapps/grades/tests/test_course_grade_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def _assert_section_order(course_grade):
with self.assertNumQueries(3), mock_get_score(1, 2):
_assert_read(expected_pass=False, expected_percent=0) # start off with grade of 0

num_queries = 48
num_queries = 50
with self.assertNumQueries(num_queries), mock_get_score(1, 2):
grade_factory.update(self.request.user, self.course, force_update_subsections=True)

Expand All @@ -87,7 +87,7 @@ def _assert_section_order(course_grade):
with self.assertNumQueries(3):
_assert_read(expected_pass=True, expected_percent=0.5) # NOT updated to grade of .25

num_queries = 24
num_queries = 26
with self.assertNumQueries(num_queries), mock_get_score(2, 2):
grade_factory.update(self.request.user, self.course, force_update_subsections=True)

Expand Down
25 changes: 0 additions & 25 deletions lms/djangoapps/grades/tests/test_subsection_grade.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import pytest
from ddt import data, ddt, unpack
from django.db import DatabaseError, connection
from django.test import override_settings
from kombu.exceptions import OperationalError as KombuOperationalError
from openedx_catalog import api as catalog_api
from openedx_catalog.models_api import CourseRun
Expand Down Expand Up @@ -102,7 +101,6 @@ def _create_grade(self, subsection=None):
return factory.create(subsection or self.sequence, read_only=True, force_calculate=True)


@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=True)
@ddt
class SubsectionGradeCompetencyStatusTest(SubsectionGradeFixtureMixin, GradeTestBase):
"""
Expand Down Expand Up @@ -178,17 +176,6 @@ def test_unattempted_passes_no_score(self):

mock_record.assert_not_called()

@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=False)
def test_setting_off_saves_grades_without_calling_core(self):
with mock_get_score(1, 2), patch(RECORD_PATH) as mock_record:
self._create_grade().update_or_create_model(self.request.user)
CreateSubsectionGrade.bulk_create_models(
UserFactory(), [self._create_grade(self.sequence2)], self.course.id,
)

mock_record.assert_not_called()
assert PersistentSubsectionGrade.objects.count() == 2

def test_bulk_path_records_each_qualifying_subsection(self):
with mock_get_score(1, 2), patch(RECORD_PATH) as mock_record, patch(EMIT_PATH) as mock_emit:
grades = CreateSubsectionGrade.bulk_create_models(
Expand Down Expand Up @@ -278,17 +265,6 @@ def test_single_path_enqueue_kwargs_are_what_the_task_reads(self):
user_id=self.request.user.id, object_ids=[str(self.sequence.location)],
)

@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=False)
def test_setting_off_does_not_enqueue(self):
with mock_get_score(1, 2), patch(RECORD_PATH, return_value=1), patch(ENQUEUE_PATH) as mock_enqueue:
with self.captureOnCommitCallbacks(execute=True):
self._create_grade().update_or_create_model(self.request.user)
CreateSubsectionGrade.bulk_create_models(
UserFactory(), [self._create_grade(self.sequence2)], self.course.id,
)

mock_enqueue.assert_not_called()

def test_bulk_path_enqueues_one_rollup_with_every_scored_object(self):
with mock_get_score(1, 2), patch(RECORD_PATH, return_value=2), patch(ENQUEUE_PATH) as mock_enqueue:
with self.captureOnCommitCallbacks(execute=True):
Expand Down Expand Up @@ -429,7 +405,6 @@ def _assert_tracker_emitted_event(self, tracker_mock, grade):
)


@override_settings(ENABLE_COMPETENCY_MASTERY_TRACKING=True)
class SubsectionGradeCompetencyIntegrationTest(SubsectionGradeFixtureMixin, GradeTestBase):
"""
Grades a subsection against a real competency criterion and checks the learner status stored with the grade.
Expand Down
8 changes: 4 additions & 4 deletions lms/djangoapps/grades/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ def test_block_structure_created_only_once(self):
assert mock_block_structure_create.call_count == 1

@ddt.data(
(ModuleStoreEnum.Type.split, 1, 49, True),
(ModuleStoreEnum.Type.split, 1, 49, False),
(ModuleStoreEnum.Type.split, 1, 50, True),
(ModuleStoreEnum.Type.split, 1, 50, False),
)
@ddt.unpack
def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, create_multiple_subsections):
Expand All @@ -170,7 +170,7 @@ def test_query_counts(self, default_store, num_mongo_calls, num_sql_calls, creat
self._apply_recalculate_subsection_grade()

@ddt.data(
(ModuleStoreEnum.Type.split, 1, 49),
(ModuleStoreEnum.Type.split, 1, 50),
)
@ddt.unpack
def test_query_counts_dont_change_with_more_content(self, default_store, num_mongo_calls, num_sql_calls):
Expand Down Expand Up @@ -258,7 +258,7 @@ def test_problem_block_with_restricted_access(self, mock_subsection_signal):
UserPartition.scheme_extensions = None

@ddt.data(
(ModuleStoreEnum.Type.split, 1, 49),
(ModuleStoreEnum.Type.split, 1, 50),
)
@ddt.unpack
def test_persistent_grades_on_course(self, default_store, num_mongo_queries, num_sql_queries):
Expand Down
11 changes: 0 additions & 11 deletions lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -677,17 +677,6 @@
# .. toggle_tickets: https://openedx.atlassian.net/browse/ENT-3818
ENABLE_COURSE_ASSESSMENT_GRADE_CHANGE_SIGNAL = False

# .. toggle_name: settings.ENABLE_COMPETENCY_MASTERY_TRACKING
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
# .. toggle_description: Set to True to update a learner's competency criterion status in the same transaction that
# persists a subsection grade. Also a safety valve: turning it off stops competency code from running on grade writes.
# .. toggle_warning: When enabled, a competency storage failure makes the grade write fail, and each grade write that
# changes a status queues a roll-up task.
# .. toggle_use_cases: opt_in
# .. toggle_creation_date: 2026-10-01
ENABLE_COMPETENCY_MASTERY_TRACKING = False

# .. toggle_name: settings.ALLOW_ADMIN_ENTERPRISE_COURSE_ENROLLMENT_DELETION
# .. toggle_implementation: DjangoSetting
# .. toggle_default: False
Expand Down
Loading