Files
MathApp/content/tests_lesson_texts.py
Zareian 8cb1ecb85e Subjects per grade (math, calculus, geometry, stats, discrete), 5 new textbooks, 202 new islands, long islands split, hand-written figures and lesson texts for the new books
- content.Subject + Unit.subject, /api/home?subject=, tutor grounded in the chosen book
- 5 new books ingested; ~1150 hand-written questions, islands named by hand
- node_split: islands over 7 lessons split into parts of <=6 (lesson ids and progress kept)
- Lesson.figures hand-authored and visually checked for 653 lessons of the new books;
  gen_lesson_figures got --subject and survives network errors
- seed files re-exported

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 05:35:18 +03:30

94 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""متن‌های درس و فصل: پر شدن از کتاب، و اینکه دیپلوی ویرایشِ ادمین را بازنویسی نکند."""
import json
from django.core.management import call_command
from django.test import TestCase
from content.curriculum_io import export_curriculum, import_curriculum, parse
from content.management.commands.fill_lesson_texts import related, split_steps, unit_blurb
from content.models import Choice, Grade, Lesson, Node, Question, Unit
from rag.models import LessonChunk
def _curriculum(blurb='', example='', steps=None):
return json.dumps({'grades': [{'title': 'پایه آزمون', 'units': [{
'subject': 'ریاضی', 'title': 'فصل ۱', 'blurb': blurb, 'nodes': [{'title': 'جزیره', 'lessons': [
{'title': 'درس', 'introText': 'توضیح', 'example': example, 'steps': steps or []},
]}],
}]}]}).encode()
class SeedKeepsAdminEditsTests(TestCase):
def test_empty_fields_are_filled_from_the_file(self):
import_curriculum(parse(_curriculum()))
import_curriculum(parse(_curriculum('در این فصل: جزیره.', 'مثال', ['قدم ۱'])))
lesson = Lesson.objects.get(title='درس')
self.assertEqual((lesson.example, lesson.steps), ('مثال', ['قدم ۱']))
self.assertEqual(Unit.objects.get(title='فصل ۱').blurb, 'در این فصل: جزیره.')
def test_text_written_in_admin_survives_the_next_deploy(self):
import_curriculum(parse(_curriculum()))
Lesson.objects.filter(title='درس').update(example='نوشته‌ی ادمین', steps=['قدمِ ادمین'])
Unit.objects.filter(title='فصل ۱').update(blurb='توضیحِ ادمین')
import_curriculum(parse(_curriculum('از فایل', 'از فایل', ['از فایل'])))
lesson = Lesson.objects.get(title='درس')
self.assertEqual((lesson.example, lesson.steps), ('نوشته‌ی ادمین', ['قدمِ ادمین']))
self.assertEqual(Unit.objects.get(title='فصل ۱').blurb, 'توضیحِ ادمین')
def test_export_round_trips(self):
import_curriculum(parse(_curriculum('توضیح', 'مثال', ['الف', 'ب'])))
out = export_curriculum(Grade.objects.filter(title='پایه آزمون'))
unit = out['grades'][0]['units'][0]
self.assertEqual(unit['blurb'], 'توضیح')
self.assertEqual(unit['nodes'][0]['lessons'][0]['steps'], ['الف', 'ب'])
class HelpersTests(TestCase):
def test_blurb_lists_islands_and_stays_short(self):
grade = Grade.objects.create(title='پایه تست')
unit = Unit.objects.create(grade=grade, title='فصل', order=1)
for i, t in enumerate(['عددهای صحیح', 'عددهای گویا', 'جمع و تفریق']):
Node.objects.create(unit=unit, title=t, order=i)
self.assertEqual(unit_blurb(unit), 'در این فصل: عددهای صحیح، عددهای گویا و جمع و تفریق.')
for i in range(20):
Node.objects.create(unit=unit, title=f'جزیره‌ی بسیار طولانیِ شماره‌ی {i}', order=10 + i)
self.assertLessEqual(len(unit_blurb(unit)), 120)
def test_steps_drop_their_own_numbering(self):
self.assertEqual(split_steps('گام 1: ضرایب\nگام 2: توان‌ها\n3) نتیجه'), ['ضرایب', 'توان‌ها', 'نتیجه'])
def test_relevance_needs_two_real_words(self):
chunk = LessonChunk(problem_type='معادله‌ی خط', problem='خط y=2x+3 را رسم کن و شیب خط را بگو')
self.assertTrue(related('رسم خط با معادله و شیب', chunk))
self.assertFalse(related('محاسبه تعداد مثلث‌های ممکن با شرایط داده شده', chunk))
class FillCommandTests(TestCase):
"""مثالِ درس از دومین مسئله‌ی تأییدشده، هرگز همان مسئله‌ی آزمون."""
def setUp(self):
grade = Grade.objects.create(title='پایه هشتم', number=8)
unit = Unit.objects.create(grade=grade, title='فصل ۱', order=1)
node = Node.objects.create(unit=unit, title='جزیره', order=1)
self.lesson = Lesson.objects.create(node=node, title='جمع کسرها', intro_text='x')
q = Question.objects.create(lesson=self.lesson, type='multiple_choice', prompt='۱/۲ + ۱/۴ = ?')
Choice.objects.create(question=q, value='3/4', is_correct=True)
common = {'collection': 'ریاضی هشتم', 'problem_type': 'جمع کسرها', 'solution_verdict': 'agrees',
'grade_title': 'هشتم', 'lesson_number': 1, 'chapter': 1, 'subject': 'ریاضی'}
LessonChunk.objects.create(order=1, problem='اولی: ۱/۲ + ۱/۴', solution='مخرج مشترک ۴\nجواب ۳/۴', checked_answer='3/4', **common)
LessonChunk.objects.create(order=2, problem='دومی با همان جواب', solution='...\n۳/۴', checked_answer='3 / 4', **common)
LessonChunk.objects.create(order=3, problem='سومی: ۱/۳ + ۱/۶', solution='مخرج مشترک ۶\n۲/۶ + ۱/۶ = ۳/۶', checked_answer='1/2', **common)
def test_example_skips_the_quiz_problem_and_its_answer(self):
call_command('fill_lesson_texts', verbosity=0)
self.lesson.refresh_from_db()
self.assertTrue(self.lesson.example.startswith('سومی'))
self.assertEqual(self.lesson.steps[-1], '✅ جواب: 1/2')
def test_second_run_changes_nothing(self):
call_command('fill_lesson_texts', verbosity=0)
Lesson.objects.filter(pk=self.lesson.pk).update(example='ادمین')
call_command('fill_lesson_texts', verbosity=0)
self.lesson.refresh_from_db()
self.assertEqual(self.lesson.example, 'ادمین')