Commit 21cadac2 by Saqib

Update course metrics grades API to allow filtering of users by groups

parent 8a78c055
...@@ -2042,6 +2042,77 @@ class CoursesApiTests(ModuleStoreTestCase): ...@@ -2042,6 +2042,77 @@ class CoursesApiTests(ModuleStoreTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['grades']), user_index) self.assertEqual(len(response.data['grades']), user_index)
def test_courses_metrics_grades_list_get_filter_users_by_group(self):
# Retrieve the list of grades for course and filter by groups
groups = GroupFactory.create_batch(2)
users = UserFactory.create_batch(5)
for i, user in enumerate(users):
user.groups.add(groups[i % 2])
for user in users:
CourseEnrollmentFactory.create(user=user, course_id=self.course.id)
for j, user in enumerate(users):
points_scored = (j + 1) * 20
points_possible = 100
module = self.get_module_for_user(user, self.course, self.item)
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user.id}
module.system.publish(module, 'grade', grade_dict)
user_ids = ','.join([str(user.id) for user in users])
test_uri = '{}/{}/metrics/grades?user_id={}&groups={}'.format(self.base_courses_uri,
self.test_course_id,
user_ids,
groups[0].id)
response = self.do_get(test_uri)
self.assertEqual(response.status_code, 200)
self.assertGreater(response.data['grade_average'], 0)
self.assertGreater(response.data['grade_maximum'], 0)
self.assertGreater(response.data['grade_minimum'], 0)
self.assertEqual(response.data['grade_count'], 3)
self.assertGreater(response.data['course_grade_average'], 0)
self.assertGreater(response.data['course_grade_maximum'], 0)
self.assertGreater(response.data['course_grade_minimum'], 0)
self.assertEqual(response.data['course_grade_count'], USER_COUNT + 5)
self.assertEqual(len(response.data['grades']), 3)
def test_courses_metrics_grades_list_get_filter_users_by_multiple_groups(self):
# Retrieve the list of grades for course and filter by multiple groups and user_id
groups = GroupFactory.create_batch(2)
users = UserFactory.create_batch(5)
for i, user in enumerate(users):
user.groups.add(groups[i % 2])
for user in users:
CourseEnrollmentFactory.create(user=user, course_id=self.course.id)
for j, user in enumerate(users):
points_scored = (j + 1) * 20
points_possible = 100
module = self.get_module_for_user(user, self.course, self.item)
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user.id}
module.system.publish(module, 'grade', grade_dict)
user_ids = ','.join([str(user.id) for user in users])
test_uri = '{}/{}/metrics/grades'.format(self.base_courses_uri, self.test_course_id,)
user_group_filter_uri = '{}?user_id={}&groups={},{}'.format(test_uri,
user_ids,
groups[0].id,
groups[1].id)
response = self.do_get(user_group_filter_uri)
self.assertEqual(response.status_code, 200)
self.assertGreater(response.data['grade_average'], 0)
self.assertGreater(response.data['grade_maximum'], 0)
self.assertGreater(response.data['grade_minimum'], 0)
self.assertEqual(response.data['grade_count'], 5)
self.assertGreater(response.data['course_grade_average'], 0)
self.assertGreater(response.data['course_grade_maximum'], 0)
self.assertGreater(response.data['course_grade_minimum'], 0)
self.assertEqual(response.data['course_grade_count'], USER_COUNT + 5)
self.assertEqual(len(response.data['grades']), 5)
def test_courses_metrics_grades_list_get_empty_course(self): def test_courses_metrics_grades_list_get_empty_course(self):
# Retrieve the list of grades for this course # Retrieve the list of grades for this course
# All the course/item/user scaffolding was handled in Setup # All the course/item/user scaffolding was handled in Setup
......
...@@ -1470,12 +1470,23 @@ class CoursesMetricsGradesList(SecureListAPIView): ...@@ -1470,12 +1470,23 @@ class CoursesMetricsGradesList(SecureListAPIView):
user_ids = map(int, user_ids.split(','))[:upper_bound] user_ids = map(int, user_ids.split(','))[:upper_bound]
queryset = queryset.filter(user__in=user_ids) queryset = queryset.filter(user__in=user_ids)
group_ids = self.request.QUERY_PARAMS.get('groups', None)
if group_ids:
try:
group_ids = map(int, group_ids.split(','))
except ValueError:
return Response({}, status.HTTP_400_BAD_REQUEST)
queryset = queryset.filter(user__groups__in=group_ids)
queryset_grade_avg = queryset.aggregate(Avg('grade')) queryset_grade_avg = queryset.aggregate(Avg('grade'))
queryset_grade_max = queryset.aggregate(Max('grade')) queryset_grade_max = queryset.aggregate(Max('grade'))
queryset_grade_min = queryset.aggregate(Min('grade')) queryset_grade_min = queryset.aggregate(Min('grade'))
queryset_grade_count = queryset.aggregate(Count('grade')) queryset_grade_count = queryset.aggregate(Count('grade'))
course_metrics = StudentGradebook.generate_leaderboard(course_key, exclude_users=exclude_users) course_metrics = StudentGradebook.generate_leaderboard(course_key,
group_ids=group_ids,
exclude_users=exclude_users)
response_data = {} response_data = {}
base_uri = generate_base_uri(request) base_uri = generate_base_uri(request)
......
...@@ -39,7 +39,7 @@ class StudentGradebook(models.Model): ...@@ -39,7 +39,7 @@ class StudentGradebook(models.Model):
unique_together = (('user', 'course_id'),) unique_together = (('user', 'course_id'),)
@classmethod @classmethod
def generate_leaderboard(cls, course_key, user_id=None, count=3, exclude_users=None): def generate_leaderboard(cls, course_key, user_id=None, group_ids=None, count=3, exclude_users=None):
""" """
Assembles a data set representing the Top N users, by grade, for a given course. Assembles a data set representing the Top N users, by grade, for a given course.
Optionally provide a user_id to include user-specific info. For example, you Optionally provide a user_id to include user-specific info. For example, you
...@@ -81,6 +81,10 @@ class StudentGradebook(models.Model): ...@@ -81,6 +81,10 @@ class StudentGradebook(models.Model):
.filter(course_id__exact=course_key, user__is_active=True, user__courseenrollment__is_active=True, .filter(course_id__exact=course_key, user__is_active=True, user__courseenrollment__is_active=True,
user__courseenrollment__course_id__exact=course_key, user__courseenrollment__course_id__exact=course_key,
user__in=enrolled_users_not_excluded) user__in=enrolled_users_not_excluded)
if group_ids:
queryset.filter(user__groups__in=group_ids)
gradebook_user_count = len(queryset) gradebook_user_count = len(queryset)
if gradebook_user_count: if gradebook_user_count:
......
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