Commit b686b2da by Matt Drayer Committed by Jonathan Piacenti

mattdrayer/api-orgs-complete-count: New metrics operation

parent ec39092c
......@@ -7,12 +7,14 @@ Run these tests @ Devstack:
import json
import uuid
import mock
from urllib import urlencode
from django.contrib.auth.models import User
from django.core.cache import cache
from django.test import Client
from django.test.utils import override_settings
from gradebook.models import StudentGradebook
from student.models import UserProfile
from student.tests.factories import CourseEnrollmentFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
......@@ -295,3 +297,105 @@ class OrganizationsApiTests(ModuleStoreTestCase):
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data[0]['id'], self.test_user.id)
self.assertEqual(response.data[0]['course_count'], 2)
def test_organizations_metrics_get(self):
users = []
for i in xrange(1, 6):
data = {
'email': 'test{}@example.com'.format(i),
'username': 'test_user{}'.format(i),
'password': 'test_pass',
'first_name': 'John{}'.format(i),
'last_name': 'Doe{}'.format(i),
'city': 'Boston',
}
response = self.do_post(self.base_users_uri, data)
self.assertEqual(response.status_code, 201)
user_id = response.data['id']
user = User.objects.get(pk=user_id)
users.append(user_id)
if i < 2:
StudentGradebook.objects.create(user=user, grade=0.75, proforma_grade=0.85)
elif i < 4:
StudentGradebook.objects.create(user=user, grade=0.82, proforma_grade=0.82)
else:
StudentGradebook.objects.create(user=user, grade=0.90, proforma_grade=0.91)
data = {
'name': self.test_organization_name,
'display_name': self.test_organization_display_name,
'contact_name': self.test_organization_contact_name,
'contact_email': self.test_organization_contact_email,
'contact_phone': self.test_organization_contact_phone,
'logo_url': self.test_organization_logo_url,
'users': users
}
response = self.do_post(self.base_organizations_uri, data)
test_uri = '{}{}/'.format(self.base_organizations_uri, str(response.data['id']))
users_uri = '{}users/'.format(test_uri)
metrics_uri = '{}metrics/'.format(test_uri)
response = self.do_get(metrics_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['users_grade_complete_count'], 4)
def test_organizations_metrics_get_courses_filter(self):
users = []
for i in xrange(1, 10):
data = {
'email': 'test{}@example.com'.format(i),
'username': 'test_user{}'.format(i),
'password': 'test_pass',
'first_name': 'John{}'.format(i),
'last_name': 'Doe{}'.format(i),
'city': 'Boston',
}
response = self.do_post(self.base_users_uri, data)
self.assertEqual(response.status_code, 201)
user_id = response.data['id']
user = User.objects.get(pk=user_id)
users.append(user_id)
course1 = CourseFactory.create(display_name="COURSE1", org="CRS1", run="RUN1")
course2 = CourseFactory.create(display_name="COURSE2", org="CRS2", run="RUN2")
course3 = CourseFactory.create(display_name="COURSE3", org="CRS3", run="RUN3")
if i < 3:
StudentGradebook.objects.create(user=user, grade=0.75, proforma_grade=0.85, course_id=course1.id)
elif i < 5:
StudentGradebook.objects.create(user=user, grade=0.82, proforma_grade=0.82, course_id=course2.id)
elif i < 7:
StudentGradebook.objects.create(user=user, grade=0.72, proforma_grade=0.78, course_id=course3.id)
elif i < 9:
StudentGradebook.objects.create(user=user, grade=0.94, proforma_grade=0.67, course_id=course1.id)
else:
StudentGradebook.objects.create(user=user, grade=0.90, proforma_grade=0.91, course_id=course2.id)
data = {
'name': self.test_organization_name,
'display_name': self.test_organization_display_name,
'contact_name': self.test_organization_contact_name,
'contact_email': self.test_organization_contact_email,
'contact_phone': self.test_organization_contact_phone,
'logo_url': self.test_organization_logo_url,
'users': users
}
response = self.do_post(self.base_organizations_uri, data)
test_uri = '{}{}/'.format(self.base_organizations_uri, str(response.data['id']))
users_uri = '{}users/'.format(test_uri)
metrics_uri = '{}metrics/'.format(test_uri)
response = self.do_get(metrics_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['users_grade_complete_count'], 5)
courses = {'courses': unicode(course1.id)}
filtered_metrics_uri = '{}?{}'.format(metrics_uri, urlencode(courses))
response = self.do_get(filtered_metrics_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['users_grade_complete_count'], 2)
courses = {'courses': '{},{}'.format(course1.id, course2.id)}
filtered_metrics_uri = '{}?{}'.format(metrics_uri, urlencode(courses))
response = self.do_get(filtered_metrics_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['users_grade_complete_count'], 5)
# pylint: disable=C0103
""" ORGANIZATIONS API VIEWS """
from django.conf import settings
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import F
from rest_framework import status, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from api_manager.courseware_access import get_course_key
from api_manager.models import Organization
from api_manager.users.serializers import UserSerializer
from api_manager.utils import str2bool
from gradebook.models import StudentGradebook
from student.models import CourseEnrollment
from .serializers import OrganizationSerializer
......@@ -23,6 +27,27 @@ class OrganizationsViewSet(viewsets.ModelViewSet):
serializer_class = OrganizationSerializer
model = Organization
@action(methods=['get',])
def metrics(self, request, pk):
"""
Provide statistical information for the specified Organization
"""
response_data = {}
grade_complete_match_range = getattr(settings, 'GRADEBOOK_GRADE_COMPLETE_PROFORMA_MATCH_RANGE', 0.01)
org_user_grades = StudentGradebook.objects.filter(user__organizations=pk)
courses_filter = request.QUERY_PARAMS.get('courses', None)
if courses_filter:
upper_bound = getattr(settings, 'API_LOOKUP_UPPER_BOUND', 100)
courses_filter = courses_filter.split(",")[:upper_bound]
courses = []
for course_string in courses_filter:
courses.append(get_course_key(course_string))
org_user_grades = org_user_grades.filter(course_id__in=courses)
users_grade_complete_count = org_user_grades\
.filter(proforma_grade__lte=F('grade') + grade_complete_match_range).count()
response_data['users_grade_complete_count'] = users_grade_complete_count
return Response(response_data, status=status.HTTP_200_OK)
@action(methods=['get', 'post'])
def users(self, request, pk):
"""
......
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