Commit 83bc318e by sanfordstudent Committed by GitHub

Merge pull request #14235 from edx/sstudent/TNL-6214

add verfication and enrollment to user profile report
parents df1bec4b 5fd94a66
...@@ -1213,7 +1213,7 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red ...@@ -1213,7 +1213,7 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red
query_features = [ query_features = [
'id', 'username', 'name', 'email', 'language', 'location', 'id', 'username', 'name', 'email', 'language', 'location',
'year_of_birth', 'gender', 'level_of_education', 'mailing_address', 'year_of_birth', 'gender', 'level_of_education', 'mailing_address',
'goals', 'goals', 'enrollment_mode', 'verification_status',
] ]
# Provide human-friendly and translatable names for these features. These names # Provide human-friendly and translatable names for these features. These names
...@@ -1231,6 +1231,8 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red ...@@ -1231,6 +1231,8 @@ def get_students_features(request, course_id, csv=False): # pylint: disable=red
'level_of_education': _('Level of Education'), 'level_of_education': _('Level of Education'),
'mailing_address': _('Mailing Address'), 'mailing_address': _('Mailing Address'),
'goals': _('Goals'), 'goals': _('Goals'),
'enrollment_mode': _('Enrollment Mode'),
'verification_status': _('Verification Status'),
} }
if is_course_cohorted(course.id): if is_course_cohorted(course.id):
......
...@@ -17,13 +17,14 @@ from django.core.serializers.json import DjangoJSONEncoder ...@@ -17,13 +17,14 @@ from django.core.serializers.json import DjangoJSONEncoder
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from opaque_keys.edx.keys import UsageKey from opaque_keys.edx.keys import UsageKey
import xmodule.graders as xmgraders import xmodule.graders as xmgraders
from student.models import CourseEnrollmentAllowed from student.models import CourseEnrollmentAllowed, CourseEnrollment
from edx_proctoring.api import get_all_exam_attempts from edx_proctoring.api import get_all_exam_attempts
from courseware.models import StudentModule from courseware.models import StudentModule
from certificates.models import GeneratedCertificate from certificates.models import GeneratedCertificate
from django.db.models import Count from django.db.models import Count
from certificates.models import CertificateStatuses from certificates.models import CertificateStatuses
from lms.djangoapps.grades.context import grading_context_for_course from lms.djangoapps.grades.context import grading_context_for_course
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
...@@ -213,6 +214,8 @@ def enrolled_students_features(course_key, features): ...@@ -213,6 +214,8 @@ def enrolled_students_features(course_key, features):
""" """
include_cohort_column = 'cohort' in features include_cohort_column = 'cohort' in features
include_team_column = 'team' in features include_team_column = 'team' in features
include_enrollment_mode = 'enrollment_mode' in features
include_verification_status = 'verification_status' in features
students = User.objects.filter( students = User.objects.filter(
courseenrollment__course_id=course_key, courseenrollment__course_id=course_key,
...@@ -256,7 +259,7 @@ def enrolled_students_features(course_key, features): ...@@ -256,7 +259,7 @@ def enrolled_students_features(course_key, features):
for feature in profile_features) for feature in profile_features)
student_dict.update(profile_dict) student_dict.update(profile_dict)
# now featch the requested meta fields # now fetch the requested meta fields
meta_dict = json.loads(profile.meta) if profile.meta else {} meta_dict = json.loads(profile.meta) if profile.meta else {}
for meta_feature, meta_key in meta_features: for meta_feature, meta_key in meta_features:
student_dict[meta_feature] = meta_dict.get(meta_key) student_dict[meta_feature] = meta_dict.get(meta_key)
...@@ -275,6 +278,18 @@ def enrolled_students_features(course_key, features): ...@@ -275,6 +278,18 @@ def enrolled_students_features(course_key, features):
(team.name for team in student.teams.all() if team.course_id == course_key), (team.name for team in student.teams.all() if team.course_id == course_key),
UNAVAILABLE UNAVAILABLE
) )
if include_enrollment_mode or include_verification_status:
enrollment_mode = CourseEnrollment.enrollment_mode_for_user(student, course_key)[0]
if include_verification_status:
student_dict['verification_status'] = SoftwareSecurePhotoVerification.verification_status_for_user(
student,
course_key,
enrollment_mode
)
if include_enrollment_mode:
student_dict['enrollment_mode'] = enrollment_mode
return student_dict return student_dict
return [extract_student(student, features) for student in students] return [extract_student(student, features) for student in students]
......
...@@ -149,6 +149,34 @@ class TestAnalyticsBasic(ModuleStoreTestCase): ...@@ -149,6 +149,34 @@ class TestAnalyticsBasic(ModuleStoreTestCase):
self.assertIn(userreport['meta.position'], ["edX expert {}".format(user.id) for user in self.users]) 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]) self.assertIn(userreport['meta.company'], ["Open edX Inc {}".format(user.id) for user in self.users])
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.models.SoftwareSecurePhotoVerification.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"])
def test_enrolled_students_features_keys_cohorted(self): def test_enrolled_students_features_keys_cohorted(self):
course = CourseFactory.create(org="test", course="course1", display_name="run1") course = CourseFactory.create(org="test", course="course1", display_name="run1")
course.cohort_config = {'cohorted': True, 'auto_cohort': True, 'auto_cohort_groups': ['cohort']} course.cohort_config = {'cohorted': True, 'auto_cohort': True, 'auto_cohort_groups': ['cohort']}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment