From 0fcda3e55f26b5d187128636f7513da348153c02 Mon Sep 17 00:00:00 2001 From: eemaanamir Date: Wed, 28 Aug 2024 15:03:44 +0500 Subject: [PATCH 1/7] feat: added ORA graded by staff notification --- .../ora_staff_grader/notifications.py | 64 +++++++++++++++++++ lms/djangoapps/ora_staff_grader/ora_api.py | 7 +- lms/djangoapps/ora_staff_grader/views.py | 2 +- .../notifications/base_notification.py | 18 ++++++ .../core/djangoapps/notifications/models.py | 2 +- 5 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 lms/djangoapps/ora_staff_grader/notifications.py diff --git a/lms/djangoapps/ora_staff_grader/notifications.py b/lms/djangoapps/ora_staff_grader/notifications.py new file mode 100644 index 000000000000..aca760dcc536 --- /dev/null +++ b/lms/djangoapps/ora_staff_grader/notifications.py @@ -0,0 +1,64 @@ +""" +This module contains utility functions for sending notifications. +""" +import logging + +from opaque_keys.edx.keys import UsageKey +from opaque_keys import InvalidKeyError + + +from openedx_events.learning.data import UserNotificationData +from openedx_events.learning.signals import USER_NOTIFICATION_REQUESTED +from openedx.core.djangoapps.content.course_overviews.api import ( + get_course_overview_or_none, +) +from lms.djangoapps.ora_staff_grader.errors import ( + XBlockInternalError, +) +from xmodule.modulestore.django import modulestore +from xmodule.modulestore.exceptions import ItemNotFoundError +from django.contrib.auth import get_user_model +from django.conf import settings + +log = logging.getLogger(__name__) +User = get_user_model() + + +def send_staff_grade_assigned_notification(request, usage_id, submission_uuid, submissions): + """ + Send a user notification for a course for a new grade being assigned + """ + try: + ora_user = User.objects.get(email=submissions[submission_uuid]['email']) + # Do not send the notification if the request user is the same as the ora submitter + if request.user != ora_user: + # Get ORA block + ora_usage_key = UsageKey.from_string(usage_id) + ora_metadata = modulestore().get_item(ora_usage_key) + # Get course metadata + course_id = str(ora_usage_key.course_key) + course_metadata = get_course_overview_or_none(course_id) + notification_data = UserNotificationData( + user_ids=[ora_user.id], + context={ + 'ora_name': ora_metadata.display_name, + 'course_name': course_metadata.display_name, + }, + notification_type="ora_staff_grade_assigned", + content_url=f"{settings.LMS_ROOT_URL}/courses/{str(course_id)}/jump_to/{str(ora_usage_key)}", + app_name="grading", + course_key=course_id, + ) + USER_NOTIFICATION_REQUESTED.send_event(notification_data=notification_data) + + # Catch bad ORA location + except (InvalidKeyError, ItemNotFoundError): + log.error(f"Bad ORA location provided: {usage_id}") + + # Issues with the XBlock handlers + except XBlockInternalError as ex: + log.error(ex) + + # Blanket exception handling in case something blows up + except Exception as ex: + log.exception(ex) diff --git a/lms/djangoapps/ora_staff_grader/ora_api.py b/lms/djangoapps/ora_staff_grader/ora_api.py index cfaac2ef6608..15d3fb235db0 100644 --- a/lms/djangoapps/ora_staff_grader/ora_api.py +++ b/lms/djangoapps/ora_staff_grader/ora_api.py @@ -22,6 +22,7 @@ ) from lms.djangoapps.ora_staff_grader.utils import call_xblock_json_handler, is_json +from .notifications import send_staff_grade_assigned_notification def get_submissions(request, usage_id): @@ -116,7 +117,7 @@ def get_assessment_info(request, usage_id, submission_uuid): return json.loads(response.content) -def submit_grade(request, usage_id, grade_data): +def submit_grade(request, usage_id, grade_data, submission_uuid): """ Submit a grade for an assessment. @@ -137,6 +138,10 @@ def submit_grade(request, usage_id, grade_data): context={"handler": handler_name, "msg": response_data.get("msg", "")} ) + if response_data.get("success", False): + submissions = get_submissions(request, usage_id) + send_staff_grade_assigned_notification(request, usage_id, submission_uuid, submissions) + return response_data diff --git a/lms/djangoapps/ora_staff_grader/views.py b/lms/djangoapps/ora_staff_grader/views.py index 16c84ca27a9a..9958ebdbbaa1 100644 --- a/lms/djangoapps/ora_staff_grader/views.py +++ b/lms/djangoapps/ora_staff_grader/views.py @@ -479,7 +479,7 @@ def post(self, request, ora_location, submission_uuid, *args, **kwargs): # Transform grade data and submit assessment, raises on failure context = {"submission_uuid": submission_uuid} grade_data = StaffAssessSerializer(request.data, context=context).data - submit_grade(request, ora_location, grade_data) + submit_grade(request, ora_location, grade_data, submission_uuid) # Clear the lock on the graded submission delete_submission_lock(request, ora_location, submission_uuid) diff --git a/openedx/core/djangoapps/notifications/base_notification.py b/openedx/core/djangoapps/notifications/base_notification.py index a417d4540588..c1c8f239cc12 100644 --- a/openedx/core/djangoapps/notifications/base_notification.py +++ b/openedx/core/djangoapps/notifications/base_notification.py @@ -207,6 +207,24 @@ 'filters': [FILTER_AUDIT_EXPIRED_USERS_WITH_NO_ROLE], 'visible_to': [CourseStaffRole.ROLE, CourseInstructorRole.ROLE] }, + 'ora_staff_grade_assigned': { + 'notification_app': 'grading', + 'name': 'ora_staff_grade_assigned', + 'is_core': False, + 'info': '', + 'web': False, + 'email': False, + 'push': False, + 'email_cadence': EmailCadence.DAILY, + 'non_editable': [], + 'content_template': _('<{p}>You have received a grade for open response assessment ' + '<{strong}>{ora_name}'), + 'content_context': { + 'ora_name': 'Name of ORA in course', + }, + 'email_template': '', + 'filters': [FILTER_AUDIT_EXPIRED_USERS_WITH_NO_ROLE], + }, } COURSE_NOTIFICATION_APPS = { diff --git a/openedx/core/djangoapps/notifications/models.py b/openedx/core/djangoapps/notifications/models.py index e1bdf94acc33..77f7b991b546 100644 --- a/openedx/core/djangoapps/notifications/models.py +++ b/openedx/core/djangoapps/notifications/models.py @@ -23,7 +23,7 @@ ADDITIONAL_NOTIFICATION_CHANNEL_SETTINGS = ['email_cadence'] # Update this version when there is a change to any course specific notification type or app. -COURSE_NOTIFICATION_CONFIG_VERSION = 11 +COURSE_NOTIFICATION_CONFIG_VERSION = 12 def get_course_notification_preference_config(): From 334c735b60146488728d0dcfc00470abb5010e8b Mon Sep 17 00:00:00 2001 From: eemaanamir Date: Wed, 28 Aug 2024 21:44:43 +0500 Subject: [PATCH 2/7] refactor: updated the notification content --- lms/djangoapps/ora_staff_grader/notifications.py | 10 ++++------ lms/djangoapps/ora_staff_grader/ora_api.py | 2 +- .../core/djangoapps/notifications/base_notification.py | 4 +++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lms/djangoapps/ora_staff_grader/notifications.py b/lms/djangoapps/ora_staff_grader/notifications.py index aca760dcc536..9146383de7ae 100644 --- a/lms/djangoapps/ora_staff_grader/notifications.py +++ b/lms/djangoapps/ora_staff_grader/notifications.py @@ -24,12 +24,12 @@ User = get_user_model() -def send_staff_grade_assigned_notification(request, usage_id, submission_uuid, submissions): +def send_staff_grade_assigned_notification(request, usage_id, submission): """ Send a user notification for a course for a new grade being assigned """ try: - ora_user = User.objects.get(email=submissions[submission_uuid]['email']) + ora_user = User.objects.get(email=submission['email']) # Do not send the notification if the request user is the same as the ora submitter if request.user != ora_user: # Get ORA block @@ -43,6 +43,8 @@ def send_staff_grade_assigned_notification(request, usage_id, submission_uuid, s context={ 'ora_name': ora_metadata.display_name, 'course_name': course_metadata.display_name, + 'points_earned': submission['score']['pointsEarned'], + 'points_possible': submission['score']['pointsPossible'], }, notification_type="ora_staff_grade_assigned", content_url=f"{settings.LMS_ROOT_URL}/courses/{str(course_id)}/jump_to/{str(ora_usage_key)}", @@ -58,7 +60,3 @@ def send_staff_grade_assigned_notification(request, usage_id, submission_uuid, s # Issues with the XBlock handlers except XBlockInternalError as ex: log.error(ex) - - # Blanket exception handling in case something blows up - except Exception as ex: - log.exception(ex) diff --git a/lms/djangoapps/ora_staff_grader/ora_api.py b/lms/djangoapps/ora_staff_grader/ora_api.py index 15d3fb235db0..b9e219d8b6df 100644 --- a/lms/djangoapps/ora_staff_grader/ora_api.py +++ b/lms/djangoapps/ora_staff_grader/ora_api.py @@ -140,7 +140,7 @@ def submit_grade(request, usage_id, grade_data, submission_uuid): if response_data.get("success", False): submissions = get_submissions(request, usage_id) - send_staff_grade_assigned_notification(request, usage_id, submission_uuid, submissions) + send_staff_grade_assigned_notification(request, usage_id, submissions[submission_uuid]) return response_data diff --git a/openedx/core/djangoapps/notifications/base_notification.py b/openedx/core/djangoapps/notifications/base_notification.py index c1c8f239cc12..631c150b3724 100644 --- a/openedx/core/djangoapps/notifications/base_notification.py +++ b/openedx/core/djangoapps/notifications/base_notification.py @@ -217,10 +217,12 @@ 'push': False, 'email_cadence': EmailCadence.DAILY, 'non_editable': [], - 'content_template': _('<{p}>You have received a grade for open response assessment ' + 'content_template': _('<{p}>You have received {points_earned} out of {points_possible} on your assessment: ' '<{strong}>{ora_name}'), 'content_context': { 'ora_name': 'Name of ORA in course', + 'points_earned': 'Points earned', + 'points_possible': 'Points possible', }, 'email_template': '', 'filters': [FILTER_AUDIT_EXPIRED_USERS_WITH_NO_ROLE], From b8525d82edcaf4a09f3942127bb5e4b79be95516 Mon Sep 17 00:00:00 2001 From: eemaanamir Date: Wed, 28 Aug 2024 22:55:35 +0500 Subject: [PATCH 3/7] test: updated and added new unit tests --- .../ora_staff_grader/notifications.py | 2 +- .../tests/test_notifications.py | 71 +++++++++++++++++++ .../notifications/tests/test_views.py | 9 ++- 3 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 lms/djangoapps/ora_staff_grader/tests/test_notifications.py diff --git a/lms/djangoapps/ora_staff_grader/notifications.py b/lms/djangoapps/ora_staff_grader/notifications.py index 9146383de7ae..48ce30869d79 100644 --- a/lms/djangoapps/ora_staff_grader/notifications.py +++ b/lms/djangoapps/ora_staff_grader/notifications.py @@ -31,7 +31,7 @@ def send_staff_grade_assigned_notification(request, usage_id, submission): try: ora_user = User.objects.get(email=submission['email']) # Do not send the notification if the request user is the same as the ora submitter - if request.user != ora_user: + if request.user.id != ora_user.id: # Get ORA block ora_usage_key = UsageKey.from_string(usage_id) ora_metadata = modulestore().get_item(ora_usage_key) diff --git a/lms/djangoapps/ora_staff_grader/tests/test_notifications.py b/lms/djangoapps/ora_staff_grader/tests/test_notifications.py new file mode 100644 index 000000000000..7ac20562e9e0 --- /dev/null +++ b/lms/djangoapps/ora_staff_grader/tests/test_notifications.py @@ -0,0 +1,71 @@ +""" +Unit test for notification util +""" +import unittest +from unittest.mock import patch, Mock + +from django.test import RequestFactory +from ..notifications import send_staff_grade_assigned_notification + + +class TestSendStaffGradeAssignedNotification(unittest.TestCase): + """ + Unit tests for the send_staff_grade_assigned_notification function. + """ + + def setUp(self): + """ + Set up mock request, usage_id, and submission data for testing. + """ + self.request_factory = RequestFactory() + self.request = self.request_factory.get('/some/path/') + self.request.user = Mock(id=1) + + self.usage_id = 'block-v1:TestX+TST+TST+type@problem+block@ora' + self.submission = { + 'email': 'student@example.com', + 'score': { + 'pointsEarned': 10, + 'pointsPossible': 20, + } + } + + @patch('lms.djangoapps.ora_staff_grader.notifications.User.objects.get') + @patch('lms.djangoapps.ora_staff_grader.notifications.UsageKey.from_string') + @patch('lms.djangoapps.ora_staff_grader.notifications.modulestore') + @patch('lms.djangoapps.ora_staff_grader.notifications.get_course_overview_or_none') + @patch('lms.djangoapps.ora_staff_grader.notifications.USER_NOTIFICATION_REQUESTED.send_event') + def test_send_notification_success(self, mock_send_event, mock_get_course_overview_or_none, mock_modulestore, mock_from_string, mock_get_user): + """ + Test that the notification is sent when the user IDs do not match. + """ + mock_get_user.return_value = Mock(id=2) + mock_from_string.return_value = Mock(course_key='course-v1:TestX+TST+TST') + mock_modulestore.return_value.get_item.return_value = Mock(display_name="ORA Assignment") + mock_get_course_overview_or_none.return_value = Mock(display_name="Test Course") + + send_staff_grade_assigned_notification(self.request, self.usage_id, self.submission) + + mock_send_event.assert_called_once() + args, kwargs = mock_send_event.call_args + notification_data = kwargs['notification_data'] + self.assertEqual(notification_data.user_ids, [2]) + self.assertEqual(notification_data.context['ora_name'], 'ORA Assignment') + self.assertEqual(notification_data.context['course_name'], 'Test Course') + self.assertEqual(notification_data.context['points_earned'], 10) + self.assertEqual(notification_data.context['points_possible'], 20) + self.assertEqual(notification_data.notification_type, "ora_staff_grade_assigned") + + @patch('lms.djangoapps.ora_staff_grader.notifications.User.objects.get') + @patch('lms.djangoapps.ora_staff_grader.notifications.UsageKey.from_string') + @patch('lms.djangoapps.ora_staff_grader.notifications.USER_NOTIFICATION_REQUESTED.send_event') + def test_no_notification_if_same_user(self, mock_send_event, mock_from_string, mock_get_user): + """ + Test that no notification is sent when the user IDs match. + """ + mock_get_user.return_value = Mock(id=1) # Same ID as the request user + mock_from_string.return_value = Mock(course_key='course-v1:TestX+TST+TST') + + send_staff_grade_assigned_notification(self.request, self.usage_id, self.submission) + + mock_send_event.assert_not_called() diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index e40e52078989..96fab17f9771 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -313,7 +313,14 @@ def _expected_api_response(self, course=None): 'push': True, 'email_cadence': 'Daily', 'info': 'Notifications for submission grading.' - } + }, + 'ora_staff_grade_assigned': { + 'web': False, + 'email': False, + 'push': False, + 'email_cadence': 'Daily', + 'info': '' + }, }, 'non_editable': {} } From f4fa1605ee0763ce50cf6eb535465d948c2d7280 Mon Sep 17 00:00:00 2001 From: eemaanamir Date: Wed, 28 Aug 2024 23:12:17 +0500 Subject: [PATCH 4/7] refactor: fixed pylint error --- lms/djangoapps/ora_staff_grader/tests/test_notifications.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lms/djangoapps/ora_staff_grader/tests/test_notifications.py b/lms/djangoapps/ora_staff_grader/tests/test_notifications.py index 7ac20562e9e0..730234fec89c 100644 --- a/lms/djangoapps/ora_staff_grader/tests/test_notifications.py +++ b/lms/djangoapps/ora_staff_grader/tests/test_notifications.py @@ -35,7 +35,8 @@ def setUp(self): @patch('lms.djangoapps.ora_staff_grader.notifications.modulestore') @patch('lms.djangoapps.ora_staff_grader.notifications.get_course_overview_or_none') @patch('lms.djangoapps.ora_staff_grader.notifications.USER_NOTIFICATION_REQUESTED.send_event') - def test_send_notification_success(self, mock_send_event, mock_get_course_overview_or_none, mock_modulestore, mock_from_string, mock_get_user): + def test_send_notification_success(self, mock_send_event, mock_get_course_overview_or_none, + mock_modulestore, mock_from_string, mock_get_user): """ Test that the notification is sent when the user IDs do not match. """ From b7315d3658bc98d23902463cb1ab5c2f56a693eb Mon Sep 17 00:00:00 2001 From: eemaanamir Date: Tue, 10 Sep 2024 19:28:33 +0500 Subject: [PATCH 5/7] feat: added waffle flag and updated notification --- .../ora_staff_grader/notifications.py | 62 ---------------- lms/djangoapps/ora_staff_grader/ora_api.py | 8 +-- .../tests/test_notifications.py | 72 ------------------- lms/djangoapps/ora_staff_grader/views.py | 2 +- .../notifications/base_notification.py | 4 +- .../djangoapps/notifications/config/waffle.py | 10 +++ .../core/djangoapps/notifications/handlers.py | 8 ++- .../notifications/tests/test_views.py | 2 +- 8 files changed, 22 insertions(+), 146 deletions(-) delete mode 100644 lms/djangoapps/ora_staff_grader/notifications.py delete mode 100644 lms/djangoapps/ora_staff_grader/tests/test_notifications.py diff --git a/lms/djangoapps/ora_staff_grader/notifications.py b/lms/djangoapps/ora_staff_grader/notifications.py deleted file mode 100644 index 48ce30869d79..000000000000 --- a/lms/djangoapps/ora_staff_grader/notifications.py +++ /dev/null @@ -1,62 +0,0 @@ -""" -This module contains utility functions for sending notifications. -""" -import logging - -from opaque_keys.edx.keys import UsageKey -from opaque_keys import InvalidKeyError - - -from openedx_events.learning.data import UserNotificationData -from openedx_events.learning.signals import USER_NOTIFICATION_REQUESTED -from openedx.core.djangoapps.content.course_overviews.api import ( - get_course_overview_or_none, -) -from lms.djangoapps.ora_staff_grader.errors import ( - XBlockInternalError, -) -from xmodule.modulestore.django import modulestore -from xmodule.modulestore.exceptions import ItemNotFoundError -from django.contrib.auth import get_user_model -from django.conf import settings - -log = logging.getLogger(__name__) -User = get_user_model() - - -def send_staff_grade_assigned_notification(request, usage_id, submission): - """ - Send a user notification for a course for a new grade being assigned - """ - try: - ora_user = User.objects.get(email=submission['email']) - # Do not send the notification if the request user is the same as the ora submitter - if request.user.id != ora_user.id: - # Get ORA block - ora_usage_key = UsageKey.from_string(usage_id) - ora_metadata = modulestore().get_item(ora_usage_key) - # Get course metadata - course_id = str(ora_usage_key.course_key) - course_metadata = get_course_overview_or_none(course_id) - notification_data = UserNotificationData( - user_ids=[ora_user.id], - context={ - 'ora_name': ora_metadata.display_name, - 'course_name': course_metadata.display_name, - 'points_earned': submission['score']['pointsEarned'], - 'points_possible': submission['score']['pointsPossible'], - }, - notification_type="ora_staff_grade_assigned", - content_url=f"{settings.LMS_ROOT_URL}/courses/{str(course_id)}/jump_to/{str(ora_usage_key)}", - app_name="grading", - course_key=course_id, - ) - USER_NOTIFICATION_REQUESTED.send_event(notification_data=notification_data) - - # Catch bad ORA location - except (InvalidKeyError, ItemNotFoundError): - log.error(f"Bad ORA location provided: {usage_id}") - - # Issues with the XBlock handlers - except XBlockInternalError as ex: - log.error(ex) diff --git a/lms/djangoapps/ora_staff_grader/ora_api.py b/lms/djangoapps/ora_staff_grader/ora_api.py index b9e219d8b6df..88c6d5648921 100644 --- a/lms/djangoapps/ora_staff_grader/ora_api.py +++ b/lms/djangoapps/ora_staff_grader/ora_api.py @@ -22,7 +22,6 @@ ) from lms.djangoapps.ora_staff_grader.utils import call_xblock_json_handler, is_json -from .notifications import send_staff_grade_assigned_notification def get_submissions(request, usage_id): @@ -117,7 +116,7 @@ def get_assessment_info(request, usage_id, submission_uuid): return json.loads(response.content) -def submit_grade(request, usage_id, grade_data, submission_uuid): +def submit_grade(request, usage_id, grade_data): """ Submit a grade for an assessment. @@ -137,11 +136,6 @@ def submit_grade(request, usage_id, grade_data, submission_uuid): raise XBlockInternalError( context={"handler": handler_name, "msg": response_data.get("msg", "")} ) - - if response_data.get("success", False): - submissions = get_submissions(request, usage_id) - send_staff_grade_assigned_notification(request, usage_id, submissions[submission_uuid]) - return response_data diff --git a/lms/djangoapps/ora_staff_grader/tests/test_notifications.py b/lms/djangoapps/ora_staff_grader/tests/test_notifications.py deleted file mode 100644 index 730234fec89c..000000000000 --- a/lms/djangoapps/ora_staff_grader/tests/test_notifications.py +++ /dev/null @@ -1,72 +0,0 @@ -""" -Unit test for notification util -""" -import unittest -from unittest.mock import patch, Mock - -from django.test import RequestFactory -from ..notifications import send_staff_grade_assigned_notification - - -class TestSendStaffGradeAssignedNotification(unittest.TestCase): - """ - Unit tests for the send_staff_grade_assigned_notification function. - """ - - def setUp(self): - """ - Set up mock request, usage_id, and submission data for testing. - """ - self.request_factory = RequestFactory() - self.request = self.request_factory.get('/some/path/') - self.request.user = Mock(id=1) - - self.usage_id = 'block-v1:TestX+TST+TST+type@problem+block@ora' - self.submission = { - 'email': 'student@example.com', - 'score': { - 'pointsEarned': 10, - 'pointsPossible': 20, - } - } - - @patch('lms.djangoapps.ora_staff_grader.notifications.User.objects.get') - @patch('lms.djangoapps.ora_staff_grader.notifications.UsageKey.from_string') - @patch('lms.djangoapps.ora_staff_grader.notifications.modulestore') - @patch('lms.djangoapps.ora_staff_grader.notifications.get_course_overview_or_none') - @patch('lms.djangoapps.ora_staff_grader.notifications.USER_NOTIFICATION_REQUESTED.send_event') - def test_send_notification_success(self, mock_send_event, mock_get_course_overview_or_none, - mock_modulestore, mock_from_string, mock_get_user): - """ - Test that the notification is sent when the user IDs do not match. - """ - mock_get_user.return_value = Mock(id=2) - mock_from_string.return_value = Mock(course_key='course-v1:TestX+TST+TST') - mock_modulestore.return_value.get_item.return_value = Mock(display_name="ORA Assignment") - mock_get_course_overview_or_none.return_value = Mock(display_name="Test Course") - - send_staff_grade_assigned_notification(self.request, self.usage_id, self.submission) - - mock_send_event.assert_called_once() - args, kwargs = mock_send_event.call_args - notification_data = kwargs['notification_data'] - self.assertEqual(notification_data.user_ids, [2]) - self.assertEqual(notification_data.context['ora_name'], 'ORA Assignment') - self.assertEqual(notification_data.context['course_name'], 'Test Course') - self.assertEqual(notification_data.context['points_earned'], 10) - self.assertEqual(notification_data.context['points_possible'], 20) - self.assertEqual(notification_data.notification_type, "ora_staff_grade_assigned") - - @patch('lms.djangoapps.ora_staff_grader.notifications.User.objects.get') - @patch('lms.djangoapps.ora_staff_grader.notifications.UsageKey.from_string') - @patch('lms.djangoapps.ora_staff_grader.notifications.USER_NOTIFICATION_REQUESTED.send_event') - def test_no_notification_if_same_user(self, mock_send_event, mock_from_string, mock_get_user): - """ - Test that no notification is sent when the user IDs match. - """ - mock_get_user.return_value = Mock(id=1) # Same ID as the request user - mock_from_string.return_value = Mock(course_key='course-v1:TestX+TST+TST') - - send_staff_grade_assigned_notification(self.request, self.usage_id, self.submission) - - mock_send_event.assert_not_called() diff --git a/lms/djangoapps/ora_staff_grader/views.py b/lms/djangoapps/ora_staff_grader/views.py index 9958ebdbbaa1..16c84ca27a9a 100644 --- a/lms/djangoapps/ora_staff_grader/views.py +++ b/lms/djangoapps/ora_staff_grader/views.py @@ -479,7 +479,7 @@ def post(self, request, ora_location, submission_uuid, *args, **kwargs): # Transform grade data and submit assessment, raises on failure context = {"submission_uuid": submission_uuid} grade_data = StaffAssessSerializer(request.data, context=context).data - submit_grade(request, ora_location, grade_data, submission_uuid) + submit_grade(request, ora_location, grade_data) # Clear the lock on the graded submission delete_submission_lock(request, ora_location, submission_uuid) diff --git a/openedx/core/djangoapps/notifications/base_notification.py b/openedx/core/djangoapps/notifications/base_notification.py index 631c150b3724..02b49df89444 100644 --- a/openedx/core/djangoapps/notifications/base_notification.py +++ b/openedx/core/djangoapps/notifications/base_notification.py @@ -207,9 +207,9 @@ 'filters': [FILTER_AUDIT_EXPIRED_USERS_WITH_NO_ROLE], 'visible_to': [CourseStaffRole.ROLE, CourseInstructorRole.ROLE] }, - 'ora_staff_grade_assigned': { + 'ora_grade_assigned': { 'notification_app': 'grading', - 'name': 'ora_staff_grade_assigned', + 'name': 'ora_grade_assigned', 'is_core': False, 'info': '', 'web': False, diff --git a/openedx/core/djangoapps/notifications/config/waffle.py b/openedx/core/djangoapps/notifications/config/waffle.py index af89bb68574f..862dd32f7485 100644 --- a/openedx/core/djangoapps/notifications/config/waffle.py +++ b/openedx/core/djangoapps/notifications/config/waffle.py @@ -28,3 +28,13 @@ # .. toggle_warning: When the flag is ON, Email Notifications feature is enabled. # .. toggle_tickets: INF-1259 ENABLE_EMAIL_NOTIFICATIONS = WaffleFlag(f'{WAFFLE_NAMESPACE}.enable_email_notifications', __name__) + +# .. toggle_name: notifications.enable_ora_grade_notifications +# .. toggle_implementation: CourseWaffleFlag +# .. toggle_default: False +# .. toggle_description: Waffle flag to enable ORA grade notifications +# .. toggle_use_cases: temporary, open_edx +# .. toggle_creation_date: 2024-09-10 +# .. toggle_target_removal_date: 2024-10-10 +# .. toggle_tickets: INF-1304 +ENABLE_ORA_GRADE_NOTIFICATION = CourseWaffleFlag(f"{WAFFLE_NAMESPACE}.enable_ora_grade_notifications", __name__) diff --git a/openedx/core/djangoapps/notifications/handlers.py b/openedx/core/djangoapps/notifications/handlers.py index 505f4b5e7024..f28cb594ea6f 100644 --- a/openedx/core/djangoapps/notifications/handlers.py +++ b/openedx/core/djangoapps/notifications/handlers.py @@ -21,7 +21,7 @@ ForumRoleAudienceFilter, TeamAudienceFilter ) -from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS +from openedx.core.djangoapps.notifications.config.waffle import ENABLE_NOTIFICATIONS, ENABLE_ORA_GRADE_NOTIFICATION from openedx.core.djangoapps.notifications.models import CourseNotificationPreference log = logging.getLogger(__name__) @@ -72,6 +72,12 @@ def generate_user_notifications(signal, sender, notification_data, metadata, **k """ Watches for USER_NOTIFICATION_REQUESTED signal and calls send_web_notifications task """ + if ( + notification_data.notification_type == 'ora_grade_assigned' + and not ENABLE_ORA_GRADE_NOTIFICATION.is_enabled(notification_data.course_key) + ): + return + from openedx.core.djangoapps.notifications.tasks import send_notifications notification_data = notification_data.__dict__ notification_data['course_key'] = str(notification_data['course_key']) diff --git a/openedx/core/djangoapps/notifications/tests/test_views.py b/openedx/core/djangoapps/notifications/tests/test_views.py index 96fab17f9771..27b369d925af 100644 --- a/openedx/core/djangoapps/notifications/tests/test_views.py +++ b/openedx/core/djangoapps/notifications/tests/test_views.py @@ -314,7 +314,7 @@ def _expected_api_response(self, course=None): 'email_cadence': 'Daily', 'info': 'Notifications for submission grading.' }, - 'ora_staff_grade_assigned': { + 'ora_grade_assigned': { 'web': False, 'email': False, 'push': False, From e18655e97f17f7815600f07d43c59ea4e315e596 Mon Sep 17 00:00:00 2001 From: Eemaan Amir <57627710+eemaanamir@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:13:03 +0500 Subject: [PATCH 6/7] refactor: refactored code --- lms/djangoapps/ora_staff_grader/ora_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lms/djangoapps/ora_staff_grader/ora_api.py b/lms/djangoapps/ora_staff_grader/ora_api.py index 88c6d5648921..5060d2cad3a2 100644 --- a/lms/djangoapps/ora_staff_grader/ora_api.py +++ b/lms/djangoapps/ora_staff_grader/ora_api.py @@ -136,6 +136,7 @@ def submit_grade(request, usage_id, grade_data): raise XBlockInternalError( context={"handler": handler_name, "msg": response_data.get("msg", "")} ) + return response_data From 4a61011d8b4936424268f64a65b770658e7050b1 Mon Sep 17 00:00:00 2001 From: Eemaan Amir <57627710+eemaanamir@users.noreply.github.com> Date: Mon, 16 Sep 2024 12:15:02 +0500 Subject: [PATCH 7/7] refactor: refactored code --- lms/djangoapps/ora_staff_grader/ora_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lms/djangoapps/ora_staff_grader/ora_api.py b/lms/djangoapps/ora_staff_grader/ora_api.py index 5060d2cad3a2..cfaac2ef6608 100644 --- a/lms/djangoapps/ora_staff_grader/ora_api.py +++ b/lms/djangoapps/ora_staff_grader/ora_api.py @@ -136,7 +136,7 @@ def submit_grade(request, usage_id, grade_data): raise XBlockInternalError( context={"handler": handler_name, "msg": response_data.get("msg", "")} ) - + return response_data