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: ...@@ -7,12 +7,14 @@ Run these tests @ Devstack:
import json import json
import uuid import uuid
import mock import mock
from urllib import urlencode
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.cache import cache from django.core.cache import cache
from django.test import Client from django.test import Client
from django.test.utils import override_settings from django.test.utils import override_settings
from gradebook.models import StudentGradebook
from student.models import UserProfile from student.models import UserProfile
from student.tests.factories import CourseEnrollmentFactory from student.tests.factories import CourseEnrollmentFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
...@@ -295,3 +297,105 @@ class OrganizationsApiTests(ModuleStoreTestCase): ...@@ -295,3 +297,105 @@ class OrganizationsApiTests(ModuleStoreTestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertEqual(response.data[0]['id'], self.test_user.id) self.assertEqual(response.data[0]['id'], self.test_user.id)
self.assertEqual(response.data[0]['course_count'], 2) 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 # pylint: disable=C0103
""" ORGANIZATIONS API VIEWS """ """ ORGANIZATIONS API VIEWS """
from django.conf import settings
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import F
from rest_framework import status, viewsets from rest_framework import status, viewsets
from rest_framework.decorators import action from rest_framework.decorators import action
from rest_framework.response import Response from rest_framework.response import Response
from api_manager.courseware_access import get_course_key
from api_manager.models import Organization from api_manager.models import Organization
from api_manager.users.serializers import UserSerializer from api_manager.users.serializers import UserSerializer
from api_manager.utils import str2bool from api_manager.utils import str2bool
from gradebook.models import StudentGradebook
from student.models import CourseEnrollment from student.models import CourseEnrollment
from .serializers import OrganizationSerializer from .serializers import OrganizationSerializer
...@@ -23,6 +27,27 @@ class OrganizationsViewSet(viewsets.ModelViewSet): ...@@ -23,6 +27,27 @@ class OrganizationsViewSet(viewsets.ModelViewSet):
serializer_class = OrganizationSerializer serializer_class = OrganizationSerializer
model = Organization 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']) @action(methods=['get', 'post'])
def users(self, request, pk): 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