Commit fc232e5e by Cliff Dyer Committed by GitHub

Merge pull request #57 from edx/neem/score-summaries

return serialized scores from get_scores()
parents 7deafc6d 7a557d7d
......@@ -33,7 +33,7 @@ def load_requirements(*requirements_paths):
setup(
name='edx-submissions',
version='1.2.0',
version='2.0.0',
author='edX',
description='An API for creating submissions and scores.',
url='http://github.com/edx/edx-submissions.git',
......
......@@ -14,7 +14,7 @@ from django.db import IntegrityError, DatabaseError
from dogapi import dog_stats_api
from submissions.serializers import (
SubmissionSerializer, StudentItemSerializer, ScoreSerializer
SubmissionSerializer, StudentItemSerializer, ScoreSerializer, UnannotatedScoreSerializer
)
from submissions.models import Submission, StudentItem, Score, ScoreSummary, ScoreAnnotation, score_set, score_reset
......@@ -626,7 +626,10 @@ def get_score(student_item):
def get_scores(course_id, student_id):
"""Return a dict mapping item_ids -> (points_earned, points_possible).
"""Return a dict mapping item_ids to scores.
Scores are represented by serialized Score objects in JSON-like dict
format.
This method would be used by an LMS to find all the scores for a given
student in a given course.
......@@ -654,7 +657,7 @@ def get_scores(course_id, student_id):
score_summaries = ScoreSummary.objects.filter(
student_item__course_id=course_id,
student_item__student_id=student_id,
).select_related('latest', 'student_item')
).select_related('latest', 'latest__submission', 'student_item')
except DatabaseError:
msg = u"Could not fetch scores for course {}, student {}".format(
course_id, student_id
......@@ -662,10 +665,8 @@ def get_scores(course_id, student_id):
logger.exception(msg)
raise SubmissionInternalError(msg)
scores = {
summary.student_item.item_id:
(summary.latest.points_earned, summary.latest.points_possible)
for summary in score_summaries
if not summary.latest.is_hidden()
summary.student_item.item_id: UnannotatedScoreSerializer(summary.latest).data
for summary in score_summaries if not summary.latest.is_hidden()
}
return scores
......
......@@ -96,12 +96,31 @@ class ScoreAnnotationSerializer(serializers.ModelSerializer):
)
class ScoreSerializer(serializers.ModelSerializer):
class UnannotatedScoreSerializer(serializers.ModelSerializer):
# Ensure that the created_at datetime is not converted to a string.
created_at = DateTimeField(format=None, required=False)
class Meta:
model = Score
fields = (
'student_item',
'submission',
'points_earned',
'points_possible',
'created_at',
# Computed
'submission_uuid',
)
class ScoreSerializer(serializers.ModelSerializer):
# Ensure that the created_at datetime is not converted to a string.
created_at = DateTimeField(format=None, required=False)
annotations = serializers.SerializerMethodField()
def get_annotations(self, obj):
"""
Inspect ScoreAnnotations to attach all relevant annotations.
......
......@@ -363,6 +363,7 @@ class TestSubmissionsApi(TestCase):
student_item['student_id'] = None
self.assertIs(api.get_score(student_item), None)
@freeze_time(datetime.datetime.now().replace(tzinfo=pytz.UTC))
def test_get_scores(self):
student_item = copy.deepcopy(STUDENT_ITEM)
student_item["course_id"] = "get_scores_course"
......@@ -388,14 +389,35 @@ class TestSubmissionsApi(TestCase):
scores = api.get_scores(
student_item["course_id"], student_item["student_id"]
)
self.assertEqual(
scores,
{
u"i4x://a/b/c/s1": (2, 5),
u"i4x://a/b/c/s2": (0, 10),
u"i4x://a/b/c/s3": (4, 4),
}
)
self.assertEqual(
scores,
{
u'i4x://a/b/c/s1': {
'created_at': datetime.datetime.now(),
'points_earned': 2,
'points_possible': 5,
'student_item': 1,
'submission': 1,
'submission_uuid': s1['uuid'],
},
u'i4x://a/b/c/s2': {
'created_at': datetime.datetime.now(),
'points_earned': 0,
'points_possible': 10,
'student_item': 2,
'submission': 2,
'submission_uuid': s2['uuid'],
},
u'i4x://a/b/c/s3': {
'created_at': datetime.datetime.now(),
'points_earned': 4,
'points_possible': 4,
'student_item': 3,
'submission': 3,
'submission_uuid': s3['uuid'],
},
}
)
def test_get_top_submissions(self):
student_item_1 = copy.deepcopy(STUDENT_ITEM)
......
......@@ -137,7 +137,8 @@ class TestResetScore(TestCase):
scores = sub_api.get_scores(self.STUDENT_ITEM['course_id'], self.STUDENT_ITEM['student_id'])
self.assertIn(self.STUDENT_ITEM['item_id'], scores)
self.assertEqual(scores[self.STUDENT_ITEM['item_id']], (3, 4))
item_score = scores[self.STUDENT_ITEM['item_id']]
self.assertEqual((item_score['points_earned'], item_score['points_possible']), (3, 4))
def test_reset_then_get_score_for_submission(self):
# Create a submission for the student and score it
......
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