def test_refund_order_voucher(self, skip_refund, enterprise_enrollment_exists, no_of_days_placed, api_called): """Test refund_order_voucher signal""" # import pdb; pdb.set_trace() date_placed = now() - timedelta(days=no_of_days_placed) course = CourseFactory.create(display_name='test course', run="Testing_course", start=date_placed) enrollment = CourseEnrollmentFactory( course_id=course.id, user=self.user, mode="verified", ) CourseModeFactory.create(course_id=course.id, mode_slug='verified') CourseEnrollmentAttribute.objects.create( enrollment=enrollment, name='date_placed', namespace='order', value=date_placed.strftime(ECOMMERCE_DATE_FORMAT)) CourseEnrollmentAttribute.objects.create(enrollment=enrollment, name='order_number', namespace='order', value='EDX-000000001') if enterprise_enrollment_exists: self._create_enterprise_enrollment(self.user.id, course.id) with patch( 'openedx.features.enterprise_support.signals.ecommerce_api_client' ) as mock_ecommerce_api_client: enrollment.update_enrollment(is_active=False, skip_refund=skip_refund) self.assertEqual(mock_ecommerce_api_client.called, api_called)
class TestMoveToVerified(SharedModuleStoreTestCase): """ Tests for the post-save listener. """ @classmethod def setUpClass(cls): super(TestMoveToVerified, cls).setUpClass() cls.course = CourseFactory.create() def setUp(self): self.user = UserFactory() # Spy on number of calls to celery task. celery_task_patcher = patch.object( sync_cohort_with_mode, 'apply_async', mock.Mock(wraps=sync_cohort_with_mode.apply_async)) self.mocked_celery_task = celery_task_patcher.start() self.addCleanup(celery_task_patcher.stop) def _enable_cohorting(self): set_course_cohort_settings(self.course.id, is_cohorted=True) def _create_verified_cohort(self): add_cohort(self.course.id, VERIFIED_COHORT_NAME, CourseCohort.MANUAL) def _enable_verified_track_cohorting(self): """ Enable verified track cohorting for the default course. """ config = VerifiedTrackCohortedCourse.objects.create( course_key=self.course.id, enabled=True) config.save() def _enroll_in_course(self): self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user) def _upgrade_to_verified(self): """ Upgrade the default enrollment to verified. """ self.enrollment.update_enrollment(mode=CourseMode.VERIFIED) def _verify_no_automatic_cohorting(self): self._enroll_in_course() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self._upgrade_to_verified() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self.assertEqual(0, self.mocked_celery_task.call_count) def _unenroll(self): self.enrollment.unenroll(self.user, self.course.id) def _reenroll(self): self.enrollment.activate() self.enrollment.change_mode(CourseMode.AUDIT) @mock.patch('verified_track_content.models.log.error') def test_automatic_cohorting_disabled(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is disabled for a course, enrollment mode changes do not move learners into a cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # But do not enable the verified track cohorting feature. self.assertFalse( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() # No logging occurs if feature is disabled for course. self.assertFalse(error_logger.called) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_course_not_cohorted(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, but the course is not cohorted, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable verified track cohorting feature, but course has not been marked as cohorting. self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) self.assertIn("course is not cohorted", error_logger.call_args[0][0]) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_missing_verified_cohort(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course and the course is cohorted, but the course does not have a verified cohort, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable cohorting, but do not create the verified cohort. self._enable_cohorting() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) self.assertIn("course does not have a verified cohort", error_logger.call_args[0][0]) def test_automatic_cohorting_enabled(self): """ If the VerifiedTrackCohortedCourse feature is enabled for a course (with course cohorting enabled with an existing verified cohort), enrollment in the verified track automatically moves learners into the verified cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._enroll_in_course() self.assertEqual(2, self.mocked_celery_task.call_count) self.assertEqual( DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual(4, self.mocked_celery_task.call_count) self.assertEqual( VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_unenrolled(self): """ Test that un-enrolling and re-enrolling works correctly. This is important because usually learners maintain their previously assigned cohort on re-enrollment. """ # Enable verified track cohorting feature and enroll in the verified track self._enable_cohorting() self._create_verified_cohort() self._enable_verified_track_cohorting() self._enroll_in_course() self._upgrade_to_verified() self.assertEqual( VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course and then re-enroll self._unenroll() self.assertEqual( VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._reenroll() self.assertEqual( DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual( VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name)
class TestMoveToVerified(SharedModuleStoreTestCase): """ Tests for the post-save listener. """ @classmethod def setUpClass(cls): super(TestMoveToVerified, cls).setUpClass() cls.course = CourseFactory.create() def setUp(self): super(TestMoveToVerified, self).setUp() self.user = UserFactory() # Spy on number of calls to celery task. celery_task_patcher = patch.object( sync_cohort_with_mode, 'apply_async', mock.Mock(wraps=sync_cohort_with_mode.apply_async)) self.mocked_celery_task = celery_task_patcher.start() self.addCleanup(celery_task_patcher.stop) def _enable_cohorting(self): set_course_cohort_settings(self.course.id, is_cohorted=True) def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME): add_cohort(self.course.id, name, CourseCohort.MANUAL) def _create_named_random_cohort(self, name): return add_cohort(self.course.id, name, CourseCohort.RANDOM) def _enable_verified_track_cohorting(self, cohort_name=None): """ Enable verified track cohorting for the default course. """ if cohort_name: config = VerifiedTrackCohortedCourse.objects.create( course_key=self.course.id, enabled=True, verified_cohort_name=cohort_name) else: config = VerifiedTrackCohortedCourse.objects.create( course_key=self.course.id, enabled=True) config.save() def _enroll_in_course(self): self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user) def _upgrade_to_verified(self): """ Upgrade the default enrollment to verified. """ self.enrollment.update_enrollment(mode=CourseMode.VERIFIED) def _verify_no_automatic_cohorting(self): self._enroll_in_course() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self._upgrade_to_verified() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self.assertEqual(0, self.mocked_celery_task.call_count) def _unenroll(self): self.enrollment.unenroll(self.user, self.course.id) def _reenroll(self): self.enrollment.activate() self.enrollment.change_mode(CourseMode.AUDIT) @mock.patch('verified_track_content.models.log.error') def test_automatic_cohorting_disabled(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is disabled for a course, enrollment mode changes do not move learners into a cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # But do not enable the verified track cohorting feature. self.assertFalse( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() # No logging occurs if feature is disabled for course. self.assertFalse(error_logger.called) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_course_not_cohorted(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, but the course is not cohorted, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable verified track cohorting feature, but course has not been marked as cohorting. self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) self.assertIn("course is not cohorted", error_logger.call_args[0][0]) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_missing_verified_cohort(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course and the course is cohorted, but the course does not have a verified cohort, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable cohorting, but do not create the verified cohort. self._enable_cohorting() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) error_message = "cohort named '%s' does not exist" self.assertIn(error_message, error_logger.call_args[0][0]) def test_automatic_cohorting_enabled(self): """ If the VerifiedTrackCohortedCourse feature is enabled for a course (with course cohorting enabled with an existing verified cohort), enrollment in the verified track automatically moves learners into the verified cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue( VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled( self.course.id)) self._enroll_in_course() self.assertEqual(2, self.mocked_celery_task.call_count) self.assertEqual( DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual(4, self.mocked_celery_task.call_count) self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_cohorting_enabled_multiple_random_cohorts(self): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, and the course is cohorted with > 1 random cohorts, the learner is randomly assigned to one of the random cohorts when in the audit track. """ # Enable cohorting, and create the verified cohort. self._enable_cohorting() self._create_verified_cohort() # Create two random cohorts. self._create_named_random_cohort("Random 1") self._create_named_random_cohort("Random 2") # Enable verified track cohorting feature self._enable_verified_track_cohorting() self._enroll_in_course() self.assertIn( get_cohort(self.user, self.course.id, assign=False).name, ["Random 1", "Random 2"]) self._upgrade_to_verified() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._unenroll() self._reenroll() self.assertIn( get_cohort(self.user, self.course.id, assign=False).name, ["Random 1", "Random 2"]) def test_unenrolled(self): """ Test that un-enrolling and re-enrolling works correctly. This is important because usually learners maintain their previously assigned cohort on re-enrollment. """ # Enable verified track cohorting feature and enroll in the verified track self._enable_cohorting() self._create_verified_cohort() self._enable_verified_track_cohorting() self._enroll_in_course() self._upgrade_to_verified() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course and then re-enroll self._unenroll() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._reenroll() self.assertEqual( DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_custom_verified_cohort_name(self): """ Test that enrolling in verified works correctly when the "verified cohort" has a custom name. """ custom_cohort_name = 'special verified cohort' self._enable_cohorting() self._create_verified_cohort(name=custom_cohort_name) self._enable_verified_track_cohorting(cohort_name=custom_cohort_name) self._enroll_in_course() self._upgrade_to_verified() self.assertEqual( custom_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) def test_custom_default_cohort_name(self): """ Test that enrolling and un-enrolling works correctly when the single cohort of type random has a different name from "Default Group". """ random_cohort_name = "custom random cohort" self._enable_cohorting() self._create_verified_cohort() default_cohort = self._create_named_random_cohort(random_cohort_name) self._enable_verified_track_cohorting() self._enroll_in_course() self.assertEqual( random_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course. The learner stays in the verified cohort, but is no longer active. self._unenroll() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Change the name of the "default" cohort. modified_cohort_name = "renamed random cohort" default_cohort.name = modified_cohort_name default_cohort.save() # Re-enroll in the course, which will downgrade the learner to audit. self._reenroll() self.assertEqual( modified_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual( DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name)
class TestMoveToVerified(SharedModuleStoreTestCase): """ Tests for the post-save listener. """ @classmethod def setUpClass(cls): super(TestMoveToVerified, cls).setUpClass() cls.course = CourseFactory.create() def setUp(self): super(TestMoveToVerified, self).setUp() self.user = UserFactory() # Spy on number of calls to celery task. celery_task_patcher = mock.patch.object( sync_cohort_with_mode, 'apply_async', mock.Mock(wraps=sync_cohort_with_mode.apply_async) ) self.mocked_celery_task = celery_task_patcher.start() self.addCleanup(celery_task_patcher.stop) def _enable_cohorting(self): """ Turn on cohorting in the course. """ set_course_cohorted(self.course.id, True) def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME): """ Create a verified cohort. """ add_cohort(self.course.id, name, CourseCohort.MANUAL) def _create_named_random_cohort(self, name): """ Create a random cohort with the supplied name. """ return add_cohort(self.course.id, name, CourseCohort.RANDOM) def _enable_verified_track_cohorting(self, cohort_name=None): """ Enable verified track cohorting for the default course. """ if cohort_name: config = VerifiedTrackCohortedCourse.objects.create( course_key=self.course.id, enabled=True, verified_cohort_name=cohort_name ) else: config = VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True) config.save() def _enroll_in_course(self): """ Enroll self.user in self.course. """ self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user) def _upgrade_enrollment(self, mode=CourseMode.VERIFIED): """ Upgrade the default enrollment to verified. """ self.enrollment.update_enrollment(mode=mode) def _verify_no_automatic_cohorting(self): """ Check that upgrading self.user to verified does not move them into a cohort. """ self._enroll_in_course() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self._upgrade_enrollment() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self.assertEqual(0, self.mocked_celery_task.call_count) def _unenroll(self): """ Unenroll self.user from self.course. """ self.enrollment.unenroll(self.user, self.course.id) def _reenroll(self): """ Re-enroll the learner into mode AUDIT. """ self.enrollment.activate() self.enrollment.change_mode(CourseMode.AUDIT) @mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error') def test_automatic_cohorting_disabled(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is disabled for a course, enrollment mode changes do not move learners into a cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # But do not enable the verified track cohorting feature. self.assertFalse(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() # No logging occurs if feature is disabled for course. self.assertFalse(error_logger.called) @mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error') def test_cohorting_enabled_course_not_cohorted(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, but the course is not cohorted, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable verified track cohorting feature, but course has not been marked as cohorting. self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) self.assertIn("course is not cohorted", error_logger.call_args[0][0]) @mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error') def test_cohorting_enabled_missing_verified_cohort(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course and the course is cohorted, but the course does not have a verified cohort, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable cohorting, but do not create the verified cohort. self._enable_cohorting() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) error_message = u"cohort named '%s' does not exist" self.assertIn(error_message, error_logger.call_args[0][0]) @ddt.data(CourseMode.VERIFIED, CourseMode.CREDIT_MODE) def test_automatic_cohorting_enabled(self, upgrade_mode): """ If the VerifiedTrackCohortedCourse feature is enabled for a course (with course cohorting enabled with an existing verified cohort), enrollment in the verified track automatically moves learners into the verified cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._enroll_in_course() self.assertEqual(2, self.mocked_celery_task.call_count) self.assertEqual(DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_enrollment(upgrade_mode) self.assertEqual(4, self.mocked_celery_task.call_count) self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_cohorting_enabled_multiple_random_cohorts(self): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, and the course is cohorted with > 1 random cohorts, the learner is randomly assigned to one of the random cohorts when in the audit track. """ # Enable cohorting, and create the verified cohort. self._enable_cohorting() self._create_verified_cohort() # Create two random cohorts. self._create_named_random_cohort("Random 1") self._create_named_random_cohort("Random 2") # Enable verified track cohorting feature self._enable_verified_track_cohorting() self._enroll_in_course() self.assertIn(get_cohort(self.user, self.course.id, assign=False).name, ["Random 1", "Random 2"]) self._upgrade_enrollment() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._unenroll() self._reenroll() self.assertIn(get_cohort(self.user, self.course.id, assign=False).name, ["Random 1", "Random 2"]) def test_unenrolled(self): """ Test that un-enrolling and re-enrolling works correctly. This is important because usually learners maintain their previously assigned cohort on re-enrollment. """ # Enable verified track cohorting feature and enroll in the verified track self._enable_cohorting() self._create_verified_cohort() self._enable_verified_track_cohorting() self._enroll_in_course() self._upgrade_enrollment() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course and then re-enroll self._unenroll() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._reenroll() self.assertEqual(DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_enrollment() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_custom_verified_cohort_name(self): """ Test that enrolling in verified works correctly when the "verified cohort" has a custom name. """ custom_cohort_name = 'special verified cohort' self._enable_cohorting() self._create_verified_cohort(name=custom_cohort_name) self._enable_verified_track_cohorting(cohort_name=custom_cohort_name) self._enroll_in_course() self._upgrade_enrollment() self.assertEqual(custom_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) def test_custom_default_cohort_name(self): """ Test that enrolling and un-enrolling works correctly when the single cohort of type random has a different name from "Default Group". """ random_cohort_name = "custom random cohort" self._enable_cohorting() self._create_verified_cohort() default_cohort = self._create_named_random_cohort(random_cohort_name) self._enable_verified_track_cohorting() self._enroll_in_course() self.assertEqual(random_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_enrollment() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course. The learner stays in the verified cohort, but is no longer active. self._unenroll() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Change the name of the "default" cohort. modified_cohort_name = "renamed random cohort" default_cohort.name = modified_cohort_name default_cohort.save() # Re-enroll in the course, which will downgrade the learner to audit. self._reenroll() self.assertEqual(modified_cohort_name, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_enrollment() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name)
class TestMoveToVerified(SharedModuleStoreTestCase): """ Tests for the post-save listener. """ @classmethod def setUpClass(cls): super(TestMoveToVerified, cls).setUpClass() cls.course = CourseFactory.create() def setUp(self): self.user = UserFactory() # Spy on number of calls to celery task. celery_task_patcher = patch.object( sync_cohort_with_mode, 'apply_async', mock.Mock(wraps=sync_cohort_with_mode.apply_async) ) self.mocked_celery_task = celery_task_patcher.start() self.addCleanup(celery_task_patcher.stop) def _enable_cohorting(self): set_course_cohort_settings(self.course.id, is_cohorted=True) def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME): add_cohort(self.course.id, name, CourseCohort.MANUAL) def _enable_verified_track_cohorting(self, cohort_name=None): """ Enable verified track cohorting for the default course. """ if cohort_name: config = VerifiedTrackCohortedCourse.objects.create( course_key=self.course.id, enabled=True, verified_cohort_name=cohort_name ) else: config = VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True) config.save() def _enroll_in_course(self): self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user) def _upgrade_to_verified(self): """ Upgrade the default enrollment to verified. """ self.enrollment.update_enrollment(mode=CourseMode.VERIFIED) def _verify_no_automatic_cohorting(self): self._enroll_in_course() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self._upgrade_to_verified() self.assertIsNone(get_cohort(self.user, self.course.id, assign=False)) self.assertEqual(0, self.mocked_celery_task.call_count) def _unenroll(self): self.enrollment.unenroll(self.user, self.course.id) def _reenroll(self): self.enrollment.activate() self.enrollment.change_mode(CourseMode.AUDIT) @mock.patch('verified_track_content.models.log.error') def test_automatic_cohorting_disabled(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is disabled for a course, enrollment mode changes do not move learners into a cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # But do not enable the verified track cohorting feature. self.assertFalse(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() # No logging occurs if feature is disabled for course. self.assertFalse(error_logger.called) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_course_not_cohorted(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course, but the course is not cohorted, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable verified track cohorting feature, but course has not been marked as cohorting. self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) self.assertIn("course is not cohorted", error_logger.call_args[0][0]) @mock.patch('verified_track_content.models.log.error') def test_cohorting_enabled_missing_verified_cohort(self, error_logger): """ If the VerifiedTrackCohortedCourse feature is enabled for a course and the course is cohorted, but the course does not have a verified cohort, an error is logged and enrollment mode changes do not move learners into a cohort. """ # Enable cohorting, but do not create the verified cohort. self._enable_cohorting() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._verify_no_automatic_cohorting() self.assertTrue(error_logger.called) error_message = "cohort named '%s' does not exist" self.assertIn(error_message, error_logger.call_args[0][0]) def test_automatic_cohorting_enabled(self): """ If the VerifiedTrackCohortedCourse feature is enabled for a course (with course cohorting enabled with an existing verified cohort), enrollment in the verified track automatically moves learners into the verified cohort. """ # Enable cohorting and create a verified cohort. self._enable_cohorting() self._create_verified_cohort() # Enable verified track cohorting feature self._enable_verified_track_cohorting() self.assertTrue(VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)) self._enroll_in_course() self.assertEqual(2, self.mocked_celery_task.call_count) self.assertEqual(DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual(4, self.mocked_celery_task.call_count) self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_unenrolled(self): """ Test that un-enrolling and re-enrolling works correctly. This is important because usually learners maintain their previously assigned cohort on re-enrollment. """ # Enable verified track cohorting feature and enroll in the verified track self._enable_cohorting() self._create_verified_cohort() self._enable_verified_track_cohorting() self._enroll_in_course() self._upgrade_to_verified() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) # Un-enroll from the course and then re-enroll self._unenroll() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._reenroll() self.assertEqual(DEFAULT_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) self._upgrade_to_verified() self.assertEqual(DEFAULT_VERIFIED_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name) def test_custom_verified_cohort_name(self): CUSTOM_COHORT_NAME = 'special verified cohort' self._enable_cohorting() self._create_verified_cohort(name=CUSTOM_COHORT_NAME) self._enable_verified_track_cohorting(cohort_name=CUSTOM_COHORT_NAME) self._enroll_in_course() self._upgrade_to_verified() self.assertEqual(CUSTOM_COHORT_NAME, get_cohort(self.user, self.course.id, assign=False).name)