Commit 17768114904009e2b6776400c739d2e3e6aad62b
1 parent
d818aecbc5
Exists in
master
Fixed the Study-related views. Wrote tests for them.
Showing 5 changed files with 74 additions and 13 deletions Side-by-side Diff
flashcards/fields.py
View file @
1776811
... | ... | @@ -40,7 +40,7 @@ |
40 | 40 | def to_python(self, value): |
41 | 41 | if value is None: |
42 | 42 | return value |
43 | - return sorted(list(FlashcardMask(value))) | |
43 | + return FlashcardMask(value) | |
44 | 44 | |
45 | 45 | def get_prep_value(self, value): |
46 | 46 | if value is None: |
... | ... | @@ -65,7 +65,7 @@ |
65 | 65 | @classmethod |
66 | 66 | def _varchar_parse_mask(cls, value): |
67 | 67 | if not value: |
68 | - return FlashcardMask([]) | |
68 | + return FlashcardMask([]) | |
69 | 69 | |
70 | 70 | mask = [tuple(map(int, i.split('-'))) for i in value.split(',')] |
71 | 71 | return FlashcardMask(mask) |
flashcards/serializers.py
View file @
1776811
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | from flashcards.models import Section, LecturePeriod, User, Flashcard, UserFlashcard, UserFlashcardQuiz |
7 | 7 | from flashcards.validators import FlashcardMask, OverlapIntervalException |
8 | 8 | from rest_framework import serializers |
9 | -from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField | |
9 | +from rest_framework.fields import EmailField, BooleanField, CharField, IntegerField, DateTimeField, empty | |
10 | 10 | from rest_framework.serializers import ModelSerializer, Serializer, PrimaryKeyRelatedField, ListField |
11 | 11 | from rest_framework.validators import UniqueValidator |
12 | 12 | from flashy.settings import QUARTER_END, QUARTER_START |
... | ... | @@ -168,7 +168,8 @@ |
168 | 168 | |
169 | 169 | |
170 | 170 | class QuizRequestSerializer(serializers.Serializer): |
171 | - sections = PrimaryKeyRelatedField(queryset=Section.objects.all(),required=False, many=True) | |
171 | + # sections = PrimaryKeyRelatedField(queryset=Section.objects.all(),required=False, many=True) | |
172 | + sections = ListField(child=IntegerField(min_value=1), required=False) | |
172 | 173 | material_date_begin = DateTimeField(default=QUARTER_START) |
173 | 174 | material_date_end = DateTimeField(default=QUARTER_END) |
174 | 175 | |
... | ... | @@ -207,7 +208,6 @@ |
207 | 208 | raise serializers.ValidationError("Invalid end date for the flashcard range") |
208 | 209 | |
209 | 210 | def validate_sections(self, value): |
210 | - print "VALUE", type(value), value | |
211 | 211 | if value is None: |
212 | 212 | return self.user.sections |
213 | 213 | section_filter = Section.objects.filter(pk__in=value) |
... | ... | @@ -230,7 +230,7 @@ |
230 | 230 | text = CharField(max_length=255) |
231 | 231 | mask = ListField(child=IntegerField()) |
232 | 232 | |
233 | - def __init__(self, instance=None, mask=[], data=None, **kwargs): | |
233 | + def __init__(self, instance=None, mask=[], data=empty, **kwargs): | |
234 | 234 | super(QuizResponseSerializer, self).__init__(instance=instance, data=data, **kwargs) |
235 | 235 | self.mask = self._validate_mask(mask) |
236 | 236 | |
... | ... | @@ -247,7 +247,7 @@ |
247 | 247 | raise serializers.ValidationError("The selected mask has to be a list") |
248 | 248 | if value is None or len(value) == 0: |
249 | 249 | return [] |
250 | - if len(value) == 2 and (0 <= value[0] and len(self.initial_data['text']) < value[1]): | |
250 | + if len(value) == 2 and (0 <= value[0] and value[1] <= len(self.instance.user_flashcard.flashcard.text)): | |
251 | 251 | return value |
252 | 252 | raise serializers.ValidationError("Invalid mask for the flashcard") |
253 | 253 | |
... | ... | @@ -261,7 +261,7 @@ |
261 | 261 | |
262 | 262 | def __init__(self, instance, data, **kwargs): |
263 | 263 | assert isinstance(instance, UserFlashcardQuiz) |
264 | - super(QuizAnswerRequestSerializer, self).__init__(instance, data, kwargs) | |
264 | + super(QuizAnswerRequestSerializer, self).__init__(instance, data, **kwargs) | |
265 | 265 | |
266 | 266 | def validate_response(self, response): |
267 | 267 | if response is None: |
flashcards/tests/test_models.py
View file @
1776811
1 | 1 | from datetime import datetime |
2 | 2 | |
3 | 3 | from django.test import TestCase |
4 | -from flashcards.models import User, Section, Flashcard, UserFlashcard | |
4 | +from flashcards.models import User, Section, Flashcard, UserFlashcard, UserFlashcardQuiz | |
5 | 5 | from flashcards.validators import FlashcardMask, OverlapIntervalException |
6 | +from flashcards.serializers import QuizRequestSerializer, QuizResponseSerializer, QuizAnswerRequestSerializer | |
7 | +from flashy.settings import QUARTER_START, QUARTER_END | |
6 | 8 | |
7 | 9 | |
8 | 10 | class RegistrationTests(TestCase): |
... | ... | @@ -98,7 +100,6 @@ |
98 | 100 | self.assertEqual(oie.message, "Invalid interval offsets in the mask") |
99 | 101 | |
100 | 102 | |
101 | - | |
102 | 103 | class FlashcardTests(TestCase): |
103 | 104 | def setUp(self): |
104 | 105 | section = Section.objects.create(department='dept', |
... | ... | @@ -113,7 +114,7 @@ |
113 | 114 | author=user, |
114 | 115 | material_date=datetime.now(), |
115 | 116 | previous=None, |
116 | - mask={(24,34), (0, 4)}) | |
117 | + mask={(24, 34), (0, 4)}) | |
117 | 118 | user.save() |
118 | 119 | section.save() |
119 | 120 | flashcard.save() |
... | ... | @@ -148,4 +149,64 @@ |
148 | 149 | self.fail() |
149 | 150 | except OverlapIntervalException: |
150 | 151 | self.assertTrue(True) |
152 | + | |
153 | + | |
154 | +class UserFlashcardQuizTests(TestCase): | |
155 | + def setUp(self): | |
156 | + self.section = Section.objects.create(department='dept', | |
157 | + course_num='101a', | |
158 | + course_title='how 2 test', | |
159 | + instructor='George Lucas', | |
160 | + quarter='SP15') | |
161 | + self.user = User.objects.create_user(email="none@none.com", password="1234") | |
162 | + self.user.sections.add(self.section) | |
163 | + self.flashcard = Flashcard.objects.create(text="This is the text of the Flashcard", | |
164 | + section=self.section, | |
165 | + author=self.user, | |
166 | + material_date=datetime.now(), | |
167 | + previous=None, | |
168 | + mask=[(24, 33), (0, 4)]) | |
169 | + self.user.save() | |
170 | + self.section.save() | |
171 | + self.flashcard.save() | |
172 | + self.user_flashcard = UserFlashcard.objects.create(flashcard=self.flashcard, | |
173 | + user=self.user, | |
174 | + mask=self.flashcard.mask, | |
175 | + pulled=datetime.now()) | |
176 | + self.user_flashcard.save() | |
177 | + self.user_flashcard.refresh_from_db() | |
178 | + self.flashcard.refresh_from_db() | |
179 | + | |
180 | + def test_quiz_request(self): | |
181 | + data = {'sections': [1], 'material_date_begin': QUARTER_START, 'material_date_end': QUARTER_END} | |
182 | + serializer = QuizRequestSerializer(user=self.user, data=data) | |
183 | + serializer.is_valid(raise_exception=True) | |
184 | + user_flashcard_quiz = serializer.create(serializer.validated_data) | |
185 | + self.assertTrue(isinstance(user_flashcard_quiz, UserFlashcardQuiz)) | |
186 | + mask = user_flashcard_quiz.user_flashcard.mask.get_random_blank() | |
187 | + self.assertIn(mask, [(24, 33), (0, 4)]) | |
188 | + user_flashcard_quiz.blanked_word = user_flashcard_quiz.user_flashcard.flashcard.text[slice(*mask)] | |
189 | + self.assertIn(user_flashcard_quiz.blanked_word, ["This", "Flashcard"]) | |
190 | + user_flashcard_quiz.save() | |
191 | + response = QuizResponseSerializer(instance=user_flashcard_quiz, mask=mask).data | |
192 | + self.assertEqual(response['pk'], 1) | |
193 | + self.assertEqual(response['section'], 1) | |
194 | + self.assertEqual(response['text'], user_flashcard_quiz.user_flashcard.flashcard.text) | |
195 | + self.assertEqual(response['mask'], mask) | |
196 | + | |
197 | + def test_quiz_answer(self): | |
198 | + data = {'response': 'Flashcard'} | |
199 | + mask = self.user_flashcard.mask.get_random_blank() | |
200 | + word = self.flashcard.text[slice(*mask)] | |
201 | + user_flashcard_quiz = UserFlashcardQuiz(user_flashcard=self.user_flashcard, blanked_word=word) | |
202 | + user_flashcard_quiz.save() | |
203 | + serializer = QuizAnswerRequestSerializer(instance=user_flashcard_quiz, data=data) | |
204 | + serializer.is_valid() | |
205 | + serializer.update(user_flashcard_quiz, serializer.validated_data) | |
206 | + self.assertEqual(user_flashcard_quiz.response, data['response']) | |
207 | + data = {'correct': True} | |
208 | + serializer = QuizAnswerRequestSerializer(instance=user_flashcard_quiz, data=data) | |
209 | + serializer.is_valid() | |
210 | + serializer.update(user_flashcard_quiz, serializer.validated_data) | |
211 | + self.assertTrue(user_flashcard_quiz.correct) |
flashcards/validators.py
View file @
1776811
flashcards/views.py
View file @
1776811
... | ... | @@ -351,7 +351,7 @@ |
351 | 351 | """ |
352 | 352 | serializer = QuizRequestSerializer(data=request.data) |
353 | 353 | serializer.is_valid(raise_exception=True) |
354 | - user_flashcard_quiz = serializer.create() | |
354 | + user_flashcard_quiz = serializer.create(serializer.validated_data) | |
355 | 355 | mask = sample(user_flashcard_quiz.user_flashcard.mask.get_random_blank(), 1) |
356 | 356 | user_flashcard_quiz.blanked_word = user_flashcard_quiz.user_flashcard.flashcard.text[slice(*mask)] |
357 | 357 | user_flashcard_quiz.save() |