diff --git a/common/djangoapps/student/models.py b/common/djangoapps/student/models.py index e24b76750d1cc1fefbd004c206d7aa65058e42e3..58279203ce829665ee8e47964bcc1369c50cb3d3 100644 --- a/common/djangoapps/student/models.py +++ b/common/djangoapps/student/models.py @@ -2091,7 +2091,7 @@ class ManualEnrollmentAudit(models.Model): return manual_enrollment -class CourseEnrollmentAllowed(models.Model): +class CourseEnrollmentAllowed(DeletableByUserValue, models.Model): """ Table of users (specified by email address strings) who are allowed to enroll in a specified course. The user may or may not (yet) exist. Enrollment by users listed in this table is allowed diff --git a/common/djangoapps/student/tests/test_models.py b/common/djangoapps/student/tests/test_models.py index ba5fc47db21acf6cb4eac147853d99e561c0b696..93f1d4bb3e009ffb034e4d57dc202fe9e8ae64cc 100644 --- a/common/djangoapps/student/tests/test_models.py +++ b/common/djangoapps/student/tests/test_models.py @@ -10,15 +10,17 @@ from django.contrib.auth.models import AnonymousUser from django.core.cache import cache from django.db.models import signals from django.db.models.functions import Lower +from django.test import TestCase from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory from courseware.models import DynamicUpgradeDeadlineConfiguration +from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.schedules.models import Schedule from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory from openedx.core.djangolib.testing.utils import skip_unless_lms -from student.models import CourseEnrollment, PendingEmailChange +from student.models import CourseEnrollment, CourseEnrollmentAllowed, PendingEmailChange from student.tests.factories import CourseEnrollmentFactory, UserFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -226,3 +228,39 @@ class PendingEmailChangeTests(SharedModuleStoreTestCase): record_was_deleted = PendingEmailChange.delete_by_user_value(self.user2, field='user') self.assertFalse(record_was_deleted) self.assertEqual(1, len(PendingEmailChange.objects.all())) + + +class TestCourseEnrollmentAllowed(TestCase): + + def setUp(self): + super(TestCourseEnrollmentAllowed, self).setUp() + self.email = 'learner@example.com' + self.course_key = CourseKey.from_string("course-v1:edX+DemoX+Demo_Course") + self.user = UserFactory.create() + self.allowed_enrollment = CourseEnrollmentAllowed.objects.create( + email=self.email, + course_id=self.course_key, + user=self.user + ) + + def test_retiring_user_deletes_record(self): + is_successful = CourseEnrollmentAllowed.delete_by_user_value( + value=self.email, + field='email' + ) + self.assertTrue(is_successful) + user_search_results = CourseEnrollmentAllowed.objects.filter( + email=self.email + ) + self.assertFalse(user_search_results) + + def test_retiring_nonexistent_user_doesnt_modify_records(self): + is_successful = CourseEnrollmentAllowed.delete_by_user_value( + value='nonexistentlearner@example.com', + field='email' + ) + self.assertFalse(is_successful) + user_search_results = CourseEnrollmentAllowed.objects.filter( + email=self.email + ) + self.assertTrue(user_search_results.exists()) diff --git a/openedx/core/djangolib/model_mixins.py b/openedx/core/djangolib/model_mixins.py index 5ceefb67dc432f4df44c39ab28ae1717d08dde1e..50627170e3385dbe72230047d11d9005c84ba7cd 100644 --- a/openedx/core/djangolib/model_mixins.py +++ b/openedx/core/djangolib/model_mixins.py @@ -17,7 +17,7 @@ class DeprecatedModelMixin(object): class DeletableByUserValue(object): """ This mixin allows inheriting models to delete instances of the model - associated with some user. + associated with some specified user. """ @classmethod