def setUp(self): self.api_user = UserFactory(username='******') self.user = UserFactory() self.course_id = COURSE_ID self.enterprise_customer = EnterpriseCustomerFactory() self.identity_provider = FakerFactory.create().slug() EnterpriseCustomerIdentityProviderFactory( provider_id=self.identity_provider, enterprise_customer=self.enterprise_customer) self.enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=self.user.id, enterprise_customer=self.enterprise_customer, ) self.enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) self.integrated_channel = SAPSuccessFactorsEnterpriseCustomerConfiguration( enterprise_customer=self.enterprise_customer, sapsf_base_url='enterprise.successfactors.com', key='key', secret='secret', ) super(TestTransmitLearnerData, self).setUp()
def test_learner_data_self_paced_course(self, passing, end_date, expected_completion, expected_grade, mock_course_api, mock_grades_api): enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) # Mock self-paced course details mock_course_api.return_value.get_course_details.return_value = dict( pacing='self', end=end_date.isoformat() if end_date else None, ) # Mock grades data mock_grades_api.return_value.get_course_grade.return_value = dict( passed=passing, ) # Collect the learner data, with time set to NOW with freeze_time(self.NOW): learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 1 assert learner_data[0].enterprise_course_enrollment_id == enrollment.id assert learner_data[0].course_id == self.course_id assert learner_data[0].course_completed == (passing and expected_completion is not None) assert learner_data[0].completed_timestamp == expected_completion assert learner_data[0].grade == expected_grade
def test_learner_data_instructor_paced_w_certificate( self, mock_certificate_api, mock_course_api): enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) # Return a mock certificate certificate = dict( username=self.user, course_id=self.course_id, certificate_type='professional', created_date=self.NOW.isoformat(), status="downloadable", is_passing=True, grade='A-', ) mock_certificate_api.return_value.get_course_certificate.return_value = certificate # Return instructor-paced course details mock_course_api.return_value.get_course_details.return_value = dict( pacing='instructor', ) learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 1 assert learner_data[0].enterprise_course_enrollment_id == enrollment.id assert learner_data[0].course_id == self.course_id assert learner_data[0].course_completed assert learner_data[0].completed_timestamp == self.NOW_TIMESTAMP assert learner_data[0].grade == BaseLearnerExporter.GRADE_PASSING
def test_collect_learner_data_without_consent(self): EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=False, ) learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 0
def setUp(self): super().setUp() self.course_ids = [ 'course-v1:edX+DemoX+Demo_Course', 'course-v1:edX+Python+1T2019', 'course-v1:edX+React+2T2019', ] self.enterprise_customer = EnterpriseCustomerFactory( name='Starfleet Academy', enable_data_sharing_consent=True, enforce_data_sharing_consent='at_enrollment', ) learners = [] for __ in range(5): user = UserFactory.create(is_staff=False, is_active=True) learners.append(user) self.learners_data = [] for learner in learners: course_id = random.choice(self.course_ids) self.learners_data.append({ 'ENTERPRISE_UUID': self.enterprise_customer.uuid, 'EMAIL': learner.email, 'USERNAME': learner.username, 'USER_ID': learner.id, 'COURSE_ID': course_id }) enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=learner.id, enterprise_customer=self.enterprise_customer) EnterpriseCourseEnrollmentFactory( enterprise_customer_user=enterprise_customer_user, course_id=course_id, ) self.existing_dsc_record_count = 2 # create consent records for some learners with `granted` set to `False` # this is needed to verify that command is working for existing DSC records for learner in self.learners_data[:self.existing_dsc_record_count]: DataSharingConsentFactory( username=learner['USERNAME'], course_id=learner['COURSE_ID'], enterprise_customer=self.enterprise_customer, granted=False)
def test_collect_learner_data_no_course_details(self, mock_course_api): EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) # Return no course details mock_course_api.return_value.get_course_details.return_value = None learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 0
def test_transmit_learner_data(self, mock_course_api, mock_certificate, mock_transmitter, mock_sap_client): user = UserFactory() course_id = 'course-v1:edX+DemoX+DemoCourse' enterprise_customer_user = EnterpriseCustomerUserFactory( user_id=user.id, enterprise_customer=self.enterprise_customer, ) enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=enterprise_customer_user, course_id=course_id, consent_granted=True, ) # Mock instructor-paced course details mock_course_api.return_value.get_course_details.return_value = dict( pacing='instructor' ) # Return a mock certificate certificate = dict( user=user, course_id=course_id, grade="A-", is_passing=True, created_date='2017-01-02T03:04:05:00Z' ) mock_certificate.return_value.get_course_certificate.return_value = certificate transmission_audit = LearnerDataTransmissionAudit( enterprise_course_enrollment_id=enrollment.id, sapsf_user_id=None, course_id=enrollment.course_id, course_completed=True, completed_timestamp=1483326245000, grade='A-', ) mock_sap_client.get_oauth_access_token.return_value = "token", datetime.datetime.utcnow() mock_transmitter_instance = mock_transmitter.return_value mock_transmitter.transmit.return_value = transmission_audit # Ensure an inactive config doesn't transmit anything. self.config.transmit_learner_data('dummy-user') assert not mock_transmitter_instance.transmit.called # Test that an active config transmits the expected data record self.config.active = True self.config.transmit_learner_data('dummy-user') assert mock_transmitter_instance.transmit.called_with(transmission_audit)
def test_learner_data_instructor_paced_no_certificate( self, mock_certificate_api, mock_course_api): enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) # Raise 404 - no certificate found mock_certificate_api.return_value.get_course_certificate.side_effect = HttpNotFoundError # Return instructor-paced course details mock_course_api.return_value.get_course_details.return_value = dict( pacing='instructor', ) learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 1 assert learner_data[0].enterprise_course_enrollment_id == enrollment.id assert learner_data[0].course_id == self.course_id assert not learner_data[0].course_completed assert learner_data[0].completed_timestamp is None assert learner_data[0].grade == BaseLearnerExporter.GRADE_INCOMPLETE
def test_learner_data_self_paced_no_grades(self, mock_course_api, mock_grades_api): enrollment = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) # Return instructor-paced course details mock_course_api.return_value.get_course_details.return_value = dict( pacing='self', ) # Mock grades data not found mock_grades_api.return_value.get_course_grade.side_effect = HttpNotFoundError learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 1 assert learner_data[0].enterprise_course_enrollment_id == enrollment.id assert learner_data[0].course_id == self.course_id assert not learner_data[0].course_completed assert learner_data[0].completed_timestamp is None assert learner_data[0].grade is None
def test_learner_data_multiple_courses(self, pacing, grade, mock_course_api, mock_grades_api, mock_certificate_api): enrollment1 = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=self.course_id, consent_granted=True, ) course_id2 = 'course-v1:edX+DemoX+DemoCourse2' enrollment2 = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=self.enterprise_customer_user, course_id=course_id2, consent_granted=True, ) enrollment3 = EnterpriseCourseEnrollmentFactory( enterprise_customer_user=EnterpriseCustomerUserFactory( user_id=UserFactory(username='******').id, enterprise_customer=self.enterprise_customer, ), course_id=self.course_id, consent_granted=True, ) def get_course_details(course_id): """ Mock course details - set course_id to match input """ return dict(pacing=pacing, course_id=course_id) mock_course_api.return_value.get_course_details.side_effect = get_course_details def get_course_certificate(course_id, username): """ Mock certificate data - return depending on course_id """ if '2' in course_id: return dict( username=username, is_passing=True, grade=grade, ) else: raise HttpNotFoundError mock_certificate_api.return_value.get_course_certificate.side_effect = get_course_certificate def get_course_grade(course_id, username): """ Mock grades data - set passed depending on course_id """ return dict( passed='2' in course_id, course_key=course_id, username=username, ) mock_grades_api.return_value.get_course_grade.side_effect = get_course_grade # Collect the learner data, with time set to NOW with freeze_time(self.NOW): learner_data = list(self.exporter.collect_learner_data()) assert len(learner_data) == 3 assert learner_data[ 0].enterprise_course_enrollment_id == enrollment1.id assert learner_data[0].course_id == self.course_id assert not learner_data[0].course_completed assert learner_data[0].completed_timestamp is None assert learner_data[0].grade == BaseLearnerExporter.GRADE_INCOMPLETE assert learner_data[ 1].enterprise_course_enrollment_id == enrollment3.id assert learner_data[1].course_id == self.course_id assert not learner_data[1].course_completed assert learner_data[1].completed_timestamp is None assert learner_data[1].grade == BaseLearnerExporter.GRADE_INCOMPLETE assert learner_data[ 2].enterprise_course_enrollment_id == enrollment2.id assert learner_data[2].course_id == course_id2 assert learner_data[2].course_completed assert learner_data[2].completed_timestamp == self.NOW_TIMESTAMP assert learner_data[2].grade == grade