Esempio n. 1
0
 def test_enrolled_students_enrollment_verification(self):
     """
     Assert that we can get enrollment mode and verification status
     """
     query_features = ('enrollment_mode', 'verification_status')
     userreports = enrolled_students_features(self.course_key, query_features)
     self.assertEqual(len(userreports), len(self.users))
     # by default all users should have "audit" as their enrollment mode
     # and "N/A" as their verification status
     for userreport in userreports:
         self.assertEqual(set(userreport.keys()), set(query_features))
         self.assertIn(userreport['enrollment_mode'], ["audit"])
         self.assertIn(userreport['verification_status'], ["N/A"])
     # make sure that the user report respects whatever value
     # is returned by verification and enrollment code
     with patch("student.models.CourseEnrollment.enrollment_mode_for_user") as enrollment_patch:
         with patch(
             "lms.djangoapps.verify_student.services.IDVerificationService.verification_status_for_user"
         ) as verify_patch:
             enrollment_patch.return_value = ["verified"]
             verify_patch.return_value = "dummy verification status"
             userreports = enrolled_students_features(self.course_key, query_features)
             self.assertEqual(len(userreports), len(self.users))
             for userreport in userreports:
                 self.assertEqual(set(userreport.keys()), set(query_features))
                 self.assertIn(userreport['enrollment_mode'], ["verified"])
                 self.assertIn(userreport['verification_status'], ["dummy verification status"])
Esempio n. 2
0
 def test_enrolled_students_enrollment_verification(self):
     """
     Assert that we can get enrollment mode and verification status
     """
     query_features = ('enrollment_mode', 'verification_status')
     userreports = enrolled_students_features(self.course_key, query_features)
     self.assertEqual(len(userreports), len(self.users))
     # by default all users should have "audit" as their enrollment mode
     # and "N/A" as their verification status
     for userreport in userreports:
         self.assertEqual(set(userreport.keys()), set(query_features))
         self.assertIn(userreport['enrollment_mode'], ["audit"])
         self.assertIn(userreport['verification_status'], ["N/A"])
     # make sure that the user report respects whatever value
     # is returned by verification and enrollment code
     with patch("student.models.CourseEnrollment.enrollment_mode_for_user") as enrollment_patch:
         with patch(
             "lms.djangoapps.verify_student.services.IDVerificationService.verification_status_for_user"
         ) as verify_patch:
             enrollment_patch.return_value = ["verified"]
             verify_patch.return_value = "dummy verification status"
             userreports = enrolled_students_features(self.course_key, query_features)
             self.assertEqual(len(userreports), len(self.users))
             for userreport in userreports:
                 self.assertEqual(set(userreport.keys()), set(query_features))
                 self.assertIn(userreport['enrollment_mode'], ["verified"])
                 self.assertIn(userreport['verification_status'], ["dummy verification status"])
Esempio n. 3
0
    def test_enrolled_students_features_keys_cohorted(self):
        course = CourseFactory.create(org="test", course="course1", display_name="run1")
        course.cohort_config = {'cohorted': True, 'auto_cohort': True, 'auto_cohort_groups': ['cohort']}
        self.store.update_item(course, self.instructor.id)
        cohorted_students = [UserFactory.create() for _ in xrange(10)]
        cohort = CohortFactory.create(name='cohort', course_id=course.id, users=cohorted_students)
        cohorted_usernames = [student.username for student in cohorted_students]
        non_cohorted_student = UserFactory.create()
        for student in cohorted_students:
            cohort.users.add(student)
            CourseEnrollment.enroll(student, course.id)
        CourseEnrollment.enroll(non_cohorted_student, course.id)
        instructor = InstructorFactory(course_key=course.id)
        self.client.login(username=instructor.username, password='******')

        query_features = ('username', 'cohort')
        # There should be a constant of 2 SQL queries when calling
        # enrolled_students_features.  The first query comes from the call to
        # User.objects.filter(...), and the second comes from
        # prefetch_related('course_groups').
        with self.assertNumQueries(2):
            userreports = enrolled_students_features(course.id, query_features)
        self.assertEqual(len([r for r in userreports if r['username'] in cohorted_usernames]), len(cohorted_students))
        self.assertEqual(len([r for r in userreports if r['username'] == non_cohorted_student.username]), 1)
        for report in userreports:
            self.assertEqual(set(report.keys()), set(query_features))
            if report['username'] in cohorted_usernames:
                self.assertEqual(report['cohort'], cohort.name)
            else:
                self.assertEqual(report['cohort'], '[unassigned]')
Esempio n. 4
0
 def test_enrolled_students_features_username(self):
     self.assertIn('username', AVAILABLE_FEATURES)
     userreports = enrolled_students_features(self.course_key, ['username'])
     self.assertEqual(len(userreports), len(self.users))
     for userreport in userreports:
         self.assertEqual(userreport.keys(), ['username'])
         self.assertIn(userreport['username'], [user.username for user in self.users])
Esempio n. 5
0
    def test_enrolled_students_features_keys_cohorted(self):
        course = CourseFactory.create(org="test", course="course1", display_name="run1")
        course.cohort_config = {'cohorted': True, 'auto_cohort': True, 'auto_cohort_groups': ['cohort']}
        self.store.update_item(course, self.instructor.id)
        cohorted_students = [UserFactory.create() for _ in range(10)]
        cohort = CohortFactory.create(name='cohort', course_id=course.id, users=cohorted_students)
        cohorted_usernames = [student.username for student in cohorted_students]
        non_cohorted_student = UserFactory.create()
        for student in cohorted_students:
            cohort.users.add(student)
            CourseEnrollment.enroll(student, course.id)
        CourseEnrollment.enroll(non_cohorted_student, course.id)
        instructor = InstructorFactory(course_key=course.id)
        self.client.login(username=instructor.username, password='******')

        query_features = ('username', 'cohort')
        # There should be a constant of 2 SQL queries when calling
        # enrolled_students_features.  The first query comes from the call to
        # User.objects.filter(...), and the second comes from
        # prefetch_related('course_groups').
        with self.assertNumQueries(2):
            userreports = enrolled_students_features(course.id, query_features)
        self.assertEqual(len([r for r in userreports if r['username'] in cohorted_usernames]), len(cohorted_students))
        self.assertEqual(len([r for r in userreports if r['username'] == non_cohorted_student.username]), 1)
        for report in userreports:
            self.assertEqual(set(report.keys()), set(query_features))
            if report['username'] in cohorted_usernames:
                self.assertEqual(report['cohort'], cohort.name)
            else:
                self.assertEqual(report['cohort'], '[unassigned]')
Esempio n. 6
0
 def test_enrolled_students_features_username(self):
     self.assertIn('username', AVAILABLE_FEATURES)
     userreports = enrolled_students_features(self.course_key, ['username'])
     self.assertEqual(len(userreports), len(self.users))
     for userreport in userreports:
         self.assertEqual(list(userreport.keys()), ['username'])
         self.assertIn(userreport['username'], [user.username for user in self.users])
Esempio n. 7
0
def upload_students_csv(_xmodule_instance_args, _entry_id, course_id, task_input, action_name):
    """
    For a given `course_id`, generate a CSV file containing profile
    information for all students that are enrolled, and store using a
    `ReportStore`.
    """
    start_time = time()
    start_date = datetime.now(UTC)
    task_progress = TaskProgress(action_name, CourseEnrollment.num_enrolled_in(course_id), start_time)
    current_step = {'step': 'Calculating Profile Info'}
    task_progress.update_task_state(extra_meta=current_step)

    # compute the student features table and format it
    query_features = task_input.get('features')
    student_data = enrolled_students_features(course_id, query_features)
    header, rows = format_dictlist(student_data, query_features)

    task_progress.attempted = task_progress.succeeded = len(rows)
    task_progress.skipped = task_progress.total - task_progress.attempted

    rows.insert(0, header)

    current_step = {'step': 'Uploading CSV'}
    task_progress.update_task_state(extra_meta=current_step)

    # Perform the upload
    upload_csv_to_report_store(rows, 'student_profile_info', course_id, start_date)

    return task_progress.update_task_state(extra_meta=current_step)
Esempio n. 8
0
    def test_enrolled_students_features_keys(self):
        query_features = (
            'username',
            'name',
            'email',
            'city',
            'country',
        )
        for user in self.users:
            user.profile.city = "Mos Eisley {}".format(user.id)
            user.profile.country = "Tatooine {}".format(user.id)
            user.profile.save()
        for feature in query_features:
            self.assertIn(feature, AVAILABLE_FEATURES)
        with self.assertNumQueries(1):
            userreports = enrolled_students_features(self.course_key,
                                                     query_features)
        self.assertEqual(len(userreports), len(self.users))

        userreports = sorted(userreports, key=lambda u: u["username"])
        users = sorted(self.users, key=lambda u: u.username)
        for userreport, user in zip(userreports, users):
            self.assertEqual(set(userreport.keys()), set(query_features))
            self.assertEqual(userreport['username'], user.username)
            self.assertEqual(userreport['email'], user.email)
            self.assertEqual(userreport['name'], user.profile.name)
            self.assertEqual(userreport['city'], user.profile.city)
            self.assertEqual(userreport['country'], user.profile.country)
def upload_students_csv(_xmodule_instance_args, _entry_id, course_id,
                        task_input, action_name):
    """
    For a given `course_id`, generate a CSV file containing profile
    information for all students that are enrolled, and store using a
    `ReportStore`.
    """
    start_time = time()
    start_date = datetime.now(UTC)
    task_progress = TaskProgress(action_name,
                                 CourseEnrollment.num_enrolled_in(course_id),
                                 start_time)
    current_step = {'step': 'Calculating Profile Info'}
    task_progress.update_task_state(extra_meta=current_step)

    # compute the student features table and format it
    query_features = task_input.get('features')
    student_data = enrolled_students_features(course_id, query_features)
    header, rows = format_dictlist(student_data, query_features)

    task_progress.attempted = task_progress.succeeded = len(rows)
    task_progress.skipped = task_progress.total - task_progress.attempted

    rows.insert(0, header)

    current_step = {'step': 'Uploading CSV'}
    task_progress.update_task_state(extra_meta=current_step)

    # Perform the upload
    upload_csv_to_report_store(rows, 'student_profile_info', course_id,
                               start_date)

    return task_progress.update_task_state(extra_meta=current_step)
Esempio n. 10
0
 def test_enrolled_student_with_no_country_city(self):
     userreports = enrolled_students_features(self.course_key, ('username', 'city', 'country',))
     for userreport in userreports:
         # This behaviour is somewhat inconsistent: None string fields
         # objects are converted to "None", but non-JSON serializable fields
         # are converted to an empty string.
         self.assertEqual(userreport['city'], "None")
         self.assertEqual(userreport['country'], "")
Esempio n. 11
0
 def test_enrolled_student_with_no_country_city(self):
     userreports = enrolled_students_features(self.course_key, ('username', 'city', 'country',))
     for userreport in userreports:
         # This behaviour is somewhat inconsistent: None string fields
         # objects are converted to "None", but non-JSON serializable fields
         # are converted to an empty string.
         self.assertEqual(userreport['city'], "None")
         self.assertEqual(userreport['country'], "")
Esempio n. 12
0
 def test_enrolled_students_features_keys(self):
     query_features = ('username', 'name', 'email')
     for feature in query_features:
         self.assertIn(feature, AVAILABLE_FEATURES)
     userreports = enrolled_students_features(self.course_key, query_features)
     self.assertEqual(len(userreports), len(self.users))
     for userreport in userreports:
         self.assertEqual(set(userreport.keys()), set(query_features))
         self.assertIn(userreport['username'], [user.username for user in self.users])
         self.assertIn(userreport['email'], [user.email for user in self.users])
         self.assertIn(userreport['name'], [user.profile.name for user in self.users])
Esempio n. 13
0
 def test_enrolled_students_meta_features_keys(self):
     """
     Assert that we can query individual fields in the 'meta' field in the UserProfile
     """
     query_features = ('meta.position', 'meta.company')
     with self.assertNumQueries(1):
         userreports = enrolled_students_features(self.course_key, query_features)
     self.assertEqual(len(userreports), len(self.users))
     for userreport in userreports:
         self.assertEqual(set(userreport.keys()), set(query_features))
         self.assertIn(userreport['meta.position'], ["edX expert {}".format(user.id) for user in self.users])
         self.assertIn(userreport['meta.company'], ["Open edX Inc {}".format(user.id) for user in self.users])
Esempio n. 14
0
 def test_enrolled_students_meta_features_keys(self):
     """
     Assert that we can query individual fields in the 'meta' field in the UserProfile
     """
     query_features = ('meta.position', 'meta.company')
     with self.assertNumQueries(1):
         userreports = enrolled_students_features(self.course_key, query_features)
     self.assertEqual(len(userreports), len(self.users))
     for userreport in userreports:
         self.assertEqual(set(userreport.keys()), set(query_features))
         self.assertIn(userreport['meta.position'], [u"edX expert {}".format(user.id) for user in self.users])
         self.assertIn(userreport['meta.company'], [u"Open edX Inc {}".format(user.id) for user in self.users])
Esempio n. 15
0
def push_students_csv_to_s3(_xmodule_instance_args, _entry_id, course_id,
                            task_input, _action_name):
    """
    For a given `course_id`, generate a CSV file containing profile
    information for all students that are enrolled, and store using a
    `ReportStore`.
    """
    # compute the student features table and format it
    query_features = task_input.get('features')
    student_data = enrolled_students_features(course_id, query_features)
    header, rows = format_dictlist(student_data, query_features)
    rows.insert(0, header)

    # Perform the upload
    upload_csv_to_report_store(rows, 'student_profile_info', course_id,
                               datetime.now(UTC))

    return UPDATE_STATUS_SUCCEEDED
Esempio n. 16
0
    def test_enrolled_students_features_keys(self):
        query_features = ('username', 'name', 'email', 'city', 'country',)
        for user in self.users:
            user.profile.city = "Mos Eisley {}".format(user.id)
            user.profile.country = "Tatooine {}".format(user.id)
            user.profile.save()
        for feature in query_features:
            self.assertIn(feature, AVAILABLE_FEATURES)
        with self.assertNumQueries(1):
            userreports = enrolled_students_features(self.course_key, query_features)
        self.assertEqual(len(userreports), len(self.users))

        userreports = sorted(userreports, key=lambda u: u["username"])
        users = sorted(self.users, key=lambda u: u.username)
        for userreport, user in zip(userreports, users):
            self.assertEqual(set(userreport.keys()), set(query_features))
            self.assertEqual(userreport['username'], user.username)
            self.assertEqual(userreport['email'], user.email)
            self.assertEqual(userreport['name'], user.profile.name)
            self.assertEqual(userreport['city'], user.profile.city)
            self.assertEqual(userreport['country'], user.profile.country)