"""شکلِ سوال: ورود از فایل، خروج، و پاسخِ API. شکلِ نامعتبر باید فایل را رد کند، نه بی‌صدا حذف شود.""" import json from django.core.cache import cache from django.test import TestCase from content import question_io from content.models import Grade, Lesson, Node, Question, Unit FIGURE = {'kind': 'bar', 'title': 'میوه‌ها', 'labels': ['سیب', 'پرتقال'], 'values': [5, 8]} class QuestionFigureTests(TestCase): def setUp(self): cache.clear() grade = Grade.objects.create(title='پایه سوم', icon='', color='') unit = Unit.objects.create(grade=grade, title='فصل ۱', order=1) self.node = Node.objects.create(unit=unit, title='آمار', order=1) self.lesson = Lesson.objects.create(node=self.node, title='نمودار') def _row(self, **extra): return {'lessonId': self.lesson.pk, 'prompt': 'کدام میوه بیشتر است؟', 'type': 'multiple_choice', 'choices': ['سیب', 'پرتقال'], 'correct': 1, **extra} def test_valid_figure_is_stored_and_exported(self): rows = question_io.parse(json.dumps([self._row(figure=FIGURE)]).encode()) question_io.import_questions(rows) q = Question.objects.get() self.assertEqual(q.figure['kind'], 'bar') exported = question_io.export_questions(Question.objects.all()) self.assertEqual(exported[0]['figure']['kind'], 'bar') def test_question_without_figure_exports_without_the_key(self): question_io.import_questions(question_io.parse(json.dumps([self._row()]).encode())) self.assertNotIn('figure', question_io.export_questions(Question.objects.all())[0]) def test_invalid_figure_rejects_the_file(self): with self.assertRaises(question_io.ImportError_): question_io.parse(json.dumps([self._row(figure={'kind': 'nope'})]).encode()) def test_quiz_api_returns_the_figure(self): question_io.import_questions(question_io.parse(json.dumps([self._row(figure=FIGURE)]).encode())) body = self.client.get(f'/api/nodes/{self.node.pk}/quiz?seed=1').json() self.assertEqual(body['questions'][0]['figure']['kind'], 'bar') plain = self.client.get(f'/api/lessons/{self.lesson.pk}/questions').json() self.assertEqual(plain['questions'][0]['figure']['kind'], 'bar')