diff --git a/common/djangoapps/student/management/commands/bulk_change_enrollment.py b/common/djangoapps/student/management/commands/bulk_change_enrollment.py index b026af7ea4..f7cb6d6762 100644 --- a/common/djangoapps/student/management/commands/bulk_change_enrollment.py +++ b/common/djangoapps/student/management/commands/bulk_change_enrollment.py @@ -83,15 +83,19 @@ class Command(BaseCommand): course_key_str = unicode(course_key) try: + course_enrollments = CourseEnrollment.objects.filter(course_id=course_key, mode=from_mode) + logger.info( + 'Moving %d users from %s to %s in course %s.', + course_enrollments.count(), from_mode, to_mode, course_key_str + ) + if not commit: + logger.info('Dry run, changes have not been saved. Run again with "commit" argument to save changes') + raise Exception('The --commit flag was not given; forcing rollback.') with transaction.atomic(): - queryset = CourseEnrollment.objects.filter(course_id=course_key, mode=from_mode) - logger.info( - 'Moving %d users from %s to %s in course %s.', queryset.count(), from_mode, to_mode, course_key_str - ) - queryset.update(mode=to_mode) + # call `change_mode` which will change the mode and also emit tracking event + for enrollment in course_enrollments: + enrollment.change_mode(mode=to_mode) - if not commit: - raise Exception('The --commit flag was not given; forcing rollback.') - logger.info('Finished moving users from %s to %s in course %s.', from_mode, to_mode, course_key_str) + logger.info('Finished moving users from %s to %s in course %s.', from_mode, to_mode, course_key_str) except Exception: # pylint: disable=broad-except logger.info('No users moved.') diff --git a/common/djangoapps/student/management/tests/test_bulk_change_enrollment.py b/common/djangoapps/student/management/tests/test_bulk_change_enrollment.py index 696c9608aa..8897c40547 100644 --- a/common/djangoapps/student/management/tests/test_bulk_change_enrollment.py +++ b/common/djangoapps/student/management/tests/test_bulk_change_enrollment.py @@ -2,9 +2,10 @@ import ddt from django.core.management import call_command from django.core.management.base import CommandError +from mock import patch, call from student.tests.factories import UserFactory, CourseModeFactory, CourseEnrollmentFactory -from student.models import CourseEnrollment +from student.models import CourseEnrollment, EVENT_NAME_ENROLLMENT_MODE_CHANGED from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -18,9 +19,10 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase): self.course = CourseFactory.create() self.users = UserFactory.create_batch(5) + @patch('student.models.tracker') @ddt.data(('audit', 'honor'), ('honor', 'audit')) @ddt.unpack - def test_bulk_convert(self, from_mode, to_mode): + def test_bulk_convert(self, from_mode, to_mode, mock_tracker): """Verify that enrollments are changed correctly.""" self._enroll_users(from_mode) CourseModeFactory(course_id=self.course.id, mode_slug=to_mode) @@ -41,6 +43,16 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase): for user in self.users: CourseEnrollment.objects.get(mode=to_mode, course_id=self.course.id, user=user) + # Confirm the analytics event was emitted. + mock_tracker.emit.assert_has_calls( # pylint: disable=maybe-no-member + [ + call( + EVENT_NAME_ENROLLMENT_MODE_CHANGED, + {'course_id': unicode(self.course.id), 'user_id': user.id, 'mode': to_mode} + ), + ] + ) + def test_without_commit(self): """Verify that nothing happens when the `commit` flag is not given.""" self._enroll_users('audit')