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
示例#7
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