From 58b110fa9083b8ff7beaff1ee2c50eaeee3b13c0 Mon Sep 17 00:00:00 2001 From: andrey-canon Date: Wed, 9 Oct 2024 11:51:53 -0500 Subject: [PATCH] feat: replace username with extrainfo national_id --- eox_nelp/processors/tests/xapi/mixins.py | 1 + eox_nelp/signals/receivers.py | 5 ++++- eox_nelp/signals/tasks.py | 4 +++- eox_nelp/signals/tests/test_receivers.py | 8 +++++--- eox_nelp/signals/tests/test_tasks.py | 10 ++++++---- eox_nelp/signals/tests/test_utils.py | 22 +++++++++++++--------- eox_nelp/signals/utils.py | 12 ++++++++++-- 7 files changed, 42 insertions(+), 20 deletions(-) diff --git a/eox_nelp/processors/tests/xapi/mixins.py b/eox_nelp/processors/tests/xapi/mixins.py index 124f563d..e1554c98 100644 --- a/eox_nelp/processors/tests/xapi/mixins.py +++ b/eox_nelp/processors/tests/xapi/mixins.py @@ -114,6 +114,7 @@ def tearDown(self): # pylint: disable=invalid-name self.transformer_class.get_data.reset_mock() self.transformer_class.get_data.side_effect = None self.transformer_class.get_object_iri.reset_mock() + modulestore.reset_mock() modulestore.return_value.get_item.reset_mock() def test_course_id_property(self): diff --git a/eox_nelp/signals/receivers.py b/eox_nelp/signals/receivers.py index fddaccdd..716b2ebb 100644 --- a/eox_nelp/signals/receivers.py +++ b/eox_nelp/signals/receivers.py @@ -355,9 +355,12 @@ def mt_course_passed_handler(user, course_id, **kwargs): # pylint: disable=unus if not getattr(settings, "ACTIVATE_MT_TRAINING_STAGE", False): return + extra_info = getattr(user, "extrainfo", None) + national_id = extra_info.national_id if extra_info else user.username + update_mt_training_stage.delay( course_id=str(course_id), - national_id=user.username, + national_id=national_id, stage_result=1, ) diff --git a/eox_nelp/signals/tasks.py b/eox_nelp/signals/tasks.py index e5e3e7b2..23d5b818 100644 --- a/eox_nelp/signals/tasks.py +++ b/eox_nelp/signals/tasks.py @@ -228,6 +228,8 @@ def course_completion_mt_updater(user_id, course_id, stage_result, force_graded= national_id (str): User identifier. """ user = User.objects.get(id=user_id) + extra_info = getattr(user, "extrainfo", None) + national_id = extra_info.national_id if extra_info else user.username is_complete, graded = get_completed_and_graded(user_id, course_id) if not is_complete or (force_graded and not graded) or (not force_graded and graded): @@ -235,6 +237,6 @@ def course_completion_mt_updater(user_id, course_id, stage_result, force_graded= update_mt_training_stage( course_id=course_id, - national_id=user.username, + national_id=national_id, stage_result=stage_result, ) diff --git a/eox_nelp/signals/tests/test_receivers.py b/eox_nelp/signals/tests/test_receivers.py index 2d9f117e..977bc5ce 100644 --- a/eox_nelp/signals/tests/test_receivers.py +++ b/eox_nelp/signals/tests/test_receivers.py @@ -14,7 +14,7 @@ from ddt import data, ddt from django.conf import settings from django.contrib.auth import get_user_model -from django.test import override_settings +from django.test import TestCase, override_settings from django.utils import timezone from eox_core.edxapp_wrapper.users import get_user_signup_source from eventtracking.tracker import get_tracker @@ -42,6 +42,7 @@ update_async_tracker_context, ) from eox_nelp.tests.utils import set_key_values +from eox_nelp.utils import save_extrainfo_field User = get_user_model() UserSignupSource = get_user_signup_source() @@ -620,7 +621,7 @@ def test_call_async_task(self, task_mock): ) -class MtCoursePassedHandlerTestCase(unittest.TestCase): +class MtCoursePassedHandlerTestCase(TestCase): """Test class for mt_course_passed_handler function.""" @patch("eox_nelp.signals.receivers.update_mt_training_stage") @@ -647,12 +648,13 @@ def test_call_async_task(self, task_mock): """ course_id = "course-v1:test+Cx105+2022_T4" user_instance, _ = User.objects.get_or_create(username="Severus") + save_extrainfo_field(user_instance, "national_id", "1234567890") mt_course_passed_handler(user_instance, CourseKey.from_string(course_id)) task_mock.delay.assert_called_with( course_id=course_id, - national_id=user_instance.username, + national_id=user_instance.extrainfo.national_id, stage_result=1, ) diff --git a/eox_nelp/signals/tests/test_tasks.py b/eox_nelp/signals/tests/test_tasks.py index a0b40b7e..6772eab8 100644 --- a/eox_nelp/signals/tests/test_tasks.py +++ b/eox_nelp/signals/tests/test_tasks.py @@ -11,7 +11,7 @@ from ddt import data, ddt from django.conf import settings from django.contrib.auth import get_user_model -from django.test import override_settings +from django.test import TestCase, override_settings from django.utils import timezone from mock import Mock, patch from opaque_keys.edx.keys import CourseKey, UsageKey @@ -32,6 +32,7 @@ ) from eox_nelp.signals.utils import get_completion_summary from eox_nelp.tests.utils import generate_list_mock_data +from eox_nelp.utils import save_extrainfo_field User = get_user_model() FALSY_ACTIVATION_VALUES = [0, "", None, [], False, {}, ()] @@ -534,7 +535,7 @@ def test_update_training_stage_call(self, api_mock): @ddt -class CourseCompletionMtUpdaterTestCase(unittest.TestCase): +class CourseCompletionMtUpdaterTestCase(TestCase): """Test class for course_completion_mt_updater function.""" def setUp(self): @@ -617,7 +618,8 @@ def test_update_mt_training_stage_call(self, test_data, updater_mock, completion - update_mt_training_stage was called with the right parameters. - mock validations pass """ - user_instance, _ = User.objects.get_or_create(username="1245789652") + user_instance, _ = User.objects.get_or_create(username="Minerva") + save_extrainfo_field(user_instance, "national_id", "1234567890") completion_summary_mock.return_value = {"incomplete_count": 0} self.descriptor.grading_policy = {"GRADER": test_data[0]} @@ -630,7 +632,7 @@ def test_update_mt_training_stage_call(self, test_data, updater_mock, completion updater_mock.assert_called_once_with( course_id=self.course_id, - national_id=user_instance.username, + national_id=user_instance.extrainfo.national_id, stage_result=2, ) self.mock_validations() diff --git a/eox_nelp/signals/tests/test_utils.py b/eox_nelp/signals/tests/test_utils.py index 32da7a4e..f0c0ca33 100644 --- a/eox_nelp/signals/tests/test_utils.py +++ b/eox_nelp/signals/tests/test_utils.py @@ -8,13 +8,14 @@ from ddt import data, ddt from django.conf import settings from django.contrib.auth import get_user_model -from django.test import override_settings +from django.test import TestCase, override_settings from django.utils import timezone from mock import patch from opaque_keys.edx.keys import CourseKey from openedx_events.learning.data import CertificateData, CourseData, UserData, UserPersonalData from eox_nelp.signals.utils import _generate_external_certificate_data, _user_has_passing_grade +from eox_nelp.utils import save_extrainfo_field User = get_user_model() @@ -42,13 +43,13 @@ def test_call_user_has_passing_grade(self, course_grade_factory_mock): @ddt -class GenerateExternalCertificateDataTestCase(unittest.TestCase): +class GenerateExternalCertificateDataTestCase(TestCase): """Test class for function `_generate_external_certificate_data`""" def setUp(self): """ Set common conditions for test cases.""" self.user, _ = User.objects.get_or_create( - username="1333666888", + username="RonWeasley", ) self.certificate_data = CertificateData( user=UserData( @@ -69,6 +70,7 @@ def setUp(self): download_url="", name="", ) + save_extrainfo_field(self.user, "national_id", "1234567890") @override_settings(EXTERNAL_CERTIFICATES_GROUP_CODES={"course-v1:test+Cx105+2022_T4": "ABC123"}) @patch("eox_nelp.signals.utils._user_has_passing_grade") @@ -84,14 +86,14 @@ def test_generate_certificate_data(self, passing_mock): passing_mock.return_value = True expected_value = { - 'reference_id': '1333666888~course-v1:test+Cx105+2022_T4', + 'reference_id': f'{self.user.extrainfo.national_id}~course-v1:test+Cx105+2022_T4', "created_at": str(time.date()), "expiration_date": None, "grade": self.certificate_data.grade * 100, "is_passing": True, "group_code": settings.EXTERNAL_CERTIFICATES_GROUP_CODES[str(self.certificate_data.course.course_key)], "user": { - "national_id": self.user.username, + "national_id": self.user.extrainfo.national_id, "english_name": self.certificate_data.user.pii.name, "arabic_name": "", } @@ -131,8 +133,9 @@ def test_invalid_national_id(self, wrong_national_id, passing_mock): """ passing_mock.return_value = True wrong_user, _ = User.objects.get_or_create( - username=wrong_national_id, + username="Albus", ) + save_extrainfo_field(wrong_user, "national_id", wrong_national_id) certificate_data = CertificateData( user=UserData( pii=UserPersonalData( @@ -159,7 +162,7 @@ def test_invalid_national_id(self, wrong_national_id, passing_mock): self.assertRaisesRegex( ValueError, - f"The username or national_id: {wrong_user.username} doesnt match national ID regex", + f"The username or national_id: {wrong_user.extrainfo.national_id} doesnt match national ID regex", _generate_external_certificate_data, **external_certificate_data, ) @@ -183,8 +186,9 @@ def test_generate_certificate_data_saml_extra_association( time = timezone.now() passing_mock.return_value = True saml_association_user, _ = User.objects.get_or_create( - username=saml_extra_association, + username="Severus", ) + save_extrainfo_field(saml_association_user, "national_id", saml_extra_association) certificate_data = CertificateData( user=UserData( pii=UserPersonalData( @@ -204,7 +208,7 @@ def test_generate_certificate_data_saml_extra_association( download_url="", name="", ) - national_id = saml_association_user.username[:10] + national_id = saml_association_user.extrainfo.national_id[:10] expected_value = { 'reference_id': f'{national_id}~course-v1:test+Cx105+2022_T4', diff --git a/eox_nelp/signals/utils.py b/eox_nelp/signals/utils.py index ef4d2444..d6636ec3 100644 --- a/eox_nelp/signals/utils.py +++ b/eox_nelp/signals/utils.py @@ -38,7 +38,15 @@ def _generate_external_certificate_data(time, certificate_data): group_codes = getattr(settings, "EXTERNAL_CERTIFICATES_GROUP_CODES", {}) course_id = str(certificate_data.course.course_key) extra_info = getattr(user, "extrainfo", None) - national_id = user.username[:10] # saml association extra filter + + if extra_info: + national_id = extra_info.national_id + arabic_name = extra_info.arabic_name + else: + national_id = user.username + arabic_name = "" + + national_id = national_id[:10] # saml association extra filter return { "reference_id": generate_reference_id(national_id, course_id), @@ -50,7 +58,7 @@ def _generate_external_certificate_data(time, certificate_data): "user": { "national_id": national_id, "english_name": certificate_data.user.pii.name, - "arabic_name": extra_info.arabic_name if extra_info else "", + "arabic_name": arabic_name, } }