def test_signal_update_dsc_cache_on_enterprise_customer_update(self): """ make sure update_dsc_cache_on_enterprise_customer_update signal clears data_sharing_consent_needed cache after enable_data_sharing_consent flag is changed. """ # Enrolling user to Course enterprise_customer = EnterpriseCustomerFactory() enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=self.user.id, enterprise_customer=enterprise_customer ) EnterpriseCourseEnrollmentFactory( course_id=self.course_id, enterprise_customer_user=enterprise_customer_user, ) self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) # updating enable_data_sharing_consent flag enterprise_customer.enable_data_sharing_consent = False enterprise_customer.save() self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id))
def setUp(self): UserFactory.create(username=TEST_ECOMMERCE_WORKER) self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() self.enterprise_customer_uuid = str(self.enterprise_customer.uuid) super().setUp()
def setUpClass(cls): super().setUpClass() cls.user = UserFactory() modulestore_course = ModuleStoreCourseFactory() course_run = CourseRunFactory(key=str(modulestore_course.id)) course = CourseFactory(course_runs=[course_run]) enterprise_customer = EnterpriseCustomerFactory(uuid=cls.enterprise_uuid) enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=cls.user.id, enterprise_customer=enterprise_customer ) CourseEnrollmentFactory( is_active=True, course_id=modulestore_course.id, user=cls.user ) EnterpriseCourseEnrollmentFactory( course_id=modulestore_course.id, enterprise_customer_user=enterprise_customer_user ) cls.program = ProgramFactory( uuid=cls.program_uuid, courses=[course], title='Journey to cooking', type='MicroMasters', authoring_organizations=[{ 'key': 'MAX', 'logo_image_url': 'http://test.org/media/organization/logos/test-logo.png' }], ) cls.site = SiteFactory(domain='test.localhost')
def test_register_user(self, mock_update_user): """ make sure marketing enterprise user call invokes update_user """ enterprise_customer = EnterpriseCustomerFactory() EnterpriseCustomerUserFactory(user_id=self.user.id, enterprise_customer=enterprise_customer) self.assertTrue(mock_update_user.called)
def test_register_user(self, mock_update_user): """ make sure marketing enterprise user call invokes update_user """ enterprise_customer = EnterpriseCustomerFactory() EnterpriseCustomerUserFactory(user_id=self.user.id, enterprise_customer=enterprise_customer) mock_update_user.assert_called_with(sailthru_vars={ 'is_enterprise_learner': True, 'enterprise_name': enterprise_customer.name, }, email=self.user.email)
def test_signal_update_dsc_cache_on_enterprise_customer_update(self): """ make sure update_dsc_cache_on_enterprise_customer_update signal clears data_sharing_consent_needed cache after enable_data_sharing_consent flag is changed. """ # Enrolling user to Course enterprise_customer = EnterpriseCustomerFactory() enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=self.user.id, enterprise_customer=enterprise_customer) EnterpriseCourseEnrollmentFactory( course_id=self.course_id, enterprise_customer_user=enterprise_customer_user, ) self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) # updating enable_data_sharing_consent flag enterprise_customer.enable_data_sharing_consent = False enterprise_customer.save() self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id))
def setUp(self): self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() super(EnterpriseSupportSignals, self).setUp()
class EnterpriseSupportSignals(TestCase): """ Tests for the enterprise support signals. """ def setUp(self): self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() super(EnterpriseSupportSignals, self).setUp() @staticmethod def _create_dsc_cache(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) TieredCache.set_all_tiers(consent_cache_key, 0) @staticmethod def _is_dsc_cache_found(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) return data_sharing_consent_needed_cache.is_found def _create_enterprise_enrollment(self, user_id, course_id): """ Create enterprise user and enrollment """ enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=user_id, enterprise_customer=self.enterprise_customer) EnterpriseCourseEnrollmentFactory( course_id=course_id, enterprise_customer_user=enterprise_customer_user, ) @patch('openedx.features.enterprise_support.signals.update_user.delay') def test_register_user(self, mock_update_user): """ make sure marketing enterprise user call invokes update_user """ self._create_enterprise_enrollment(self.user.id, self.course_id) mock_update_user.assert_called_with(sailthru_vars={ 'is_enterprise_learner': True, 'enterprise_name': self.enterprise_customer.name, }, email=self.user.email) def test_signal_update_dsc_cache_on_course_enrollment(self): """ make sure update_dsc_cache_on_course_enrollment signal clears cache when Enterprise Course Enrollment takes place """ self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) self._create_enterprise_enrollment(self.user.id, self.course_id) self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id)) def test_signal_update_dsc_cache_on_enterprise_customer_update(self): """ make sure update_dsc_cache_on_enterprise_customer_update signal clears data_sharing_consent_needed cache after enable_data_sharing_consent flag is changed. """ self._create_enterprise_enrollment(self.user.id, self.course_id) self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) # updating enable_data_sharing_consent flag self.enterprise_customer.enable_data_sharing_consent = False self.enterprise_customer.save() self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id)) def test_handle_enterprise_learner_passing_grade(self): """ Test to assert transmit_single_learner_data is called when COURSE_GRADE_NOW_PASSED signal is fired """ with patch( 'integrated_channels.integrated_channel.tasks.transmit_single_learner_data.apply_async', return_value=None) as mock_task_apply: course_key = CourseKey.from_string(self.course_id) COURSE_GRADE_NOW_PASSED.disconnect( dispatch_uid='new_passing_learner') COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) self.assertFalse(mock_task_apply.called) self._create_enterprise_enrollment(self.user.id, self.course_id) task_kwargs = { 'username': self.user.username, 'course_run_id': self.course_id } COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) mock_task_apply.assert_called_once_with(kwargs=task_kwargs) COURSE_GRADE_NOW_PASSED.connect(listen_for_passing_grade, dispatch_uid='new_passing_learner')
def test_full_pipeline_succeeds_for_unlinking_testshib_account( self, mock_get_enterprise_customer_for_learner_settings_view, mock_get_enterprise_customer_for_learner, mock_enterprise_customer_for_request, ): # First, create, the request and strategy that store pipeline state, # configure the backend, and mock out wire traffic. self.provider = self._configure_testshib_provider() request, strategy = self.get_request_and_strategy( auth_entry=pipeline.AUTH_ENTRY_LOGIN, redirect_uri='social:complete') request.backend.auth_complete = MagicMock( return_value=self.fake_auth_complete(strategy)) user = self.create_user_models_for_existing_account( strategy, '*****@*****.**', 'password', self.get_username()) self.assert_social_auth_exists_for_user(user, strategy) request.user = user # We're already logged in, so simulate that the cookie is set correctly self.set_logged_in_cookies(request) # linking a learner with enterprise customer. enterprise_customer = EnterpriseCustomerFactory() assert EnterpriseCustomerUser.objects.count( ) == 0, "Precondition check: no link records should exist" EnterpriseCustomerUser.objects.link_user(enterprise_customer, user.email) self.assertTrue( EnterpriseCustomerUser.objects.filter( enterprise_customer=enterprise_customer, user_id=user.id).count() == 1) EnterpriseCustomerIdentityProvider.objects.get_or_create( enterprise_customer=enterprise_customer, provider_id=self.provider.provider_id) enterprise_customer_data = { 'uuid': enterprise_customer.uuid, 'name': enterprise_customer.name, 'identity_provider': 'saml-default', } mock_enterprise_customer_for_request.return_value = enterprise_customer_data mock_get_enterprise_customer_for_learner.return_value = enterprise_customer_data mock_get_enterprise_customer_for_learner_settings_view.return_value = enterprise_customer_data # Instrument the pipeline to get to the dashboard with the full expected state. self.client.get( pipeline.get_login_url(self.provider.provider_id, pipeline.AUTH_ENTRY_LOGIN)) actions.do_complete( request.backend, social_views._do_login, # pylint: disable=protected-access request=request) with self._patch_edxmako_current_request(strategy.request): login_user(strategy.request) actions.do_complete( request.backend, social_views._do_login, user=user, # pylint: disable=protected-access request=request) # First we expect that we're in the linked state, with a backend entry. self.assert_account_settings_context_looks_correct( account_settings_context(request), linked=True) self.assert_social_auth_exists_for_user(request.user, strategy) FEATURES_WITH_ENTERPRISE_ENABLED = settings.FEATURES.copy() FEATURES_WITH_ENTERPRISE_ENABLED[ 'ENABLE_ENTERPRISE_INTEGRATION'] = True with patch.dict("django.conf.settings.FEATURES", FEATURES_WITH_ENTERPRISE_ENABLED): # Fire off the disconnect pipeline without the user information. actions.do_disconnect(request.backend, None, None, redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request) self.assertNotEqual( EnterpriseCustomerUser.objects.filter( enterprise_customer=enterprise_customer, user_id=user.id).count(), 0) # Fire off the disconnect pipeline to unlink. self.assert_redirect_after_pipeline_completes( actions.do_disconnect( request.backend, user, None, redirect_field_name=auth.REDIRECT_FIELD_NAME, request=request)) # Now we expect to be in the unlinked state, with no backend entry. self.assert_account_settings_context_looks_correct( account_settings_context(request), linked=False) self.assert_social_auth_does_not_exist_for_user(user, strategy) self.assertEqual( EnterpriseCustomerUser.objects.filter( enterprise_customer=enterprise_customer, user_id=user.id).count(), 0)
def test_fetch_enterprise_customer_by_id(self): the_uuid = uuid.uuid4() customer = EnterpriseCustomerFactory.create(uuid=the_uuid) assert customer == fetch_enterprise_customer_by_id(the_uuid)
class EnterpriseSupportSignals(SharedModuleStoreTestCase): """ Tests for the enterprise support signals. """ def setUp(self): UserFactory.create(username=TEST_ECOMMERCE_WORKER) self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() self.enterprise_customer_uuid = str(self.enterprise_customer.uuid) super().setUp() @staticmethod def _create_dsc_cache(user_id, course_id, enterprise_customer_uuid): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id, enterprise_customer_uuid) TieredCache.set_all_tiers(consent_cache_key, 0) @staticmethod def _is_dsc_cache_found(user_id, course_id, enterprise_customer_uuid): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id, enterprise_customer_uuid) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) return data_sharing_consent_needed_cache.is_found def _create_enterprise_enrollment(self, user_id, course_id): """ Create enterprise user and enrollment """ enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=user_id, enterprise_customer=self.enterprise_customer) EnterpriseCourseEnrollmentFactory( course_id=course_id, enterprise_customer_user=enterprise_customer_user, ) @patch('openedx.features.enterprise_support.signals.update_user.delay') def test_register_user(self, mock_update_user): """ make sure marketing enterprise user call invokes update_user """ self._create_enterprise_enrollment(self.user.id, self.course_id) mock_update_user.assert_called_with(sailthru_vars={ 'is_enterprise_learner': True, 'enterprise_name': self.enterprise_customer.name, }, email=self.user.email) def test_signal_update_dsc_cache_on_course_enrollment(self): """ make sure update_dsc_cache_on_course_enrollment signal clears cache when Enterprise Course Enrollment takes place """ self._create_dsc_cache(self.user.id, self.course_id, self.enterprise_customer_uuid) assert self._is_dsc_cache_found(self.user.id, self.course_id, self.enterprise_customer_uuid) self._create_enterprise_enrollment(self.user.id, self.course_id) assert not self._is_dsc_cache_found(self.user.id, self.course_id, self.enterprise_customer_uuid) def test_signal_update_dsc_cache_on_enterprise_customer_update(self): """ make sure update_dsc_cache_on_enterprise_customer_update signal clears data_sharing_consent_needed cache after enable_data_sharing_consent flag is changed. """ self._create_enterprise_enrollment(self.user.id, self.course_id) self._create_dsc_cache(self.user.id, self.course_id, self.enterprise_customer_uuid) assert self._is_dsc_cache_found(self.user.id, self.course_id, self.enterprise_customer_uuid) # updating enable_data_sharing_consent flag self.enterprise_customer.enable_data_sharing_consent = False self.enterprise_customer.save() assert not self._is_dsc_cache_found(self.user.id, self.course_id, self.enterprise_customer_uuid) def _create_enrollment_to_refund(self, no_of_days_placed=10, enterprise_enrollment_exists=True): """Create enrollment to refund. """ 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) return enrollment @ddt.data( (True, True, 2, False), # test if skip_refund (False, True, 20, False), # test refundable time passed (False, False, 2, False), # test not enterprise enrollment ( False, True, 2, True ), # success: no skip_refund, is enterprise enrollment and still in refundable window. ) @ddt.unpack def test_refund_order_voucher(self, skip_refund, enterprise_enrollment_exists, no_of_days_placed, api_called): """Test refund_order_voucher signal""" enrollment = self._create_enrollment_to_refund( no_of_days_placed, enterprise_enrollment_exists) 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) assert mock_ecommerce_api_client.called == api_called @ddt.data( (HttpClientError, 'INFO'), (HttpServerError, 'ERROR'), (Exception, 'ERROR'), ) @ddt.unpack def test_refund_order_voucher_with_client_errors(self, mock_error, log_level): """Test refund_order_voucher signal client_error""" enrollment = self._create_enrollment_to_refund() with patch( 'openedx.features.enterprise_support.signals.ecommerce_api_client' ) as mock_ecommerce_api_client: client_instance = mock_ecommerce_api_client.return_value client_instance.enterprise.coupons.create_refunded_voucher.post.side_effect = mock_error( ) with LogCapture(LOGGER_NAME) as logger: enrollment.update_enrollment(is_active=False) assert mock_ecommerce_api_client.called is True logger.check(( LOGGER_NAME, log_level, 'Encountered {} from ecommerce while creating refund voucher. ' 'Order=EDX-000000001, enrollment={}, user={}'.format( mock_error.__name__, enrollment, enrollment.user), )) def test_handle_enterprise_learner_passing_grade(self): """ Test to assert transmit_single_learner_data is called when COURSE_GRADE_NOW_PASSED signal is fired """ with patch( 'integrated_channels.integrated_channel.tasks.transmit_single_learner_data.apply_async', return_value=None) as mock_task_apply: course_key = CourseKey.from_string(self.course_id) COURSE_GRADE_NOW_PASSED.disconnect( dispatch_uid='new_passing_learner') COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) assert not mock_task_apply.called self._create_enterprise_enrollment(self.user.id, self.course_id) task_kwargs = { 'username': self.user.username, 'course_run_id': self.course_id } COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) mock_task_apply.assert_called_once_with(kwargs=task_kwargs) COURSE_GRADE_NOW_PASSED.connect(listen_for_passing_grade, dispatch_uid='new_passing_learner') def test_handle_enterprise_learner_subsection(self): """ Test to assert transmit_subsection_learner_data is called when COURSE_ASSESSMENT_GRADE_CHANGED signal is fired. """ with patch( 'integrated_channels.integrated_channel.tasks.transmit_single_subsection_learner_data.apply_async', return_value=None) as mock_task_apply: course_key = CourseKey.from_string(self.course_id) COURSE_ASSESSMENT_GRADE_CHANGED.disconnect() COURSE_ASSESSMENT_GRADE_CHANGED.send(sender=None, user=self.user, course_id=course_key, subsection_id='subsection_id', subsection_grade=1.0) assert not mock_task_apply.called self._create_enterprise_enrollment(self.user.id, self.course_id) task_kwargs = { 'username': self.user.username, 'course_run_id': self.course_id, 'subsection_id': 'subsection_id', 'grade': '1.0' } COURSE_ASSESSMENT_GRADE_CHANGED.send(sender=None, user=self.user, course_id=course_key, subsection_id='subsection_id', subsection_grade=1.0) mock_task_apply.assert_called_once_with(kwargs=task_kwargs) COURSE_ASSESSMENT_GRADE_CHANGED.connect(listen_for_passing_grade)
def setUp(self): UserFactory.create(username=TEST_ECOMMERCE_WORKER) self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() super(EnterpriseSupportSignals, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
class EnterpriseSupportSignals(SharedModuleStoreTestCase): """ Tests for the enterprise support signals. """ def setUp(self): UserFactory.create(username=TEST_ECOMMERCE_WORKER) self.user = UserFactory.create(username='******', email=TEST_EMAIL) self.course_id = 'course-v1:edX+DemoX+Demo_Course' self.enterprise_customer = EnterpriseCustomerFactory() super(EnterpriseSupportSignals, self).setUp() @staticmethod def _create_dsc_cache(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) TieredCache.set_all_tiers(consent_cache_key, 0) @staticmethod def _is_dsc_cache_found(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) return data_sharing_consent_needed_cache.is_found def _create_enterprise_enrollment(self, user_id, course_id): """ Create enterprise user and enrollment """ enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=user_id, enterprise_customer=self.enterprise_customer) EnterpriseCourseEnrollmentFactory( course_id=course_id, enterprise_customer_user=enterprise_customer_user, ) @patch('openedx.features.enterprise_support.signals.update_user.delay') def test_register_user(self, mock_update_user): """ make sure marketing enterprise user call invokes update_user """ self._create_enterprise_enrollment(self.user.id, self.course_id) mock_update_user.assert_called_with(sailthru_vars={ 'is_enterprise_learner': True, 'enterprise_name': self.enterprise_customer.name, }, email=self.user.email) def test_signal_update_dsc_cache_on_course_enrollment(self): """ make sure update_dsc_cache_on_course_enrollment signal clears cache when Enterprise Course Enrollment takes place """ self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) self._create_enterprise_enrollment(self.user.id, self.course_id) self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id)) def test_signal_update_dsc_cache_on_enterprise_customer_update(self): """ make sure update_dsc_cache_on_enterprise_customer_update signal clears data_sharing_consent_needed cache after enable_data_sharing_consent flag is changed. """ self._create_enterprise_enrollment(self.user.id, self.course_id) self._create_dsc_cache(self.user.id, self.course_id) self.assertTrue(self._is_dsc_cache_found(self.user.id, self.course_id)) # updating enable_data_sharing_consent flag self.enterprise_customer.enable_data_sharing_consent = False self.enterprise_customer.save() self.assertFalse(self._is_dsc_cache_found(self.user.id, self.course_id)) @ddt.data( (True, True, 2, False), # test if skip_refund (False, True, 20, False), # test refundable time passed (False, False, 2, False), # test not enterprise enrollment ( False, True, 2, True ), # success: no skip_refund, is enterprise enrollment and still in refundable window. ) @ddt.unpack 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) def test_handle_enterprise_learner_passing_grade(self): """ Test to assert transmit_single_learner_data is called when COURSE_GRADE_NOW_PASSED signal is fired """ with patch( 'integrated_channels.integrated_channel.tasks.transmit_single_learner_data.apply_async', return_value=None) as mock_task_apply: course_key = CourseKey.from_string(self.course_id) COURSE_GRADE_NOW_PASSED.disconnect( dispatch_uid='new_passing_learner') COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) self.assertFalse(mock_task_apply.called) self._create_enterprise_enrollment(self.user.id, self.course_id) task_kwargs = { 'username': self.user.username, 'course_run_id': self.course_id } COURSE_GRADE_NOW_PASSED.send(sender=None, user=self.user, course_id=course_key) mock_task_apply.assert_called_once_with(kwargs=task_kwargs) COURSE_GRADE_NOW_PASSED.connect(listen_for_passing_grade, dispatch_uid='new_passing_learner')