diff --git a/conf/locale/he/LC_MESSAGES/django.po b/conf/locale/he/LC_MESSAGES/django.po index d29bdaef1f..2ed94f23c8 100644 --- a/conf/locale/he/LC_MESSAGES/django.po +++ b/conf/locale/he/LC_MESSAGES/django.po @@ -19121,10 +19121,6 @@ msgid "" "subjects." msgstr "עיין בקורסים שהושקו לאחרונה וראה מה חדש בנושאים האהובים עליך." -#: themes/edx.org/lms/templates/dashboard.html -msgid "Take advantage of free coaching!" -msgstr "" - #: themes/edx.org/lms/templates/dashboard.html msgid "Get Started" msgstr "" diff --git a/conf/locale/hi/LC_MESSAGES/django.po b/conf/locale/hi/LC_MESSAGES/django.po index 3ecb5136ab..a7bca1b22a 100644 --- a/conf/locale/hi/LC_MESSAGES/django.po +++ b/conf/locale/hi/LC_MESSAGES/django.po @@ -18201,10 +18201,6 @@ msgid "" "subjects." msgstr "" -#: themes/edx.org/lms/templates/dashboard.html -msgid "Take advantage of free coaching!" -msgstr "" - #: themes/edx.org/lms/templates/dashboard.html msgid "Get Started" msgstr "" diff --git a/conf/locale/ko_KR/LC_MESSAGES/django.po b/conf/locale/ko_KR/LC_MESSAGES/django.po index 88054ae64f..3992de5d8d 100644 --- a/conf/locale/ko_KR/LC_MESSAGES/django.po +++ b/conf/locale/ko_KR/LC_MESSAGES/django.po @@ -17370,10 +17370,6 @@ msgid "" "subjects." msgstr "" -#: themes/edx.org/lms/templates/dashboard.html -msgid "Take advantage of free coaching!" -msgstr "" - #: themes/edx.org/lms/templates/dashboard.html msgid "Get Started" msgstr "" diff --git a/conf/locale/pt_BR/LC_MESSAGES/django.po b/conf/locale/pt_BR/LC_MESSAGES/django.po index 6d9800d190..ed9a191556 100644 --- a/conf/locale/pt_BR/LC_MESSAGES/django.po +++ b/conf/locale/pt_BR/LC_MESSAGES/django.po @@ -19492,10 +19492,6 @@ msgid "" "subjects." msgstr "" -#: themes/edx.org/lms/templates/dashboard.html -msgid "Take advantage of free coaching!" -msgstr "" - #: themes/edx.org/lms/templates/dashboard.html msgid "Get Started" msgstr "" diff --git a/conf/locale/ru/LC_MESSAGES/django.po b/conf/locale/ru/LC_MESSAGES/django.po index c14da1dafc..6d2ab4968c 100644 --- a/conf/locale/ru/LC_MESSAGES/django.po +++ b/conf/locale/ru/LC_MESSAGES/django.po @@ -20296,10 +20296,6 @@ msgstr "" "Ознакомьтесь с недавно запущенными курсами и новостями по вашим любимым " "предметам." -#: themes/edx.org/lms/templates/dashboard.html -msgid "Take advantage of free coaching!" -msgstr "" - #: themes/edx.org/lms/templates/dashboard.html msgid "Get Started" msgstr "" diff --git a/openedx/core/djangoapps/catalog/tests/factories.py b/openedx/core/djangoapps/catalog/tests/factories.py index f2760edf86..600b187f9d 100644 --- a/openedx/core/djangoapps/catalog/tests/factories.py +++ b/openedx/core/djangoapps/catalog/tests/factories.py @@ -236,7 +236,6 @@ class ProgramTypeFactory(DictFactoryBase): class ProgramTypeAttrsFactory(DictFactoryBase): uuid = factory.Faker('uuid4') slug = factory.Faker('word') - coaching_supported = False class ProgramFactory(DictFactoryBase): diff --git a/openedx/core/djangoapps/external_user_ids/apps.py b/openedx/core/djangoapps/external_user_ids/apps.py index abf154abc3..4d3c6ca09a 100644 --- a/openedx/core/djangoapps/external_user_ids/apps.py +++ b/openedx/core/djangoapps/external_user_ids/apps.py @@ -11,6 +11,3 @@ class ExternalUserIDConfig(AppConfig): Default configuration for the "openedx.core.djangoapps.credit" Django application. """ name = 'openedx.core.djangoapps.external_user_ids' - - def ready(self): - from . import signals # pylint: disable=unused-import diff --git a/openedx/core/djangoapps/external_user_ids/models.py b/openedx/core/djangoapps/external_user_ids/models.py index 1c4b3943e2..09fe47c4f3 100644 --- a/openedx/core/djangoapps/external_user_ids/models.py +++ b/openedx/core/djangoapps/external_user_ids/models.py @@ -20,7 +20,7 @@ class ExternalIdType(TimeStampedModel): .. no_pii: """ - MICROBACHELORS_COACHING = 'mb_coaching' + CALIPER = 'caliper' XAPI = 'xapi' LTI = 'lti' diff --git a/openedx/core/djangoapps/external_user_ids/signals.py b/openedx/core/djangoapps/external_user_ids/signals.py deleted file mode 100644 index 166303d12b..0000000000 --- a/openedx/core/djangoapps/external_user_ids/signals.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Signal Handlers for External User Ids to be created and maintainer -""" - -from logging import getLogger - -from django.db.models.signals import post_save -from django.dispatch import receiver - -from openedx.core.djangoapps.catalog.utils import get_programs - -from .models import ExternalId, ExternalIdType - -LOGGER = getLogger(__name__) - - -def _user_needs_external_id(instance, created): - return ( - created and - instance.user and - not ExternalId.user_has_external_id( - user=instance.user, - type_name=ExternalIdType.MICROBACHELORS_COACHING) - ) - - -@receiver(post_save, sender='student.CourseEnrollment') -def create_external_id_for_microbachelors_program( - sender, instance, created, **kwargs # pylint: disable=unused-argument -): - """ - Watches for post_save signal for creates on the CourseEnrollment table. - Generate an External ID if the Enrollment is in a MicroBachelors Program - """ - if _user_needs_external_id(instance, created): - mb_programs = [ - program for program in get_programs(course=instance.course_id) - if program.get('type_attrs', {}).get('coaching_supported') - ] - if mb_programs: - ExternalId.add_new_user_id( - user=instance.user, - type_name=ExternalIdType.MICROBACHELORS_COACHING - ) - - -@receiver(post_save, sender='entitlements.CourseEntitlement') -def create_external_id_for_microbachelors_program_entitlement( - sender, instance, created, **kwargs # pylint: disable=unused-argument -): - """ - Watches for post_save signal for creates on the CourseEntitlement table. - Generate an External ID if the Entitlement is in a MicroBachelors Program - """ - if _user_needs_external_id(instance, created): - mb_programs = [ - program for program in get_programs(catalog_course_uuid=instance.course_uuid) - if program.get('type_attrs', {}).get('coaching_supported') - ] - if mb_programs: - ExternalId.add_new_user_id( - user=instance.user, - type_name=ExternalIdType.MICROBACHELORS_COACHING - ) diff --git a/openedx/core/djangoapps/external_user_ids/tests/factories.py b/openedx/core/djangoapps/external_user_ids/tests/factories.py index 86aa747bfe..aaafe27959 100644 --- a/openedx/core/djangoapps/external_user_ids/tests/factories.py +++ b/openedx/core/djangoapps/external_user_ids/tests/factories.py @@ -14,7 +14,7 @@ class ExternalIDTypeFactory(factory.django.DjangoModelFactory): # lint-amnesty, class Meta: model = ExternalIdType - name = FuzzyChoice([ExternalIdType.MICROBACHELORS_COACHING]) + name = FuzzyChoice([ExternalIdType.CALIPER]) description = FuzzyText() diff --git a/openedx/core/djangoapps/external_user_ids/tests/test_signals.py b/openedx/core/djangoapps/external_user_ids/tests/test_signals.py deleted file mode 100644 index 290c3a27ac..0000000000 --- a/openedx/core/djangoapps/external_user_ids/tests/test_signals.py +++ /dev/null @@ -1,192 +0,0 @@ -""" -Signal Tests for External User Ids that are sent out of Open edX -""" - -from opaque_keys.edx.keys import CourseKey -from django.core.cache import cache -from edx_django_utils.cache import RequestCache - -from common.djangoapps.entitlements.models import CourseEntitlement -from openedx.core.djangoapps.catalog.tests.factories import ( - CourseFactory, - ProgramFactory, -) -from common.djangoapps.student.tests.factories import TEST_PASSWORD, UserFactory, CourseEnrollmentFactory -from openedx.core.djangoapps.catalog.cache import ( - CATALOG_COURSE_PROGRAMS_CACHE_KEY_TPL, - COURSE_PROGRAMS_CACHE_KEY_TPL, - PROGRAM_CACHE_KEY_TPL, -) -from openedx.core.djangoapps.external_user_ids.models import ExternalId, ExternalIdType -from common.djangoapps.student.models import CourseEnrollment -from common.djangoapps.course_modes.models import CourseMode - -from openedx.core.djangolib.testing.utils import CacheIsolationTestCase -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order - - -class MicrobachelorsExternalIDTest(ModuleStoreTestCase, CacheIsolationTestCase): - """ - Test cases for Signals for External User Ids - """ - ENABLED_CACHES = ['default'] - - @classmethod - def setUpClass(cls): - super().setUpClass() - - cls.course_list = [] - cls.user = UserFactory.create() - cls.course_keys = [ - CourseKey.from_string('course-v1:edX+DemoX+Test_Course'), - CourseKey.from_string('course-v1:edX+DemoX+Another_Test_Course'), - ] - ExternalIdType.objects.create( - name=ExternalIdType.MICROBACHELORS_COACHING, - description='test' - ) - - def setUp(self): - super().setUp() - RequestCache.clear_all_namespaces() - self.program = self._create_cached_program() - self.client.login(username=self.user.username, password=TEST_PASSWORD) - - def _create_cached_program(self): - """ helper method to create a cached program """ - program = ProgramFactory.create() - - for course_key in self.course_keys: - program['courses'].append(CourseFactory(id=course_key)) - - program['type'] = 'MicroBachelors' - program['type_attrs']['coaching_supported'] = True - - for course in program['courses']: - cache.set( - CATALOG_COURSE_PROGRAMS_CACHE_KEY_TPL.format(course_uuid=course['uuid']), - [program['uuid']], - None - ) - - course_run = course['course_runs'][0]['key'] - cache.set( - COURSE_PROGRAMS_CACHE_KEY_TPL.format(course_run_id=course_run), - [program['uuid']], - None - ) - cache.set( - PROGRAM_CACHE_KEY_TPL.format(uuid=program['uuid']), - program, - None - ) - - return program - - def test_enroll_mb_create_external_id(self): - course_run_key = self.program['courses'][0]['course_runs'][0]['key'] - - # Enroll user - enrollment = CourseEnrollmentFactory.create( - course_id=course_run_key, - user=self.user, - mode=CourseMode.VERIFIED, - ) - enrollment.save() - external_id = ExternalId.objects.get( - user=self.user - ) - assert external_id is not None - assert external_id.external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - - def test_second_enroll_mb_no_new_external_id(self): - course_run_key1 = self.program['courses'][0]['course_runs'][0]['key'] - course_run_key2 = self.program['courses'][1]['course_runs'][0]['key'] - - # Enroll user - CourseEnrollmentFactory.create( - course_id=course_run_key1, - user=self.user, - mode=CourseMode.VERIFIED, - ) - external_id = ExternalId.objects.get( - user=self.user - ) - assert external_id is not None - assert external_id.external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - original_external_user_uuid = external_id.external_user_id - - CourseEnrollmentFactory.create( - course_id=course_run_key2, - user=self.user, - mode=CourseMode.VERIFIED, - ) - enrollments = CourseEnrollment.objects.filter(user=self.user) - - assert len(enrollments) == 2 - - external_ids = ExternalId.objects.filter( - user=self.user - ) - - assert len(external_ids) == 1 - assert external_ids[0].external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - assert original_external_user_uuid == external_ids[0].external_user_id - - def test_entitlement_mb_create_external_id(self): - catalog_course = self.program['courses'][0] - - assert ExternalId.objects.filter( - user=self.user - ).count() == 0 - - entitlement = CourseEntitlement.objects.create( - course_uuid=catalog_course['uuid'], - mode=CourseMode.VERIFIED, - user=self.user, - order_number='TEST-12345' - ) - entitlement.save() - - external_id = ExternalId.objects.get( - user=self.user - ) - assert external_id is not None - assert external_id.external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - - def test_second_entitlement_mb_no_new_external_id(self): - catalog_course1 = self.program['courses'][0] - catalog_course2 = self.program['courses'][1] - - # Enroll user - entitlement = CourseEntitlement.objects.create( - course_uuid=catalog_course1['uuid'], - mode=CourseMode.VERIFIED, - user=self.user, - order_number='TEST-12345' - ) - entitlement.save() - external_id = ExternalId.objects.get( - user=self.user - ) - assert external_id is not None - assert external_id.external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - original_external_user_uuid = external_id.external_user_id - - CourseEntitlement.objects.create( - course_uuid=catalog_course2['uuid'], - mode=CourseMode.VERIFIED, - user=self.user, - order_number='TEST-12345' - ) - entitlements = CourseEntitlement.objects.filter(user=self.user) - - assert len(entitlements) == 2 - - external_ids = ExternalId.objects.filter( - user=self.user - ) - - assert len(external_ids) == 1 - assert external_ids[0].external_id_type.name == ExternalIdType.MICROBACHELORS_COACHING - assert original_external_user_uuid == external_ids[0].external_user_id diff --git a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py index 6ec6e3694f..0cc2754e47 100644 --- a/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py +++ b/openedx/core/djangoapps/user_api/accounts/tests/test_retirement_views.py @@ -39,7 +39,7 @@ from openedx.core.djangoapps.credit.models import ( CreditRequirement, CreditRequirementStatus ) -from openedx.core.djangoapps.external_user_ids.models import ExternalId, ExternalIdType +from openedx.core.djangoapps.external_user_ids.models import ExternalIdType from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory from openedx.core.djangoapps.user_api.accounts.views import AccountRetirementPartnerReportView @@ -496,7 +496,6 @@ class TestPartnerReportingList(ModuleStoreTestCase): """ EXPECTED_MB_ORGS_CONFIG = [ { - AccountRetirementPartnerReportView.ORGS_CONFIG_ORG_KEY: 'mb_coaching', AccountRetirementPartnerReportView.ORGS_CONFIG_FIELD_HEADINGS_KEY: [ AccountRetirementPartnerReportView.STUDENT_ID_KEY, AccountRetirementPartnerReportView.ORIGINAL_EMAIL_KEY, @@ -516,7 +515,7 @@ class TestPartnerReportingList(ModuleStoreTestCase): self.url = reverse('accounts_retirement_partner_report') self.maxDiff = None self.test_created_datetime = datetime.datetime(2018, 1, 1, tzinfo=pytz.UTC) - ExternalIdType.objects.get_or_create(name=ExternalIdType.MICROBACHELORS_COACHING) + ExternalIdType.objects.get_or_create(name=ExternalIdType.CALIPER) def get_user_dict(self, user, enrollments): """ @@ -624,56 +623,6 @@ class TestPartnerReportingList(ModuleStoreTestCase): self.assert_status_and_user_list(user_dicts) - def test_success_mb_coaching(self): - """ - Check that MicroBachelors users who have consented to coaching have the proper info - included for the partner report. - """ - path = 'openedx.core.djangoapps.user_api.accounts.views.has_ever_consented_to_coaching' - with mock.patch(path, return_value=True) as mock_has_ever_consented: - user_dicts, users = self.create_partner_reporting_statuses(num=1) - external_id, created = ExternalId.add_new_user_id( # lint-amnesty, pylint: disable=unused-variable - user=users[0], - type_name=ExternalIdType.MICROBACHELORS_COACHING - ) - - expected_user = user_dicts[0] - expected_users = [expected_user] - expected_user[AccountRetirementPartnerReportView.STUDENT_ID_KEY] = str(external_id.external_user_id) - expected_user[ - AccountRetirementPartnerReportView.ORGS_CONFIG_KEY] = TestPartnerReportingList.EXPECTED_MB_ORGS_CONFIG - - self.assert_status_and_user_list(expected_users) - mock_has_ever_consented.assert_called_once() - - def test_success_mb_coaching_no_external_id(self): - """ - Check that MicroBachelors users who have consented to coaching, but who do not have an external id, have the - proper info included for the partner report. - """ - path = 'openedx.core.djangoapps.user_api.accounts.views.has_ever_consented_to_coaching' - with mock.patch(path, return_value=True) as mock_has_ever_consented: - user_dicts, users = self.create_partner_reporting_statuses(num=1) # lint-amnesty, pylint: disable=unused-variable - - self.assert_status_and_user_list(user_dicts) - mock_has_ever_consented.assert_called_once() - - def test_success_mb_coaching_no_consent(self): - """ - Check that MicroBachelors users who have not consented to coaching have the proper info - included for the partner report. - """ - path = 'openedx.core.djangoapps.user_api.accounts.views.has_ever_consented_to_coaching' - with mock.patch(path, return_value=False) as mock_has_ever_consented: - user_dicts, users = self.create_partner_reporting_statuses(num=1) - ExternalId.add_new_user_id( - user=users[0], - type_name=ExternalIdType.MICROBACHELORS_COACHING - ) - - self.assert_status_and_user_list(user_dicts) - mock_has_ever_consented.assert_called_once() - def test_no_users(self): """ Checks that the call returns a success code and empty list if no users are found. diff --git a/openedx/core/djangoapps/user_api/accounts/views.py b/openedx/core/djangoapps/user_api/accounts/views.py index 83bdde4f44..95e5f7fb31 100644 --- a/openedx/core/djangoapps/user_api/accounts/views.py +++ b/openedx/core/djangoapps/user_api/accounts/views.py @@ -57,7 +57,6 @@ from openedx.core.djangoapps.ace_common.template_context import get_base_templat from openedx.core.djangoapps.api_admin.models import ApiAccessRequest from openedx.core.djangoapps.course_groups.models import UnregisteredLearnerCohortAssignments from openedx.core.djangoapps.credit.models import CreditRequest, CreditRequirementStatus -from openedx.core.djangoapps.external_user_ids.models import ExternalId, ExternalIdType from openedx.core.djangoapps.lang_pref import LANGUAGE_KEY from openedx.core.djangoapps.profile_images.images import remove_profile_images from openedx.core.djangoapps.user_api import accounts @@ -93,11 +92,6 @@ from .serializers import ( from .signals import USER_RETIRE_LMS_CRITICAL, USER_RETIRE_LMS_MISC, USER_RETIRE_MAILINGS from .utils import create_retirement_request_and_deactivate_account, username_suffix_generator -try: - from coaching.api import has_ever_consented_to_coaching -except ImportError: - has_ever_consented_to_coaching = None - log = logging.getLogger(__name__) USER_PROFILE_PII = { @@ -746,49 +740,8 @@ class AccountRetirementPartnerReportView(ViewSet): 'created': retirement_status.created, } - # Some orgs have a custom list of headings and content for the partner report. Add this, if applicable. - self._add_orgs_config_for_user(retirement, retirement_status.user) - return retirement - def _add_orgs_config_for_user(self, retirement, user): - """ - Check to see if the user's info was sent to any partners (orgs) that have a a custom list of headings and - content for the partner report. If so, add this. - """ - # See if the MicroBachelors coaching provider needs to be notified of this user's retirement - if has_ever_consented_to_coaching is not None and has_ever_consented_to_coaching(user): - # See if the user has a MicroBachelors external id. If not, they were never sent to the - # coaching provider. - external_ids = ExternalId.objects.filter( - user=user, - external_id_type__name=ExternalIdType.MICROBACHELORS_COACHING - ) - if external_ids.exists(): - # User has an external id. Add the additional info. - external_id = str(external_ids[0].external_user_id) - self._add_coaching_orgs_config(retirement, external_id) - - def _add_coaching_orgs_config(self, retirement, external_id): - """ - Add the orgs configuration for MicroBachelors coaching - """ - # Add the custom field headings - retirement[AccountRetirementPartnerReportView.ORGS_CONFIG_KEY] = [ - { - AccountRetirementPartnerReportView.ORGS_CONFIG_ORG_KEY: 'mb_coaching', - AccountRetirementPartnerReportView.ORGS_CONFIG_FIELD_HEADINGS_KEY: [ - AccountRetirementPartnerReportView.STUDENT_ID_KEY, - AccountRetirementPartnerReportView.ORIGINAL_EMAIL_KEY, - AccountRetirementPartnerReportView.ORIGINAL_NAME_KEY, - AccountRetirementPartnerReportView.DELETION_COMPLETED_KEY - ] - } - ] - - # Add the custom field value - retirement[AccountRetirementPartnerReportView.STUDENT_ID_KEY] = external_id - @request_requires_username def retirement_partner_status_create(self, request): """