diff options
Diffstat (limited to 'yaksh/test_views.py')
-rw-r--r-- | yaksh/test_views.py | 1392 |
1 files changed, 1329 insertions, 63 deletions
diff --git a/yaksh/test_views.py b/yaksh/test_views.py index a7ccac2..4e1343e 100644 --- a/yaksh/test_views.py +++ b/yaksh/test_views.py @@ -22,6 +22,7 @@ from django.conf import settings from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files import File from django.contrib.messages import get_messages +from django.contrib.contenttypes.models import ContentType from celery.contrib.testing.worker import start_worker from django.test import SimpleTestCase @@ -30,7 +31,8 @@ from yaksh.models import ( User, Profile, Question, Quiz, QuestionPaper, AnswerPaper, Answer, Course, AssignmentUpload, McqTestCase, IntegerTestCase, StringTestCase, FloatTestCase, FIXTURES_DIR_PATH, LearningModule, LearningUnit, Lesson, - LessonFile, CourseStatus, dict_to_yaml, Post, Comment + LessonFile, CourseStatus, dict_to_yaml, Post, Comment, Topic, + TableOfContents, LessonQuizAnswer ) from yaksh.views import add_as_moderator, course_forum, post_comments from yaksh.forms import PostForm, CommentForm @@ -2564,6 +2566,372 @@ class TestAddCourse(TestCase): target_status_code=301) +class TestUploadMarks(TestCase): + def setUp(self): + self.client = Client() + + self.mod_group = Group.objects.create(name='moderator') + + # Create Moderator with profile + self.teacher = User.objects.create_user( + username='teacher', + password='teacher', + first_name='teacher', + last_name='teaacher', + email='teacher@test.com' + ) + + Profile.objects.create( + user=self.teacher, + roll_number=101, + institute='IIT', + department='Chemical', + position='Moderator', + timezone='UTC', + is_moderator=True + ) + + self.TA = User.objects.create_user( + username='TA', + password='TA', + first_name='TA', + last_name='TA', + email='TA@test.com' + ) + + Profile.objects.create( + user=self.TA, + roll_number=102, + institute='IIT', + department='Aeronautical', + position='Moderator', + timezone='UTC', + is_moderator=True + ) + + # Create Student + self.student1 = User.objects.create_user( + username='student1', + password='student1', + first_name='student_first_name', + last_name='student_last_name', + email='demo_student1@test.com' + ) + self.student2 = User.objects.create_user( + username='student2', + password='student2', + first_name='student_first_name', + last_name='student_last_name', + email='demo_student2@test.com' + ) + + # Add to moderator group + self.mod_group.user_set.add(self.teacher) + self.mod_group.user_set.add(self.TA) + + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.teacher + ) + + self.question1 = Question.objects.create( + id=1212, summary='Dummy1', points=1, + type='code', user=self.teacher + ) + self.question2 = Question.objects.create( + id=1213, summary='Dummy2', points=1, + type='code', user=self.teacher + ) + + self.quiz = Quiz.objects.create(time_between_attempts=0, + description='demo quiz') + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=2.0 + ) + self.question_paper.fixed_questions.add(self.question1) + self.question_paper.fixed_questions.add(self.question2) + self.question_paper.save() + + self.ans_paper1 = AnswerPaper.objects.create( + user=self.student1, attempt_number=1, + question_paper=self.question_paper, start_time=timezone.now(), + user_ip='101.0.0.1', course=self.course, + end_time=timezone.now()+timezone.timedelta(minutes=20) + ) + self.ans_paper2 = AnswerPaper.objects.create( + user=self.student2, attempt_number=1, + question_paper=self.question_paper, start_time=timezone.now(), + user_ip='101.0.0.1', course=self.course, + end_time=timezone.now()+timezone.timedelta(minutes=20) + ) + self.answer1 = Answer( + question=self.question1, answer="answer1", + correct=False, error=json.dumps([]), marks=0 + ) + self.answer2 = Answer( + question=self.question2, answer="answer2", + correct=False, error=json.dumps([]), marks=0 + ) + self.answer12 = Answer( + question=self.question1, answer="answer12", + correct=False, error=json.dumps([]), marks=0 + ) + self.answer1.save() + self.answer12.save() + self.answer2.save() + self.ans_paper1.answers.add(self.answer1) + self.ans_paper1.answers.add(self.answer2) + self.ans_paper2.answers.add(self.answer12) + self.ans_paper1.questions_answered.add(self.question1) + self.ans_paper1.questions_answered.add(self.question2) + self.ans_paper2.questions_answered.add(self.question1) + self.ans_paper1.questions.add(self.question1) + self.ans_paper1.questions.add(self.question2) + self.ans_paper2.questions.add(self.question1) + self.ans_paper2.questions.add(self.question2) + + def tearDown(self): + self.client.logout() + self.student1.delete() + self.student2.delete() + self.TA.delete() + self.teacher.delete() + self.course.delete() + self.ans_paper1.delete() + self.ans_paper2.delete() + self.question_paper.delete() + self.quiz.delete() + self.question1.delete() + self.question2.delete() + self.mod_group.delete() + + def test_upload_users_marks_not_attempted_question(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_not_attempted_question.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + ans_paper = AnswerPaper.objects.get(user=self.student2, + question_paper=self.question_paper, + course=self.course) + self.assertEqual(ans_paper.marks_obtained, 1.3) + answer = Answer.objects.get(answer='answer12') + self.assertEqual(answer.comment.strip(), 'very good') + + def test_upload_users_marks_invalid_question_id(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_invalid_question_id.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + + def test_upload_users_marks_invalid_user(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_invalid_user.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + + def test_upload_users_marks_invalid_data(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_invalid_data.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + + def test_upload_users_marks_headers_missing(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_header_missing.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + ans_paper = AnswerPaper.objects.get(user=self.student1, + question_paper=self.question_paper, + course=self.course) + self.assertEqual(ans_paper.marks_obtained, 0.9) + + def test_upload_users_marks_headers_modified(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_header_modified.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + answer = Answer.objects.get(answer='answer1') + self.assertEqual(answer.comment.strip(), 'fine work') + self.assertNotEqual(answer.marks, 0.75) + answer = Answer.objects.get(answer='answer2') + self.assertEqual(answer.comment.strip(), 'not nice') + + def test_upload_users_marks_csv_single_question(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "marks_single_question.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + ans_paper = AnswerPaper.objects.get(user=self.student1, + question_paper=self.question_paper, + course=self.course) + self.assertEqual(ans_paper.marks_obtained, 0.5) + answer = Answer.objects.get(answer='answer1') + self.assertEqual(answer.comment.strip(), 'okay work') + + def test_upload_users_with_correct_csv(self): + # Given + self.client.login( + username=self.teacher.username, + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, "marks_correct.csv") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + ans_paper = AnswerPaper.objects.get(user=self.student1, + question_paper=self.question_paper, + course=self.course) + self.assertEqual(ans_paper.marks_obtained, 2) + answer = Answer.objects.get(answer='answer1') + self.assertEqual(answer.comment.strip(), 'good work') + + def test_upload_users_with_wrong_csv(self): + # Given + self.client.login( + username='teacher', + password='teacher' + ) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, "demo_questions.zip") + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + message = "The file uploaded is not a CSV file." + + # When + response = self.client.post( + reverse('yaksh:upload_marks', + kwargs={'course_id': self.course.id, + 'questionpaper_id': self.question_paper.id}), + data={'csv_file': upload_file}) + csv_file.close() + + # Then + self.assertEqual(response.status_code, 302) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual('The file uploaded is not a CSV file.', messages[0]) + + class TestCourseDetail(TestCase): def setUp(self): self.client = Client() @@ -2755,6 +3123,33 @@ class TestCourseDetail(TestCase): id=uploaded_users.first().id).exists() ) + def test_upload_existing_user_email(self): + # Given + self.client.login( + username=self.user1.username, password=self.user1_plaintext_pass) + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + 'user_existing_email.csv') + csv_file = open(csv_file_path, 'rb') + upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) + csv_file.close() + + # When + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) + + # Then + uploaded_users = User.objects.filter(email='demo_student@test.com') + self.assertEqual(response.status_code, 302) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertIn('demo_student', messages[0]) + self.assertTrue( + self.user1_course.students.filter( + id=uploaded_users.first().id).exists() + ) + self.assertEqual(uploaded_users.count(), 1) + def test_upload_users_add_update_reject(self): # Given self.client.login( @@ -3292,7 +3687,7 @@ class TestCourseDetail(TestCase): response = self.client.get(reverse('yaksh:download_sample_csv')) self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - 'attachment; filename="sample_user_upload"') + 'attachment; filename="sample_user_upload.csv"') def test_view_course_status(self): """ Test to view course status """ @@ -3938,6 +4333,7 @@ class TestSelfEnroll(TestCase): self.assertRedirects(response, '/exam/manage/') + class TestGrader(SimpleTestCase): allow_database_queries = True @@ -5937,12 +6333,11 @@ class TestQuestionPaper(TestCase): 'add-random': ['']} ) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed(response, 'yaksh/design_questionpaper.html') - random_set = response.context['random_sets'][0] - added_random_ques = random_set.questions.all() - self.assertIn(self.random_que1, added_random_ques) - self.assertIn(self.random_que2, added_random_ques) + self.assertEqual(response.status_code, 302) + self.assertTrue( + self.question_paper.random_questions.filter( + id__in=[self.random_que1.id, self.random_que2.id]).exists() + ) # Check if questions already exists self.client.login( @@ -5969,10 +6364,11 @@ class TestQuestionPaper(TestCase): data={'checked_ques': [self.fixed_que.id], 'add-fixed': ''} ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['qpaper'], self.fixed_question_paper) - self.assertEqual(response.context['fixed_questions'][0], - self.fixed_que) + self.assertEqual(response.status_code, 302) + self.assertTrue( + self.fixed_question_paper.fixed_questions.filter( + id=self.fixed_que.id).exists() + ) # Add one more fixed question in question paper response = self.client.post( @@ -5983,10 +6379,11 @@ class TestQuestionPaper(TestCase): data={'checked_ques': [self.question_float.id], 'add-fixed': ''} ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['qpaper'], self.fixed_question_paper) - self.assertEqual(response.context['fixed_questions'], - [self.fixed_que, self.question_float]) + self.assertEqual(response.status_code, 302) + self.assertTrue( + self.fixed_question_paper.fixed_questions.filter( + id=self.question_float.id).exists() + ) # Remove fixed question from question paper response = self.client.post( @@ -5997,10 +6394,11 @@ class TestQuestionPaper(TestCase): data={'added-questions': [self.fixed_que.id], 'remove-fixed': ''} ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['qpaper'], self.fixed_question_paper) - self.assertEqual(response.context['fixed_questions'], - [self.question_float]) + self.assertEqual(response.status_code, 302) + self.assertFalse( + self.fixed_question_paper.fixed_questions.filter( + id=self.fixed_que.id).exists() + ) # Remove one more fixed question from question paper response = self.client.post( @@ -6011,9 +6409,11 @@ class TestQuestionPaper(TestCase): data={'added-questions': [self.question_float.id], 'remove-fixed': ''} ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['qpaper'], self.fixed_question_paper) - self.assertEqual(response.context['fixed_questions'], []) + self.assertEqual(response.status_code, 302) + self.assertFalse( + self.fixed_question_paper.fixed_questions.filter( + id=self.question_float.id).exists() + ) # Remove random questions from question paper random_que_set = self.question_paper.random_questions.all().first() @@ -6025,9 +6425,11 @@ class TestQuestionPaper(TestCase): data={'random_sets': random_que_set.id, 'remove-random': ''} ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.context['qpaper'], self.question_paper) - self.assertEqual(len(response.context['random_sets']), 0) + self.assertEqual(response.status_code, 302) + self.assertFalse( + self.question_paper.random_questions.filter( + id=random_que_set.id).exists() + ) class TestLearningModule(TestCase): @@ -6183,7 +6585,7 @@ class TestLearningModule(TestCase): learning_module = LearningModule.objects.get(name="test module1") self.assertEqual(learning_module.description, "my test1") self.assertEqual(learning_module.creator, self.user) - self.assertTrue(learning_module.check_prerequisite) + self.assertFalse(learning_module.check_prerequisite) self.assertEqual(learning_module.html_data, Markdown().convert("my test1")) @@ -6276,7 +6678,7 @@ class TestLearningModule(TestCase): updated_learning_unit = LearningUnit.objects.get(id=learning_unit.id) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/add_module.html') - self.assertFalse(updated_learning_unit.check_prerequisite) + self.assertTrue(updated_learning_unit.check_prerequisite) # Test to remove learning unit from learning module response = self.client.post( @@ -6568,6 +6970,54 @@ class TestLessons(TestCase): lesson=self.lesson).first() self.assertIn("test", lesson_files.file.name) lesson_file_path = lesson_files.file.path + + # Teacher adds multiple videos in video path + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson.id, + "course_id": self.course.id, + "module_id": self.learning_module.id}), + data={"name": "updated lesson", + "description": "updated description", + "video_path": "{'youtube': 'test', 'others': 'test'}", + "Save": "Save"} + ) + self.assertEqual(response.status_code, 200) + self.assertIn( + "Video path : Only one type of video path is allowed", + str(response.content) + ) + + # Teacher adds wrong pattern in video path + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson.id, + "course_id": self.course.id, + "module_id": self.learning_module.id}), + data={"name": "updated lesson", + "description": "updated description", + "video_path": "test", + "Save": "Save"} + ) + self.assertEqual(response.status_code, 200) + self.assertIn( + "Video path : Value must be dictionary", + str(response.content) + ) + + # Teacher adds correct path in video path + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson.id, + "course_id": self.course.id, + "module_id": self.learning_module.id}), + data={"name": "updated lesson", + "description": "updated description", + "video_path": "{'others': 'test'}", + "Save": "Save"} + ) + self.assertEqual(response.status_code, 302) + # Teacher removes the lesson file response = self.client.post( reverse('yaksh:edit_lesson', @@ -6644,20 +7094,6 @@ class TestLessons(TestCase): self.assertEqual(response.status_code, 200) self.assertEqual(response.context["msg"], err_msg) - def test_preview_lesson_description(self): - """ Test preview lesson description converted from md to html""" - self.client.login( - username=self.teacher.username, - password=self.teacher_plaintext_pass - ) - lesson = json.dumps({'description': self.lesson.description}) - response = self.client.post( - reverse('yaksh:preview_html_text'), - data=lesson, content_type="application/json" - ) - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json()['data'], '<p>test description</p>') - class TestPost(TestCase): def setUp(self): @@ -6724,7 +7160,7 @@ class TestPost(TestCase): }) response = self.client.get(url, follow=True) self.assertEqual(response.status_code, 200) - redirection_url = '/exam/login/?next=/exam/forum/{0}/'.format( + redirection_url = '/exam/login/?next=/exam/forum/course_forum/{0}/'.format( str(self.course.id) ) self.assertRedirects(response, redirection_url) @@ -6755,7 +7191,7 @@ class TestPost(TestCase): self.assertEquals(response.status_code, 404) def test_course_forum_url_resolves_course_forum_view(self): - view = resolve('/exam/forum/1/') + view = resolve('/exam/forum/course_forum/1/') self.assertEqual(view.func, course_forum) def test_course_forum_contains_link_to_post_comments_page(self): @@ -6768,10 +7204,11 @@ class TestPost(TestCase): url = reverse('yaksh:course_forum', kwargs={ 'course_id': self.course.id }) + course_ct = ContentType.objects.get_for_model(self.course) post = Post.objects.create( title='post 1', description='post 1 description', - course=self.course, + target_ct=course_ct, target_id=self.course.id, creator=self.student ) response = self.client.get(url) @@ -6796,9 +7233,11 @@ class TestPost(TestCase): } response = self.client.post(url, data) # This shouldn't be 302. Check where does it redirects. + course_ct = ContentType.objects.get_for_model(self.course) result = Post.objects.filter(title='Post 1', creator=self.student, - course=self.course) + target_ct=course_ct, + target_id=self.course.id) self.assertTrue(result.exists()) def test_new_post_invalid_post_data(self): @@ -6831,24 +7270,12 @@ class TestPost(TestCase): self.assertEquals(response.status_code, 200) self.assertFalse(Post.objects.exists()) - def test_contains_form(self): - self.client.login( - username=self.student.username, - password=self.student_plaintext_pass - ) - self.course.students.add(self.student) - url = reverse('yaksh:course_forum', kwargs={ - 'course_id': self.course.id - }) - response = self.client.get(url) - form = response.context.get('form') - self.assertIsInstance(form, PostForm) - def test_open_created_post_denies_anonymous_user(self): + course_ct = ContentType.objects.get_for_model(self.course) post = Post.objects.create( title='post 1', description='post 1 description', - course=self.course, + target_ct=course_ct, target_id=self.course.id, creator=self.student ) url = reverse('yaksh:post_comments', kwargs={ @@ -6887,11 +7314,12 @@ class TestPost(TestCase): password=self.user_plaintext_pass ) self.course.students.add(self.user) + course_ct = ContentType.objects.get_for_model(self.course) post = Post.objects.create( title='post 1', description='post 1 description', - course=self.course, - creator=self.user + target_ct=course_ct, target_id=self.course.id, + creator=self.student ) url = reverse('yaksh:hide_post', kwargs={ 'course_id': self.course.id, @@ -6954,10 +7382,11 @@ class TestPostComment(TestCase): enrollment="Enroll Request", creator=self.user ) + course_ct = ContentType.objects.get_for_model(self.course) self.post = Post.objects.create( title='post 1', description='post 1 description', - course=self.course, + target_ct=course_ct, target_id=self.course.id, creator=self.student ) @@ -7713,3 +8142,840 @@ class TestStartExam(TestCase): self.student.delete() self.quiz1.delete() self.user1_course1.delete() + + +class TestLessonContents(TestCase): + def setUp(self): + self.client = Client() + self.mod_group = Group.objects.create(name='moderator') + tzone = pytz.timezone('UTC') + + # Create Moderator with profile + self.user1_plaintext_pass = 'demo' + self.user1 = User.objects.create_user( + username='demo_user', + password=self.user1_plaintext_pass, + first_name='first_name', + last_name='last_name', + email='demo@test.com', + ) + Profile.objects.create( + user=self.user1, + roll_number=10, + institute='IIT', + department='Chemical', + position='Moderator', + timezone='UTC', + is_moderator=True + ) + + # Add to moderator group + self.mod_group.user_set.add(self.user1) + + # Create Student + self.student_plaintext_pass = 'demo_student' + self.student = User.objects.create_user( + username='demo_student', + password=self.student_plaintext_pass, + first_name='student_first_name', + last_name='student_last_name', + email='demo_student@test.com' + ) + Profile.objects.create( + user=self.student, + roll_number=10, + institute='IIT', + department='Chemical', + position='Moderator', + timezone='UTC' + ) + + # Create courses for user1 + self.user1_course1 = Course.objects.create( + name="My Course", enrollment="Enroll Request", creator=self.user1 + ) + + # Create learning modules for user1 + self.learning_module1 = LearningModule.objects.create( + order=1, name="My Module", description="My Module", + check_prerequisite=False, creator=self.user1 + ) + self.lesson1 = Lesson.objects.create( + name="My Lesson", description="My Lesson", + creator=self.user1 + ) + + # Create units for lesson + self.lesson_unit1 = LearningUnit.objects.create( + order=1, type="lesson", lesson=self.lesson1 + ) + self.learning_module1.learning_unit.add(self.lesson_unit1) + self.user1_course1.learning_module.add(self.learning_module1) + + def tearDown(self): + self.client.logout() + self.user1.delete() + self.lesson_unit1.delete() + self.user1_course1.delete() + self.learning_module1.delete() + + def test_create_marker(self): + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + # disallow user other than moderator or course creator or course teacher + response = self.client.post( + reverse('yaksh:add_marker', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'content': '1', 'question_type': ''} + ) + self.assertEqual(response.status_code, 404) + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Get json response for topic + response = self.client.post( + reverse('yaksh:add_marker', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'content': '1', 'question_type': ''} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual(json_response.get("content_type"), '1') + + # Get json response for question form + response = self.client.post( + reverse('yaksh:add_marker', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'content': '2', 'question_type': ''} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual(json_response.get("content_type"), '2') + + def test_add_lesson_topic(self): + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + # disallow user other than moderator or course creator or course teacher + response = self.client.post( + reverse('yaksh:add_topic', + kwargs={"content_type": '1', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'name': 'My Lesson Topic', + 'description': 'My lesson topic description'} + ) + self.assertEqual(response.status_code, 404) + + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Post json response for topic + response = self.client.post( + reverse('yaksh:add_topic', + kwargs={"content_type": '1', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'name': 'My_Lesson_Topic', + 'description': 'My lesson topic description'} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "Saved topic successfully" + ) + topics = Topic.objects.filter(name="My_Lesson_Topic") + self.assertTrue(topics.exists()) + + # Get json response for topic form + single_topic = topics.first() + toc = TableOfContents.objects.get( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id=single_topic.id + ) + response = self.client.get( + reverse('yaksh:edit_topic', + kwargs={"content_type": '1', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "topic_id": single_topic.id, + "toc_id": toc.id}) + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + + # delete topic Toc + response = self.client.post( + reverse('yaksh:delete_toc', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'redirect_url': reverse("yaksh:login")} + ) + self.assertEqual(response.status_code, 302) + + def test_add_lesson_quiz(self): + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + # disallow user other than moderator or course creator or course teacher + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '1', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'My_Lesson_question', + 'description': 'My lesson topic description', + 'language': 'mcq', 'type': 'other', 'topic': 'test'} + ) + self.assertEqual(response.status_code, 404) + + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Post json response for lesson quiz (with 400 error) + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '1', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'My_Lesson_question', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'integer', 'topic': 'test'} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 400) + self.assertFalse(json_response.get("success")) + + # Post json response for lesson quiz (with 200 success) + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '2', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'My_Lesson_question', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'integer', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 1, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, 'integertestcase_set-TOTAL_FORMS': 0, + 'integertestcase_set-INITIAL_FORMS': 0, + 'integertestcase_set-MIN_NUM_FORMS': 0, + 'integertestcase_set-MAX_NUM_FORMS': 0, + 'integertestcase_set-0-correct': "1"} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + + self.assertEqual( + json_response.get("message"), "Saved question successfully" + ) + que = Question.objects.filter(summary="My_Lesson_question") + self.assertTrue(que.exists()) + + # Get edit question form + single_que = que.first() + toc = TableOfContents.objects.get( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id=single_que.id + ) + response = self.client.get( + reverse('yaksh:edit_marker_quiz', + kwargs={"content_type": '2', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "question_id": single_que.id, + "toc_id": toc.id}) + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual(json_response.get("content_type"), 2) + + # delete question Toc + response = self.client.post( + reverse('yaksh:delete_toc', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'redirect_url': reverse("yaksh:login")} + ) + self.assertEqual(response.status_code, 302) + + def test_get_and_submit_marker_quiz(self): + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Create a question for lesson exercise + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'My_Lesson_question', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'integer', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 1, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'integertestcase_set-TOTAL_FORMS': 1, + 'integertestcase_set-INITIAL_FORMS': 0, + 'integertestcase_set-MIN_NUM_FORMS': 0, + 'integertestcase_set-MAX_NUM_FORMS': 0, + 'integertestcase_set-0-type': 'integertestcase', + 'integertestcase_set-0-correct': "1"} + ) + + self.client.logout() + que = Question.objects.filter(summary="My_Lesson_question") + + single_que = que.first() + toc = TableOfContents.objects.get( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id=single_que.id + ) + + # Get lesson exercise as student + # Given + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + + # When + response = self.client.get( + reverse('yaksh:get_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}) + ) + + # Then + self.assertEqual(response.status_code, 404) + + # Given + self.user1_course1.students.add(self.student) + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + + # When + response = self.client.get( + reverse('yaksh:get_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}) + ) + json_response = json.loads(response.content) + + # Then + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + + # Submit empty answer for lesson quiz + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'answer': ''} + ) + json_response = json.loads(response.content) + + # Then + self.assertEqual(response.status_code, 200) + self.assertFalse(json_response.get("success")) + + # Submit valid answer for lesson quiz + # When + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'answer': '1'} + ) + json_response = json.loads(response.content) + + # Then + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "You answered the question correctly" + ) + + + def test_lesson_statistics(self): + # Given + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Create a question for lesson exercise + # When + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'My_Lesson_question', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'integer', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 1, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'integertestcase_set-TOTAL_FORMS': 1, + 'integertestcase_set-INITIAL_FORMS': 0, + 'integertestcase_set-MIN_NUM_FORMS': 0, + 'integertestcase_set-MAX_NUM_FORMS': 0, + 'integertestcase_set-0-type': 'integertestcase', + 'integertestcase_set-0-correct': "1"} + ) + self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'Mcc_Lesson_stats', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'mcc', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 2, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'mcqtestcase_set-TOTAL_FORMS': 2, + 'mcqtestcase_set-INITIAL_FORMS': 0, + 'mcqtestcase_set-MIN_NUM_FORMS': 0, + 'mcqtestcase_set-MAX_NUM_FORMS': 0, + 'mcqtestcase_set-0-type': 'mcqtestcase', + 'mcqtestcase_set-0-options': "1", + 'mcqtestcase_set-0-correct': True, + 'mcqtestcase_set-1-type': 'mcqtestcase', + 'mcqtestcase_set-1-options': "2", + 'mcqtestcase_set-1-correct': False + } + ) + que = Question.objects.filter(summary="My_Lesson_question") + + single_que = que.first() + toc = TableOfContents.objects.get( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id=single_que.id + ) + self.client.logout() + self.user1_course1.students.add(self.student) + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'answer': '1'} + ) + self.client.logout() + + # Then + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + response = self.client.get( + reverse('yaksh:lesson_statistics', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}) + ) + response_data = response.context + self.assertEqual(response.status_code, 200) + self.assertEqual( + next(iter(response_data.get("data").keys())).id, toc.id + ) + + # Then + response = self.client.get( + reverse('yaksh:lesson_statistics', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "toc_id": toc.id}) + ) + response_data = response.context + student_info = response_data.get("objects").object_list[0] + self.assertEqual(response.status_code, 200) + self.assertEqual( + next(iter(response_data.get("data").keys())).id, toc.id + ) + self.assertEqual(student_info.get("student_id"), self.student.id) + + # Test for mcc lesson question statistics + # Given + que = Question.objects.filter(summary="Mcc_Lesson_stats") + + single_que = que.first() + toc = TableOfContents.objects.get( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id=single_que.id + ) + self.client.logout() + + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": toc.id}), + data={'answer': [str(i.id) for i in single_que.get_test_cases()]} + ) + self.client.logout() + + # Then + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + response = self.client.get( + reverse('yaksh:lesson_statistics', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "toc_id": toc.id}) + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(student_info.get("student_id"), self.student.id) + + def test_multiple_lesson_question_types(self): + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Create float based question + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'Float_Lesson', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'float', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 1, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'floattestcase_set-TOTAL_FORMS': 1, + 'floattestcase_set-INITIAL_FORMS': 0, + 'floattestcase_set-MIN_NUM_FORMS': 0, + 'floattestcase_set-MAX_NUM_FORMS': 0, + 'floattestcase_set-0-type': 'floattestcase', + 'floattestcase_set-0-correct': "1", + 'floattestcase_set-0-error_margin': "0.1" + } + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "Saved question successfully" + ) + + + # Create a mcq question + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'Mcq_Lesson', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'mcq', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 2, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'mcqtestcase_set-TOTAL_FORMS': 2, + 'mcqtestcase_set-INITIAL_FORMS': 0, + 'mcqtestcase_set-MIN_NUM_FORMS': 0, + 'mcqtestcase_set-MAX_NUM_FORMS': 0, + 'mcqtestcase_set-0-type': 'mcqtestcase', + 'mcqtestcase_set-0-options': "1", + 'mcqtestcase_set-0-correct': True, + 'mcqtestcase_set-1-type': 'mcqtestcase', + 'mcqtestcase_set-1-options': "2", + 'mcqtestcase_set-1-correct': False + } + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "Saved question successfully" + ) + + # Create a mcc question + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'Mcc_Lesson', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'mcc', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 2, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'mcqtestcase_set-TOTAL_FORMS': 2, + 'mcqtestcase_set-INITIAL_FORMS': 0, + 'mcqtestcase_set-MIN_NUM_FORMS': 0, + 'mcqtestcase_set-MAX_NUM_FORMS': 0, + 'mcqtestcase_set-0-type': 'mcqtestcase', + 'mcqtestcase_set-0-options': "1", + 'mcqtestcase_set-0-correct': True, + 'mcqtestcase_set-1-type': 'mcqtestcase', + 'mcqtestcase_set-1-options': "2", + 'mcqtestcase_set-1-correct': False + } + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "Saved question successfully" + ) + + + # Create a string based question + response = self.client.post( + reverse('yaksh:add_marker_quiz', + kwargs={"content_type": '3', + "course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id}), + data={'timer': '00:00:00', 'summary': 'String_Lesson', + 'description': 'My lesson question description', + 'language': 'other', 'type': 'string', 'topic': 'test', + 'points': '1', 'form-TOTAL_FORMS': 1, + 'form-MAX_NUM_FORMS': '', + 'form-INITIAL_FORMS': 0, + 'stringtestcase_set-TOTAL_FORMS': 1, + 'stringtestcase_set-INITIAL_FORMS': 0, + 'stringtestcase_set-MIN_NUM_FORMS': 0, + 'stringtestcase_set-MAX_NUM_FORMS': 0, + 'stringtestcase_set-0-type': 'stringtestcase', + 'stringtestcase_set-0-correct': "test", + 'stringtestcase_set-0-string_check': "lower" + } + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "Saved question successfully" + ) + + ques = Question.objects.filter( + summary__in=["Mcq_Lesson", "Mcc_Lesson", + "Float_Lesson", "String_Lesson"] + ).values_list("id", flat=True) + self.assertTrue(ques.exists()) + tocs = TableOfContents.objects.filter( + course_id=self.user1_course1.id, lesson_id=self.lesson1.id, + object_id__in=ques + ).values_list("id", flat=True) + self.assertTrue(tocs.exists()) + + # Student submits answers to all the questions + self.user1_course1.students.add(self.student) + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + + # submit mcq question + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": tocs[0]}), + data={'answer': '1'} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "You answered the question correctly" + ) + + # submit mcc question + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": tocs[1]}), + data={'answer': ['1']} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertFalse(json_response.get("success")) + self.assertIn( + "You have answered the question incorrectly", + json_response.get("message"), + ) + + # submit float question + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": tocs[2]}), + data={'answer': '1.0'} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertFalse(json_response.get("success")) + self.assertIn( + "You have answered the question incorrectly", + json_response.get("message"), + ) + + + # submit string question + response = self.client.post( + reverse('yaksh:submit_marker_quiz', + kwargs={"course_id": self.user1_course1.id, + "toc_id": tocs[3]}), + data={'answer': 'test'} + ) + json_response = json.loads(response.content) + self.assertEqual(response.status_code, 200) + self.assertTrue(json_response.get("success")) + self.assertEqual( + json_response.get("message"), "You answered the question correctly" + ) + self.client.logout() + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + + # Get statistics for mcc question + response = self.client.get( + reverse('yaksh:lesson_statistics', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "toc_id": tocs[1]}) + ) + response_data = response.context + student_info = response_data.get("objects").object_list[0] + self.assertEqual(response.status_code, 200) + self.assertEqual(student_info.get("student_id"), self.student.id) + + # Get statistics for mcq question + response = self.client.get( + reverse('yaksh:lesson_statistics', + kwargs={"course_id": self.user1_course1.id, + "lesson_id": self.lesson1.id, + "toc_id": tocs[0]}) + ) + response_data = response.context + student_info = response_data.get("objects").object_list[0] + self.assertEqual(response.status_code, 200) + self.assertEqual(student_info.get("student_id"), self.student.id) + + def test_upload_download_lesson_contents(self): + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + dummy_file = SimpleUploadedFile("test.txt", b"test") + # Invalid file type + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson1.id, + "course_id": self.user1_course1.id, + "module_id": self.learning_module1.id}), + data={"toc": dummy_file, + "upload_toc": "upload_toc"} + ) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(response.status_code, 200) + self.assertIn('Please upload yaml or yml type file', messages) + + # Valid yaml file for TOC + yaml_path = os.sep.join((FIXTURES_DIR_PATH, 'sample_lesson_toc.yaml')) + with open(yaml_path, 'rb') as fp: + yaml_file = SimpleUploadedFile("test.yml", fp.read()) + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson1.id, + "course_id": self.user1_course1.id, + "module_id": self.learning_module1.id}), + data={"toc": yaml_file, + "upload_toc": "upload_toc"} + ) + contents = [ + 'Sample lesson quiz 1', 'Sample lesson quiz 2', + 'Sample lesson topic 1', 'Sample lesson topic 2' + ] + self.assertEqual(response.status_code, 200) + has_que = Question.objects.filter( + summary__in=contents[:2] + ).exists() + has_topics = Topic.objects.filter( + name__in=contents[2:] + ).exists() + self.assertTrue(has_que) + self.assertTrue(has_topics) + + # Invalid YAML file data + yaml_content = b""" + --- + name: 'Sample lesson topic 2' + description: 'Topic 2 description' + """ + yaml_file = SimpleUploadedFile("test.yml", yaml_content) + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson1.id, + "course_id": self.user1_course1.id, + "module_id": self.learning_module1.id}), + data={"toc": yaml_file, + "upload_toc": "upload_toc"} + ) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(response.status_code, 200) + self.assertIn("Error parsing yaml", messages[0]) + + # Invalid YAML with no content_type and invalid time format + yaml_path = os.sep.join((FIXTURES_DIR_PATH, 'invalid_yaml.yaml')) + with open(yaml_path, 'rb') as fp: + yaml_file = SimpleUploadedFile("test.yml", fp.read()) + response = self.client.post( + reverse('yaksh:edit_lesson', + kwargs={"lesson_id": self.lesson1.id, + "course_id": self.user1_course1.id, + "module_id": self.learning_module1.id}), + data={"toc": yaml_file, + "upload_toc": "upload_toc"} + ) + messages = [m.message for m in get_messages(response.wsgi_request)] + self.assertEqual(response.status_code, 200) + self.assertIn( + "content_type or time key is missing", messages[0] + ) + self.assertIn("Invalid time format", messages[1]) + + # Download yaml sample + response = self.client.get(reverse('yaksh:download_sample_toc')) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.get('Content-Disposition'), + 'attachment; filename="sample_lesson_toc.yaml"') |