From 17768114904009e2b6776400c739d2e3e6aad62b Mon Sep 17 00:00:00 2001 From: Rohan Rangray Date: Wed, 20 May 2015 01:23:33 -0700 Subject: [PATCH] Fixed the Study-related views. Wrote tests for them. --- flashcards/fields.py | 4 +-- flashcards/serializers.py | 12 ++++---- flashcards/tests/test_models.py | 67 +++++++++++++++++++++++++++++++++++++++-- flashcards/validators.py | 2 +- flashcards/views.py | 2 +- 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/flashcards/fields.py b/flashcards/fields.py index c3b124e..6685491 100644 --- a/flashcards/fields.py +++ b/flashcards/fields.py @@ -40,7 +40,7 @@ class MaskField(models.Field): def to_python(self, value): if value is None: return value - return sorted(list(FlashcardMask(value))) + return FlashcardMask(value) def get_prep_value(self, value): if value is None: @@ -65,7 +65,7 @@ class MaskField(models.Field): @classmethod def _varchar_parse_mask(cls, value): if not value: - return FlashcardMask([]) + return FlashcardMask([]) mask = [tuple(map(int, i.split('-'))) for i in value.split(',')] return FlashcardMask(mask) diff --git a/flashcards/serializers.py b/flashcards/serializers.py index 0293904..0057cce 100644 --- a/flashcards/serializers.py +++ b/flashcards/serializers.py @@ -6,7 +6,7 @@ import pytz from flashcards.models import Section, LecturePeriod, User, Flashcard, UserFlashcard, UserFlashcardQuiz from flashcards.validators import FlashcardMask, OverlapIntervalException from rest_framework import serializers -from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField +from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField, empty from rest_framework.serializers import ModelSerializer, Serializer, PrimaryKeyRelatedField, ListField from rest_framework.validators import UniqueValidator from flashy.settings import QUARTER_END, QUARTER_START @@ -168,7 +168,8 @@ class FlashcardUpdateSerializer(serializers.Serializer): class QuizRequestSerializer(serializers.Serializer): - sections = PrimaryKeyRelatedField(queryset=Section.objects.all(),required=False, many=True) + # sections = PrimaryKeyRelatedField(queryset=Section.objects.all(),required=False, many=True) + sections = ListField(child=IntegerField(min_value=1), required=False) material_date_begin = DateTimeField(default=QUARTER_START) material_date_end = DateTimeField(default=QUARTER_END) @@ -207,7 +208,6 @@ class QuizRequestSerializer(serializers.Serializer): raise serializers.ValidationError("Invalid end date for the flashcard range") def validate_sections(self, value): - print "VALUE", type(value), value if value is None: return self.user.sections section_filter = Section.objects.filter(pk__in=value) @@ -230,7 +230,7 @@ class QuizResponseSerializer(ModelSerializer): text = CharField(max_length=255) mask = ListField(child=IntegerField()) - def __init__(self, instance=None, mask=[], data=None, **kwargs): + def __init__(self, instance=None, mask=[], data=empty, **kwargs): super(QuizResponseSerializer, self).__init__(instance=instance, data=data, **kwargs) self.mask = self._validate_mask(mask) @@ -247,7 +247,7 @@ class QuizResponseSerializer(ModelSerializer): raise serializers.ValidationError("The selected mask has to be a list") if value is None or len(value) == 0: return [] - if len(value) == 2 and (0 <= value[0] and len(self.initial_data['text']) < value[1]): + if len(value) == 2 and (0 <= value[0] and value[1] <= len(self.instance.user_flashcard.flashcard.text)): return value raise serializers.ValidationError("Invalid mask for the flashcard") @@ -261,7 +261,7 @@ class QuizAnswerRequestSerializer(ModelSerializer): def __init__(self, instance, data, **kwargs): assert isinstance(instance, UserFlashcardQuiz) - super(QuizAnswerRequestSerializer, self).__init__(instance, data, kwargs) + super(QuizAnswerRequestSerializer, self).__init__(instance, data, **kwargs) def validate_response(self, response): if response is None: diff --git a/flashcards/tests/test_models.py b/flashcards/tests/test_models.py index 287077a..22c3700 100644 --- a/flashcards/tests/test_models.py +++ b/flashcards/tests/test_models.py @@ -1,8 +1,10 @@ from datetime import datetime from django.test import TestCase -from flashcards.models import User, Section, Flashcard, UserFlashcard +from flashcards.models import User, Section, Flashcard, UserFlashcard, UserFlashcardQuiz from flashcards.validators import FlashcardMask, OverlapIntervalException +from flashcards.serializers import QuizRequestSerializer, QuizResponseSerializer, QuizAnswerRequestSerializer +from flashy.settings import QUARTER_START, QUARTER_END class RegistrationTests(TestCase): @@ -98,7 +100,6 @@ class FlashcardMaskTest(TestCase): self.assertEqual(oie.message, "Invalid interval offsets in the mask") - class FlashcardTests(TestCase): def setUp(self): section = Section.objects.create(department='dept', @@ -113,7 +114,7 @@ class FlashcardTests(TestCase): author=user, material_date=datetime.now(), previous=None, - mask={(24,34), (0, 4)}) + mask={(24, 34), (0, 4)}) user.save() section.save() flashcard.save() @@ -148,3 +149,63 @@ class FlashcardTests(TestCase): self.fail() except OverlapIntervalException: self.assertTrue(True) + + +class UserFlashcardQuizTests(TestCase): + def setUp(self): + self.section = Section.objects.create(department='dept', + course_num='101a', + course_title='how 2 test', + instructor='George Lucas', + quarter='SP15') + self.user = User.objects.create_user(email="none@none.com", password="1234") + self.user.sections.add(self.section) + self.flashcard = Flashcard.objects.create(text="This is the text of the Flashcard", + section=self.section, + author=self.user, + material_date=datetime.now(), + previous=None, + mask=[(24, 33), (0, 4)]) + self.user.save() + self.section.save() + self.flashcard.save() + self.user_flashcard = UserFlashcard.objects.create(flashcard=self.flashcard, + user=self.user, + mask=self.flashcard.mask, + pulled=datetime.now()) + self.user_flashcard.save() + self.user_flashcard.refresh_from_db() + self.flashcard.refresh_from_db() + + def test_quiz_request(self): + data = {'sections': [1], 'material_date_begin': QUARTER_START, 'material_date_end': QUARTER_END} + serializer = QuizRequestSerializer(user=self.user, data=data) + serializer.is_valid(raise_exception=True) + user_flashcard_quiz = serializer.create(serializer.validated_data) + self.assertTrue(isinstance(user_flashcard_quiz, UserFlashcardQuiz)) + mask = user_flashcard_quiz.user_flashcard.mask.get_random_blank() + self.assertIn(mask, [(24, 33), (0, 4)]) + user_flashcard_quiz.blanked_word = user_flashcard_quiz.user_flashcard.flashcard.text[slice(*mask)] + self.assertIn(user_flashcard_quiz.blanked_word, ["This", "Flashcard"]) + user_flashcard_quiz.save() + response = QuizResponseSerializer(instance=user_flashcard_quiz, mask=mask).data + self.assertEqual(response['pk'], 1) + self.assertEqual(response['section'], 1) + self.assertEqual(response['text'], user_flashcard_quiz.user_flashcard.flashcard.text) + self.assertEqual(response['mask'], mask) + + def test_quiz_answer(self): + data = {'response': 'Flashcard'} + mask = self.user_flashcard.mask.get_random_blank() + word = self.flashcard.text[slice(*mask)] + user_flashcard_quiz = UserFlashcardQuiz(user_flashcard=self.user_flashcard, blanked_word=word) + user_flashcard_quiz.save() + serializer = QuizAnswerRequestSerializer(instance=user_flashcard_quiz, data=data) + serializer.is_valid() + serializer.update(user_flashcard_quiz, serializer.validated_data) + self.assertEqual(user_flashcard_quiz.response, data['response']) + data = {'correct': True} + serializer = QuizAnswerRequestSerializer(instance=user_flashcard_quiz, data=data) + serializer.is_valid() + serializer.update(user_flashcard_quiz, serializer.validated_data) + self.assertTrue(user_flashcard_quiz.correct) diff --git a/flashcards/validators.py b/flashcards/validators.py index 64ac37f..8295436 100644 --- a/flashcards/validators.py +++ b/flashcards/validators.py @@ -17,7 +17,7 @@ class FlashcardMask(set): def get_random_blank(self): if self.max_offset() > 0: - return sample(self, 1) + return sample(self, 1)[0] return () def _iterable_check(self, iterable): diff --git a/flashcards/views.py b/flashcards/views.py index dd506e9..e0929b3 100644 --- a/flashcards/views.py +++ b/flashcards/views.py @@ -351,7 +351,7 @@ class UserFlashcardQuizViewSet(GenericViewSet, CreateModelMixin, UpdateModelMixi """ serializer = QuizRequestSerializer(data=request.data) serializer.is_valid(raise_exception=True) - user_flashcard_quiz = serializer.create() + user_flashcard_quiz = serializer.create(serializer.validated_data) mask = sample(user_flashcard_quiz.user_flashcard.mask.get_random_blank(), 1) user_flashcard_quiz.blanked_word = user_flashcard_quiz.user_flashcard.flashcard.text[slice(*mask)] user_flashcard_quiz.save() -- 1.9.1