From 0b68c84286fe53c32b6b8c1e01ce30845bb8496c Mon Sep 17 00:00:00 2001 From: Andy Shultz Date: Thu, 8 Dec 2022 09:17:22 -0500 Subject: [PATCH] fix: convert exam update into a lambda on commit Current behavior for both old and new exams paths on exam creation is that the signal fires, the update code kicks off a celery task which looks for a new exam, and that exam is not found so no actual update is done. Or the old version is visible but the updated version is not. By waiting until the change is actually committed, we should find the new exam when we search for it. This is currently an invisible bug just because of the large numbers of updates that working on a course provides, the exam will be correct unless it was the absolute last thing that was touched, in which case it will be out of date. --- cms/djangoapps/contentstore/signals/handlers.py | 4 ++-- cms/djangoapps/contentstore/tests/test_exams.py | 4 +++- cms/djangoapps/contentstore/tests/test_proctoring.py | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/cms/djangoapps/contentstore/signals/handlers.py b/cms/djangoapps/contentstore/signals/handlers.py index 1cb5873327..535169f021 100644 --- a/cms/djangoapps/contentstore/signals/handlers.py +++ b/cms/djangoapps/contentstore/signals/handlers.py @@ -125,9 +125,9 @@ def listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable= dump_course_to_neo4j ) - # register special exams asynchronously + # register special exams asynchronously after the data is ready course_key_str = str(course_key) - update_special_exams_and_publish.delay(course_key_str) + transaction.on_commit(lambda: update_special_exams_and_publish.delay(course_key_str)) if key_supports_outlines(course_key): # Push the course outline to learning_sequences asynchronously. diff --git a/cms/djangoapps/contentstore/tests/test_exams.py b/cms/djangoapps/contentstore/tests/test_exams.py index 0da6345a48..a014089ebc 100644 --- a/cms/djangoapps/contentstore/tests/test_exams.py +++ b/cms/djangoapps/contentstore/tests/test_exams.py @@ -2,7 +2,7 @@ Test the exams service integration into Studio """ from datetime import datetime, timedelta -from unittest.mock import patch +from unittest.mock import patch, Mock import ddt from django.conf import settings @@ -19,6 +19,8 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory @override_waffle_flag(EXAMS_IDA, active=True) @patch.dict('django.conf.settings.FEATURES', {'ENABLE_SPECIAL_EXAMS': True}) @patch('cms.djangoapps.contentstore.exams._patch_course_exams') +@patch('cms.djangoapps.contentstore.signals.handlers.transaction.on_commit', + new=Mock(side_effect=lambda func: func()),) # run right away class TestExamService(ModuleStoreTestCase): """ Test for syncing exams to the exam service diff --git a/cms/djangoapps/contentstore/tests/test_proctoring.py b/cms/djangoapps/contentstore/tests/test_proctoring.py index 80f6e2d207..ec92eb74e4 100644 --- a/cms/djangoapps/contentstore/tests/test_proctoring.py +++ b/cms/djangoapps/contentstore/tests/test_proctoring.py @@ -4,7 +4,7 @@ Tests for the edx_proctoring integration into Studio from datetime import datetime, timedelta -from unittest.mock import patch +from unittest.mock import patch, Mock import ddt from django.conf import settings @@ -20,6 +20,8 @@ from common.djangoapps.student.tests.factories import UserFactory @ddt.ddt @patch.dict('django.conf.settings.FEATURES', {'ENABLE_SPECIAL_EXAMS': True}) +@patch('cms.djangoapps.contentstore.signals.handlers.transaction.on_commit', + new=Mock(side_effect=lambda func: func()),) # run right away class TestProctoredExams(ModuleStoreTestCase): """ Tests for the publishing of proctored exams