Skip to content
Snippets Groups Projects
Verified Commit cc88f2c7 authored by Jan Maximilian Michal's avatar Jan Maximilian Michal
Browse files

Modifications that syncronize several previously merged branches

* Fixed errors that arose from merging errors
* Added feedback to mock data so student page works
* Student serializer now only send necessary submission info on initial load
parent 41852415
No related branches found
No related tags found
1 merge request!39Modifications that syncronize several previously merged branches
Pipeline #
......@@ -7,8 +7,8 @@ from rest_framework.validators import UniqueValidator
from core import models
from core.models import (ExamType, Feedback, GeneralTaskSubscription,
StudentInfo, Submission, SubmissionType,
TutorSubmissionAssignment)
StudentInfo, Submission, SubmissionType, Test,
TutorSubmissionAssignment, UserAccount)
from util.factories import GradyUserFactory
log = logging.getLogger(__name__)
......@@ -25,7 +25,20 @@ class CannotSetFirstFeedbackFinal(Exception):
class DynamicFieldsModelSerializer(DynamicFieldsMixin,
serializers.ModelSerializer):
pass
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(DynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
class ExamSerializer(DynamicFieldsModelSerializer):
......@@ -138,47 +151,67 @@ class FeedbackCommentSerializer(serializers.ModelSerializer):
read_only_fields = ('created',)
class SubmissionTypeSerializer(DynamicFieldsModelSerializer):
fullScore = serializers.ReadOnlyField(source='full_score')
typeId = serializers.ReadOnlyField(source='id')
class TestSerializer(DynamicFieldsModelSerializer):
class Meta:
model = Test
fields = ('name', 'label', 'annotation')
class SubmissionTypeListSerializer(DynamicFieldsModelSerializer):
fullScore = serializers.IntegerField(source='full_score')
class Meta:
model = SubmissionType
fields = ('id', 'name', 'fullScore')
class SubmissionTypeSerializer(SubmissionTypeListSerializer):
class Meta:
model = SubmissionType
fields = ('typeId', 'name', 'fullScore', 'description', 'solution')
fields = ('id', 'name', 'fullScore', 'description', 'solution')
class SubmissionSerializer(DynamicFieldsModelSerializer):
feedback = serializers.ReadOnlyField(source='feedback.text')
score = serializers.ReadOnlyField(source='feedback.score')
typeId = serializers.ReadOnlyField(source='type.id')
typeName = serializers.ReadOnlyField(source='type.name')
fullScore = serializers.ReadOnlyField(source='type.full_score')
type = SubmissionTypeSerializer()
feedback = FeedbackSerializer()
tests = TestSerializer(many=True)
class Meta:
model = Submission
fields = ('type', 'text', 'feedback', 'tests')
class SubmissionListSerializer(DynamicFieldsModelSerializer):
type = SubmissionTypeListSerializer(fields=('id', 'name', 'fullScore'))
# TODO change this according to new feedback model
feedback = FeedbackSerializer(fields=('score',))
class Meta:
model = Submission
fields = ('typeId', 'typeName', 'text',
'feedback', 'score', 'fullScore')
fields = ('type', 'feedback')
class StudentInfoSerializer(DynamicFieldsModelSerializer):
name = serializers.ReadOnlyField(source='user.fullname')
user = serializers.ReadOnlyField(source='user.username')
matrikel_no = serializers.ReadOnlyField(source='user.matrikel_no')
exam = ExamSerializer()
submissions = SubmissionSerializer(many=True)
submissions = SubmissionListSerializer(many=True)
class Meta:
model = StudentInfo
fields = ('name', 'user', 'exam', 'submissions')
fields = ('name', 'user', 'matrikel_no', 'exam', 'submissions')
class SubmissionNoTextFieldsSerializer(DynamicFieldsModelSerializer):
score = serializers.ReadOnlyField(source='feedback.score')
typeId = serializers.ReadOnlyField(source='type.id')
type = serializers.ReadOnlyField(source='type.name')
fullScore = serializers.ReadOnlyField(source='type.full_score')
class Meta:
model = Submission
fields = ('typeId', 'score', 'fullScore')
fields = ('type', 'score', 'fullScore')
class StudentInfoSerializerForListView(DynamicFieldsModelSerializer):
......@@ -196,13 +229,13 @@ class TutorSerializer(DynamicFieldsModelSerializer):
feedback_count = serializers.IntegerField(source='get_feedback_count',
read_only=True)
def create(self, validated_data) -> models.UserAccount:
def create(self, validated_data) -> UserAccount:
log.info("Crating tutor from data %s", validated_data)
return user_factory.make_tutor(
username=validated_data['username'])
class Meta:
model = models.UserAccount
model = UserAccount
fields = ('username', 'feedback_count')
......
......@@ -49,7 +49,8 @@ class StudentPageTests(APITestCase):
}]
})
self.student = self.test_data['students'][0].student
self.student = self.test_data['students'][0]
self.student_info = self.student.student
self.tutor = self.test_data['tutors'][0]
self.reviewer = self.test_data['reviewers'][0]
self.submission = self.test_data['submissions'][0]
......@@ -57,7 +58,7 @@ class StudentPageTests(APITestCase):
self.request = self.factory.get(reverse('student-page'))
self.view = StudentSelfApiView.as_view()
force_authenticate(self.request, user=self.student.user)
force_authenticate(self.request, user=self.student)
self.response = self.view(self.request)
self.exam_obj = self.response.data['exam']
......@@ -66,7 +67,7 @@ class StudentPageTests(APITestCase):
def test_student_information_contains_name(self):
self.assertEqual(
self.response.data['name'], self.student.user.fullname)
self.response.data['name'], self.student.fullname)
def test_all_student_submissions_are_loded(self):
self.assertEqual(len(self.submission_list),
......@@ -76,40 +77,40 @@ class StudentPageTests(APITestCase):
def test_exam_data_contains_module_reference(self):
self.assertEqual(
self.exam_obj["module_reference"],
self.student.exam.module_reference)
self.student_info.exam.module_reference)
def test_exam_data_contains_total_score(self):
self.assertEqual(
self.exam_obj["total_score"], self.student.exam.total_score)
self.exam_obj["total_score"], self.student_info.exam.total_score)
def test_exam_data_contains_pass_score(self):
self.assertEqual(
self.exam_obj["pass_score"], self.student.exam.pass_score)
self.exam_obj["pass_score"], self.student_info.exam.pass_score)
def test_exam_data_contains_pass_only_field(self):
self.assertEqual(
self.exam_obj["pass_only"], self.student.exam.pass_only)
self.exam_obj["pass_only"], self.student_info.exam.pass_only)
# Tests concerning submission data
def test_a_student_submissions_contains_type_name(self):
self.assertEqual(
self.submission_list_first_entry['typeName'],
self.student.submissions.first().type.name)
self.submission_list_first_entry['type']['name'],
self.student_info.submissions.first().type.name)
def test_a_student_submissions_contains_type_id(self):
self.assertEqual(
self.submission_list_first_entry['typeId'],
self.student.submissions.first().type.id)
self.submission_list_first_entry['type']['id'],
self.student_info.submissions.first().type.id)
def test_submission_data_contains_full_score(self):
self.assertEqual(
self.submission_list_first_entry['fullScore'],
self.student.submissions.first().type.full_score)
self.submission_list_first_entry['type']['fullScore'],
self.student_info.submissions.first().type.full_score)
def test_submission_data_contains_feedback_score(self):
self.assertEqual(
self.submission_list_first_entry['score'],
self.student.submissions.first().feedback.score)
self.submission_list_first_entry['feedback']['score'],
self.student_info.submissions.first().feedback.score)
# We don't want a matriculation number here
def test_matriculation_number_is_not_send(self):
......@@ -148,7 +149,8 @@ class StudentSelfSubmissionsTests(APITestCase):
}]
})
self.student = self.test_data['students'][0].student
self.student = self.test_data['students'][0]
self.student_info = self.student.student
self.tutor = self.test_data['tutors'][0]
self.submission = self.test_data['submissions'][0]
self.feedback = self.submission.feedback
......@@ -156,7 +158,7 @@ class StudentSelfSubmissionsTests(APITestCase):
self.request = self.factory.get(reverse('student-submissions'))
self.view = StudentSelfSubmissionsApiView.as_view()
force_authenticate(self.request, user=self.student.user)
force_authenticate(self.request, user=self.student)
self.response = self.view(self.request)
self.submission_list = self.response.data
......@@ -165,33 +167,38 @@ class StudentSelfSubmissionsTests(APITestCase):
# Tests concerning submission data
def test_a_student_submissions_contains_type_name(self):
self.assertEqual(
self.submission_list_first_entry['typeName'],
self.student.submissions.first().type.name)
self.submission_list_first_entry['type']['name'],
self.student_info.submissions.first().type.name)
def test_a_student_submissions_contains_type_id(self):
self.assertEqual(
self.submission_list_first_entry['typeId'],
self.student.submissions.first().type.id)
self.submission_list_first_entry['type']['id'],
self.student_info.submissions.first().type.id)
def test_submission_data_contains_full_score(self):
self.assertEqual(
self.submission_list_first_entry['fullScore'],
self.student.submissions.first().type.full_score)
self.submission_list_first_entry['type']['fullScore'],
self.student_info.submissions.first().type.full_score)
def test_submission_data_contains_text(self):
def test_submission_data_contains_description(self):
self.assertEqual(
self.submission_list_first_entry['text'],
self.student.submissions.first().text)
self.submission_list_first_entry['type']['description'],
self.student_info.submissions.first().type.description)
def test_submission_data_contains_feedback_score(self):
def test_submission_data_contains_solution(self):
self.assertEqual(
self.submission_list_first_entry['type']['solution'],
self.student_info.submissions.first().type.solution)
def test_submission_data_contains_final_status(self):
self.assertEqual(
self.submission_list_first_entry['score'],
self.student.submissions.first().feedback.score)
self.submission_list_first_entry['feedback']['isFinal'],
self.student_info.submissions.first().feedback.is_final)
def test_submission_data_contains_feedback_text(self):
def test_submission_data_contains_feedback_score(self):
self.assertEqual(
self.submission_list_first_entry['feedback'],
self.student.submissions.first().feedback.text)
self.submission_list_first_entry['feedback']['score'],
self.student_info.submissions.first().feedback.score)
# We don't want a matriculation number here
def test_matriculation_number_is_not_send(self):
......
......@@ -69,5 +69,6 @@ class StudentPageTests(APITestCase):
self.response.data[0]['submissions'][0]['score'])
def test_submissions_full_score_is_included(self):
print(self.response.data[0]['submissions'][0])
self.assertEqual(self.student.submissions.first().type.full_score,
self.response.data[0]['submissions'][0]['fullScore'])
......@@ -62,7 +62,7 @@ class SubmissionTypeViewTestRetrieve(APITestCase):
self.assertEqual(self.response.status_code, status.HTTP_200_OK)
def test_get_id(self):
self.assertEqual(self.pk, self.response.data['typeId'])
self.assertEqual(self.pk, self.response.data['id'])
def test_get_sumbission_type_name(self):
self.assertEqual('Hard question', self.response.data['name'])
......
......@@ -247,17 +247,13 @@ def init_test_instance():
' asasxasx\n'
' lorem ipsum und so\n',
'type': '02. Merge this or that or maybe even this',
'user': 'student01'
},
{
'text': 'function blabl\n'
' on multi lines\n'
' for blabla in bla:\n'
' arrrgh\n'
' asasxasx\n'
' lorem ipsum und so\n',
'type': '03. This one exists for the sole purpose to test',
'user': 'student01'
'user': 'student01',
'feedback': {
'text': 'Not good!',
'score': 5,
'of_tutor': 'tutor01',
'is_final': True
}
},
{
'text': 'function blabl\n'
......@@ -267,7 +263,13 @@ def init_test_instance():
' asasxasx\n'
' lorem ipsum und so\n',
'type': '03. This one exists for the sole purpose to test',
'user': 'student02'
'user': 'student01',
'feedback': {
'text': 'Not good!',
'score': 5,
'of_tutor': 'tutor01',
'is_final': True
}
},
]}
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment