diff options
author | adityacp | 2018-07-03 11:36:25 +0530 |
---|---|---|
committer | adityacp | 2018-07-03 11:36:25 +0530 |
commit | 637a75a5ea8fcae1e00c0200d52c471d50c8729a (patch) | |
tree | 9a2f13aaf80573fa44465031ccc6f895e7fdda0b /yaksh/test_views.py | |
parent | 02705e4c676750291b6a5c4ea14e2947f29cb6c7 (diff) | |
parent | e3ad85ace916354ab96b23c1359ee72a6c2a740b (diff) | |
download | online_test-637a75a5ea8fcae1e00c0200d52c471d50c8729a.tar.gz online_test-637a75a5ea8fcae1e00c0200d52c471d50c8729a.tar.bz2 online_test-637a75a5ea8fcae1e00c0200d52c471d50c8729a.zip |
Update to latest changes
Diffstat (limited to 'yaksh/test_views.py')
-rw-r--r-- | yaksh/test_views.py | 1367 |
1 files changed, 898 insertions, 469 deletions
diff --git a/yaksh/test_views.py b/yaksh/test_views.py index 8fa4747..5bd55eb 100644 --- a/yaksh/test_views.py +++ b/yaksh/test_views.py @@ -8,9 +8,7 @@ except ImportError: from io import BytesIO as string_io import zipfile import shutil -from textwrap import dedent from markdown import Markdown - from django.contrib.auth.models import Group from django.contrib.auth import authenticate from django.core.urlresolvers import reverse @@ -20,12 +18,15 @@ from django.utils import timezone from django.core import mail from django.conf import settings from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.files import File + -from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\ - QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\ - AssignmentUpload, FileUpload, McqTestCase, IntegerTestCase, StringTestCase,\ - FloatTestCase, FIXTURES_DIR_PATH, LearningModule, LearningUnit, Lesson,\ - LessonFile +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 +) from yaksh.decorators import user_has_profile @@ -37,21 +38,23 @@ class TestUserRegistration(TestCase): self.registered_user.delete() def test_register_user_post(self): - response = self.client.post(reverse('yaksh:register'), - data={'username': 'register_user', - 'email':'register_user@mail.com', 'password': 'reg_user', - 'confirm_password': 'reg_user', 'first_name': 'user1_f_name', - 'last_name': 'user1_l_name', 'roll_number': '1', - 'institute': 'demo_institute', 'department': 'demo_dept', - 'position': 'student', 'timezone': pytz.utc.zone - } + self.client.post( + reverse('yaksh:register'), + data={'username': 'register_user', + 'email': 'register_user@mail.com', 'password': 'reg_user', + 'confirm_password': 'reg_user', 'first_name': 'user1_f_name', + 'last_name': 'user1_l_name', 'roll_number': '1', + 'institute': 'demo_institute', 'department': 'demo_dept', + 'position': 'student', 'timezone': pytz.utc.zone + } ) self.registered_user = User.objects.get(username='register_user') self.assertEqual(self.registered_user.email, 'register_user@mail.com') self.assertEqual(self.registered_user.first_name, 'user1_f_name') self.assertEqual(self.registered_user.last_name, 'user1_l_name') self.assertEqual(self.registered_user.profile.roll_number, '1') - self.assertEqual(self.registered_user.profile.institute, 'demo_institute') + self.assertEqual(self.registered_user.profile.institute, + 'demo_institute') self.assertEqual(self.registered_user.profile.department, 'demo_dept') self.assertEqual(self.registered_user.profile.position, 'student') self.assertEqual(self.registered_user.profile.timezone, 'UTC') @@ -93,7 +96,6 @@ class TestProfile(TestCase): self.user1.delete() self.user2.delete() - def test_user_has_profile_for_user_without_profile(self): """ If no profile exists for user passed as argument return False @@ -108,7 +110,6 @@ class TestProfile(TestCase): has_profile_status = user_has_profile(self.user2) self.assertTrue(has_profile_status) - def test_view_profile_denies_anonymous(self): """ If not logged in redirect to login page @@ -149,15 +150,16 @@ class TestProfile(TestCase): username=self.user2.username, password=self.user2_plaintext_pass ) - post_response = self.client.post(reverse('yaksh:new_activation'), - data={'email':self.user2.email} + post_response = self.client.post( + reverse('yaksh:new_activation'), + data={'email': self.user2.email} ) subject = mail.outbox[0].subject.replace(" ", "_") activation_key = mail.outbox[0].body.split("\n")[2].split("/")[-1] - get_response = self.client.get(reverse('yaksh:activate', - kwargs={'key': activation_key}), - follow=True - ) + get_response = self.client.get( + reverse('yaksh:activate', kwargs={'key': activation_key}), + follow=True + ) updated_profile_user = User.objects.get(id=self.user2.id) updated_profile = Profile.objects.get(user=updated_profile_user) self.assertEqual(post_response.status_code, 200) @@ -166,6 +168,14 @@ class TestProfile(TestCase): self.assertEqual(updated_profile.is_email_verified, True) self.assertTemplateUsed(get_response, 'yaksh/activation_status.html') + post_response = self.client.post( + reverse('yaksh:new_activation'), + data={'email': 'user@mail.com'} + ) + self.assertEqual(post_response.status_code, 200) + self.assertFalse(post_response.context['success']) + self.assertTemplateUsed(get_response, 'yaksh/activation_status.html') + def test_edit_profile_post(self): """ POST request to edit_profile view should update the user's profile @@ -174,7 +184,8 @@ class TestProfile(TestCase): username=self.user2.username, password=self.user2_plaintext_pass ) - response = self.client.post(reverse('yaksh:edit_profile'), + response = self.client.post( + reverse('yaksh:edit_profile'), data={ 'user': self.user2, 'first_name': 'new_first_name', @@ -206,7 +217,8 @@ class TestProfile(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.post(reverse('yaksh:edit_profile'), + response = self.client.post( + reverse('yaksh:edit_profile'), data={ 'user': self.user1, 'first_name': 'new_first_name', @@ -274,10 +286,11 @@ class TestProfile(TestCase): username=self.user2.username, password=self.user2_plaintext_pass ) - response = self.client.post(reverse('yaksh:update_email'), + response = self.client.post( + reverse('yaksh:update_email'), data={ 'username': self.user2.username, - 'email':"demo_user2@mail.com" + 'email': "demo_user2@mail.com" } ) updated_user = User.objects.get(id=self.user2.id) @@ -338,12 +351,15 @@ class TestStudentDashboard(TestCase): timezone='UTC' ) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) - self.hidden_course = Course.objects.create(name="Hidden Course", - enrollment="Enroll Request", creator=self.user, code="hide", - hidden=True) + self.hidden_course = Course.objects.create( + name="Hidden Course", enrollment="Enroll Request", + creator=self.user, code="hide", hidden=True + ) def tearDown(self): self.client.logout() @@ -387,7 +403,7 @@ class TestStudentDashboard(TestCase): def test_student_dashboard_all_courses_get(self): """ - Check student dashboard for all non hidden courses + Check student dashboard for all non hidden courses """ self.client.login( username=self.student.username, @@ -403,7 +419,7 @@ class TestStudentDashboard(TestCase): def test_student_dashboard_enrolled_courses_get(self): """ - Check student dashboard for all courses in which student is + Check student dashboard for all courses in which student is enrolled """ self.client.login( @@ -412,7 +428,7 @@ class TestStudentDashboard(TestCase): ) self.course.students.add(self.student) response = self.client.get(reverse('yaksh:quizlist_user', - kwargs={'enrolled': "enrolled"}), + kwargs={'enrolled': "enrolled"}), follow=True ) self.assertEqual(response.status_code, 200) @@ -430,8 +446,8 @@ class TestStudentDashboard(TestCase): password=self.student_plaintext_pass ) response = self.client.post(reverse('yaksh:quizlist_user'), - data={'course_code': 'hide'} - ) + data={'course_code': 'hide'} + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/quizzes_user.html") self.assertEqual(response.context['title'], 'Search') @@ -485,8 +501,10 @@ class TestMonitor(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Open Enrollment", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Open Enrollment", creator=self.user + ) self.quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), @@ -509,13 +527,16 @@ class TestMonitor(TestCase): points=1.0, language="python", type="code", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question) ) self.question_paper.fixed_questions.add(self.question) user_answer = "def add(a, b)\n\treturn a+b" - self.new_answer = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([])) + self.new_answer = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]) + ) self.new_answer.save() self.answerpaper = AnswerPaper.objects.create( user=self.student, question_paper=self.question_paper, @@ -578,17 +599,19 @@ class TestMonitor(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:monitor', - kwargs={'quiz_id': self.quiz.id, - 'course_id': self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:monitor', + kwargs={'quiz_id': self.quiz.id, + 'course_id': self.course.id}), + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/monitor.html") self.assertEqual(response.context['msg'], "Quiz Results") self.assertEqual(response.context['papers'][0], self.answerpaper) - self.assertEqual(response.context['latest_attempts'][0], self.answerpaper) + self.assertEqual(response.context['latest_attempts'][0], + self.answerpaper) def test_get_quiz_user_data(self): """ @@ -598,19 +621,23 @@ class TestMonitor(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:user_data', - kwargs={'user_id':self.student.id, - 'questionpaper_id': self.question_paper.id, - 'course_id': self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:user_data', + kwargs={'user_id': self.student.id, + 'questionpaper_id': self.question_paper.id, + 'course_id': self.course.id}), + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/user_data.html') - self.assertEqual(response.context['data']['papers'][0], self.answerpaper) - self.assertEqual(response.context['data']['profile'], self.student.profile) + self.assertEqual(response.context['data']['papers'][0], + self.answerpaper) + self.assertEqual(response.context['data']['profile'], + self.student.profile) self.assertEqual(response.context['data']['user'], self.student) self.assertEqual(response.context['data']['questionpaperid'], - str(self.question_paper.id)) + str(self.question_paper.id)) + class TestGradeUser(TestCase): def setUp(self): @@ -659,7 +686,8 @@ class TestGradeUser(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", + self.course = Course.objects.create( + name="Python Course", enrollment="Open Enrollment", creator=self.user) self.quiz = Quiz.objects.create( @@ -683,13 +711,16 @@ class TestGradeUser(TestCase): points=1.0, language="python", type="code", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question.id) ) self.question_paper.fixed_questions.add(self.question) user_answer = "def add(a, b)\n\treturn a+b" - self.new_answer = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([]), marks=0.5) + self.new_answer = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]), marks=0.5 + ) self.new_answer.save() self.answerpaper = AnswerPaper.objects.create( user=self.student, question_paper=self.question_paper, @@ -752,15 +783,16 @@ class TestGradeUser(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:grade_user', - kwargs={"quiz_id": self.quiz.id, - 'course_id': self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:grade_user', + kwargs={"quiz_id": self.quiz.id, + 'course_id': self.course.id}), + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/grade_user.html") self.assertEqual(response.context['users'][0]['user__first_name'], - self.student.first_name) + self.student.first_name) self.assertEqual(response.context['quiz'], self.quiz) self.assertFalse(response.context['has_quiz_assignments']) @@ -772,12 +804,13 @@ class TestGradeUser(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:grade_user', - kwargs={"quiz_id": self.quiz.id, - "course_id": self.course.id, - "user_id": self.student.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:grade_user', + kwargs={"quiz_id": self.quiz.id, + "course_id": self.course.id, + "user_id": self.student.id}), + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/grade_user.html") self.assertFalse(response.context['has_user_assignments']) @@ -793,25 +826,28 @@ class TestGradeUser(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - self.client.get(reverse('yaksh:grade_user', + self.client.get(reverse('yaksh:grade_user', kwargs={"quiz_id": self.quiz.id, "course_id": self.course.id, "user_id": self.student.id}), - follow=True - ) + follow=True + ) question_marks = "q{0}_marks".format(self.question.id) - response = self.client.post(reverse('yaksh:grade_user', - kwargs={"quiz_id": self.quiz.id, - "user_id": self.student.id, - "course_id": self.course.id, - "attempt_number": self.answerpaper.attempt_number}), - data={question_marks: 1.0} - ) + response = self.client.post( + reverse( + 'yaksh:grade_user', + kwargs={"quiz_id": self.quiz.id, + "user_id": self.student.id, + "course_id": self.course.id, + "attempt_number": self.answerpaper.attempt_number} + ), + data={question_marks: 1.0} + ) - updated_ans_paper = AnswerPaper.objects.get(user=self.student, - question_paper=self.question_paper, - attempt_number=self.answerpaper.attempt_number - ) + updated_ans_paper = AnswerPaper.objects.get( + user=self.student, question_paper=self.question_paper, + attempt_number=self.answerpaper.attempt_number + ) updated_ans = Answer.objects.get(question=self.question) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/grade_user.html") @@ -866,8 +902,10 @@ class TestDownloadAssignment(TestCase): email='demo_student2@test.com' ) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) self.quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), @@ -889,7 +927,8 @@ class TestDownloadAssignment(TestCase): points=1.0, language="python", type="upload", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question.id) ) self.question_paper.fixed_questions.add(self.question) @@ -897,16 +936,14 @@ class TestDownloadAssignment(TestCase): # create assignment file assignment_file1 = SimpleUploadedFile("file1.txt", b"Test") assignment_file2 = SimpleUploadedFile("file2.txt", b"Test") - assignment_file3 = SimpleUploadedFile("file3.txt", b"Test") - self.assignment1 = AssignmentUpload.objects.create(user=self.student1, - assignmentQuestion=self.question, - assignmentFile=assignment_file1, - question_paper=self.question_paper + SimpleUploadedFile("file3.txt", b"Test") + self.assignment1 = AssignmentUpload.objects.create( + user=self.student1, assignmentQuestion=self.question, + assignmentFile=assignment_file1, question_paper=self.question_paper ) - self.assignment2 = AssignmentUpload.objects.create(user=self.student2, - assignmentQuestion=self.question, - assignmentFile=assignment_file2, - question_paper=self.question_paper + self.assignment2 = AssignmentUpload.objects.create( + user=self.student2, assignmentQuestion=self.question, + assignmentFile=assignment_file2, question_paper=self.question_paper ) def tearDown(self): @@ -934,7 +971,7 @@ class TestDownloadAssignment(TestCase): password=self.student1_plaintext_pass ) response = self.client.get(reverse('yaksh:download_quiz_assignment', - kwargs={'quiz_id': self.quiz.id}), + kwargs={'quiz_id': self.quiz.id}), follow=True ) self.assertEqual(response.status_code, 404) @@ -955,7 +992,7 @@ class TestDownloadAssignment(TestCase): file_name = file_name.replace(" ", "_") self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - "attachment; filename={0}".format(file_name)) + "attachment; filename={0}".format(file_name)) zip_file = string_io(response.content) zipped_file = zipfile.ZipFile(zip_file, 'r') self.assertIsNone(zipped_file.testzip()) @@ -972,18 +1009,19 @@ class TestDownloadAssignment(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:download_user_assignment', - kwargs={'quiz_id': self.quiz.id, - 'question_id': self.question.id, - 'user_id': self.student2.id - }), - follow=True - ) + response = self.client.get( + reverse('yaksh:download_user_assignment', + kwargs={'quiz_id': self.quiz.id, + 'question_id': self.question.id, + 'user_id': self.student2.id + }), + follow=True + ) file_name = "{0}.zip".format(self.student2.get_full_name()) file_name = file_name.replace(" ", "_") self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - "attachment; filename={0}".format(file_name)) + "attachment; filename={0}".format(file_name)) zip_file = string_io(response.content) zipped_file = zipfile.ZipFile(zip_file, 'r') self.assertIsNone(zipped_file.testzip()) @@ -1030,8 +1068,10 @@ class TestAddQuiz(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) self.quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), @@ -1075,7 +1115,6 @@ class TestAddQuiz(TestCase): username=self.student.username, password=self.student_plaintext_pass ) - course_id = self.course.id response = self.client.get(reverse('yaksh:add_quiz'), follow=True ) @@ -1104,8 +1143,9 @@ class TestAddQuiz(TestCase): password=self.user_plaintext_pass ) tzone = pytz.timezone('UTC') - response = self.client.post(reverse('yaksh:edit_quiz', - kwargs={'quiz_id': self.quiz.id}), + response = self.client.post( + reverse('yaksh:edit_quiz', + kwargs={'quiz_id': self.quiz.id}), data={ 'start_date_time': '2016-01-10 09:00:15', 'end_date_time': '2016-01-15 09:00:15', @@ -1121,10 +1161,12 @@ class TestAddQuiz(TestCase): ) updated_quiz = Quiz.objects.get(id=self.quiz.id) - self.assertEqual(updated_quiz.start_date_time, + self.assertEqual( + updated_quiz.start_date_time, datetime(2016, 1, 10, 9, 0, 15, 0, tzone) ) - self.assertEqual(updated_quiz.end_date_time, + self.assertEqual( + updated_quiz.end_date_time, datetime(2016, 1, 15, 9, 0, 15, 0, tzone) ) self.assertEqual(updated_quiz.duration, 30) @@ -1147,7 +1189,8 @@ class TestAddQuiz(TestCase): ) tzone = pytz.timezone('UTC') - response = self.client.post(reverse('yaksh:add_quiz'), + response = self.client.post( + reverse('yaksh:add_quiz'), data={ 'start_date_time': '2016-01-10 09:00:15', 'end_date_time': '2016-01-15 09:00:15', @@ -1163,10 +1206,12 @@ class TestAddQuiz(TestCase): ) quiz_list = Quiz.objects.all().order_by('-id') new_quiz = quiz_list[0] - self.assertEqual(new_quiz.start_date_time, + self.assertEqual( + new_quiz.start_date_time, datetime(2016, 1, 10, 9, 0, 15, 0, tzone) ) - self.assertEqual(new_quiz.end_date_time, + self.assertEqual( + new_quiz.end_date_time, datetime(2016, 1, 15, 9, 0, 15, 0, tzone) ) self.assertEqual(new_quiz.duration, 50) @@ -1197,7 +1242,6 @@ class TestAddQuiz(TestCase): username=self.student.username, password=self.student_plaintext_pass ) - course_id = self.course.id response = self.client.get(reverse('yaksh:add_exercise'), follow=True ) @@ -1225,9 +1269,9 @@ class TestAddQuiz(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - tzone = pytz.timezone('UTC') - response = self.client.post(reverse('yaksh:edit_exercise', - kwargs={'quiz_id': self.exercise.id}), + response = self.client.post( + reverse('yaksh:edit_exercise', + kwargs={'quiz_id': self.exercise.id}), data={ 'description': 'updated demo exercise', 'active': True @@ -1253,9 +1297,8 @@ class TestAddQuiz(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - - tzone = pytz.timezone('UTC') - response = self.client.post(reverse('yaksh:add_exercise'), + response = self.client.post( + reverse('yaksh:add_exercise'), data={ 'description': "Demo Exercise", 'active': True @@ -1327,8 +1370,10 @@ class TestAddTeacher(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) self.pre_req_quiz = Quiz.objects.create( start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0, tzone), @@ -1360,13 +1405,16 @@ class TestAddTeacher(TestCase): """ If not logged in redirect to login page """ - response = self.client.get(reverse('yaksh:add_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:add_teacher', + kwargs={'course_id': self.course.id} + ), follow=True ) - redirect_destination = ('/exam/login/?next=/exam' - '/manage/addteacher/{0}/'.format(self.course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/manage/addteacher/{0}/'.format( + self.course.id) + ) self.assertRedirects(response, redirect_destination) def test_add_teacher_denies_non_moderator(self): @@ -1378,9 +1426,10 @@ class TestAddTeacher(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:add_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:add_teacher', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertEqual(response.status_code, 404) @@ -1393,9 +1442,10 @@ class TestAddTeacher(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:add_teacher', - kwargs={'course_id': self.course.id} - ) + response = self.client.get( + reverse('yaksh:add_teacher', + kwargs={'course_id': self.course.id} + ) ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/addteacher.html') @@ -1421,7 +1471,7 @@ class TestAddTeacher(TestCase): email='demo{}@test.com'.format(i) ) - teacher_profile = Profile.objects.create( + Profile.objects.create( user=teacher, roll_number='T{}'.format(i), institute='IIT', @@ -1431,9 +1481,10 @@ class TestAddTeacher(TestCase): ) teacher_id_list.append(teacher.id) - response = self.client.post(reverse('yaksh:add_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.post( + reverse('yaksh:add_teacher', + kwargs={'course_id': self.course.id} + ), data={'check': teacher_id_list} ) @@ -1485,7 +1536,8 @@ class TestRemoveTeacher(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", + self.course = Course.objects.create( + name="Python Course", enrollment="Enroll Request", creator=self.user) self.pre_req_quiz = Quiz.objects.create( @@ -1505,6 +1557,7 @@ class TestRemoveTeacher(TestCase): description='demo quiz', pass_criteria=40, creator=self.user ) + def tearDown(self): self.client.logout() self.user.delete() @@ -1517,13 +1570,16 @@ class TestRemoveTeacher(TestCase): """ If not logged in redirect to login page """ - response = self.client.get(reverse('yaksh:remove_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:remove_teacher', + kwargs={'course_id': self.course.id} + ), follow=True ) - redirect_destination = ('/exam/login/?next=/exam' - '/manage/remove_teachers/{0}/'.format(self.course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/manage/remove_teachers/{0}/'.format( + self.course.id) + ) self.assertRedirects(response, redirect_destination) def test_remove_teacher_denies_non_moderator(self): @@ -1535,9 +1591,10 @@ class TestRemoveTeacher(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:remove_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:remove_teacher', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertEqual(response.status_code, 404) @@ -1561,7 +1618,7 @@ class TestRemoveTeacher(TestCase): email='remove_teacher{}@test.com'.format(i) ) - teacher_profile = Profile.objects.create( + Profile.objects.create( user=teacher, roll_number='RT{}'.format(i), institute='IIT', @@ -1572,16 +1629,17 @@ class TestRemoveTeacher(TestCase): teacher_id_list.append(teacher.id) self.course.teachers.add(teacher) - response = self.client.post(reverse('yaksh:remove_teacher', - kwargs={'course_id': self.course.id} - ), + response = self.client.post( + reverse('yaksh:remove_teacher', + kwargs={'course_id': self.course.id} + ), data={'remove': teacher_id_list} ) self.assertEqual(response.status_code, 302) redirect_destination = '/exam/manage/courses' - self.assertRedirects(response, redirect_destination, - status_code=302, + self.assertRedirects( + response, redirect_destination, status_code=302, target_status_code=301 ) for t_id in teacher_id_list: @@ -1668,13 +1726,38 @@ class TestCourses(TestCase): order=0, name="test module", description="module", check_prerequisite=False, creator=self.teacher) - self.user1_course = Course.objects.create(name="Python Course", + self.user1_course = Course.objects.create( + name="Python Course", enrollment="Enroll Request", creator=self.user1) + # Create Learning Module for Python Course + self.learning_module1 = LearningModule.objects.create( + order=0, name="demo module", description="module", + check_prerequisite=False, creator=self.user1) + + self.quiz = Quiz.objects.create( + time_between_attempts=0, description='demo quiz', + creator=self.user1) + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0) + self.lesson = Lesson.objects.create( + name="demo lesson", description="test description", + creator=self.user1) + + self.lesson_unit = LearningUnit.objects.create( + order=1, type="lesson", lesson=self.lesson) + self.quiz_unit = LearningUnit.objects.create( + order=2, type="quiz", quiz=self.quiz) + + # Add units to module + self.learning_module1.learning_unit.add(self.lesson_unit) + self.learning_module1.learning_unit.add(self.quiz_unit) + # Add teacher to user1 course self.user1_course.teachers.add(self.teacher) - self.user2_course = Course.objects.create(name="Java Course", + self.user2_course = Course.objects.create( + name="Java Course", enrollment="Enroll Request", creator=self.user2) self.user2_course.learning_module.add(self.learning_module) @@ -1683,20 +1766,14 @@ class TestCourses(TestCase): self.user1.delete() self.user2.delete() self.student.delete() - self.user1_course.delete() - self.user2_course.delete() self.teacher.delete() - self.learning_module.delete() def test_courses_denies_anonymous(self): """ If not logged in redirect to login page """ - response = self.client.get(reverse('yaksh:courses'), - follow=True - ) - redirect_destination = ('/exam/login/?next=/exam' - '/manage/courses/') + response = self.client.get(reverse('yaksh:courses'), follow=True) + redirect_destination = ('/exam/login/?next=/exam/manage/courses/') self.assertRedirects(response, redirect_destination) def test_courses_denies_non_moderator(self): @@ -1708,9 +1785,7 @@ class TestCourses(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:courses'), - follow=True - ) + response = self.client.get(reverse('yaksh:courses'), follow=True) self.assertEqual(response.status_code, 404) def test_courses_get(self): @@ -1721,9 +1796,7 @@ class TestCourses(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.get(reverse('yaksh:courses'), - follow=True - ) + response = self.client.get(reverse('yaksh:courses'), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/courses.html') @@ -1833,11 +1906,12 @@ class TestCourses(TestCase): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/course_modules.html") self.assertEqual(response.context['course'], self.user1_course) - self.assertEqual(response.context['learning_modules'][0], - self.learning_module) + module, percent = response.context['modules'][0] + self.assertEqual(module, self.learning_module) + self.assertEqual(percent, 0.0) def test_duplicate_course(self): - """ Test To clone/duplicate course """ + """ Test To clone/duplicate course and link modules""" # Student Login self.client.login( @@ -1869,27 +1943,64 @@ class TestCourses(TestCase): self.assertTemplateUsed(response, "yaksh/complete.html") self.assertIn(err_msg, response.context['message']) - # Moderator/Course creator login + # Test clone/duplicate courses and create copies of modules and units + + # Teacher Login + # Given + # Add files to a lesson + lesson_file = SimpleUploadedFile("file1.txt", b"Test") + django_file = File(lesson_file) + lesson_file_obj = LessonFile() + lesson_file_obj.lesson = self.lesson + lesson_file_obj.file.save(lesson_file.name, django_file, save=True) + + # Add module to Python Course + self.user1_course.learning_module.add(self.learning_module1) self.client.login( - username=self.user2.username, - password=self.user2_plaintext_pass + username=self.teacher.username, + password=self.teacher_plaintext_pass ) - - # Allows creator to duplicate the course response = self.client.get( reverse('yaksh:duplicate_course', - kwargs={"course_id": self.user2_course.id}), + kwargs={"course_id": self.user1_course.id}), follow=True ) - self.assertEqual(response.status_code, 200) + # When courses = Course.objects.filter( - creator=self.user2).order_by("id") - self.assertEqual(courses.count(), 2) - self.assertEqual(courses.last().creator, self.user2) - self.assertEqual(courses.last().name, "Copy Of Java Course") - self.assertEqual(courses.last().get_learning_modules()[0].id, - self.user2_course.get_learning_modules()[0].id) + creator=self.teacher).order_by("id") + module = courses.last().get_learning_modules()[0] + units = module.get_learning_units() + cloned_lesson = units[0].lesson + cloned_quiz = units[1].quiz + expected_lesson_files = cloned_lesson.get_files() + actual_lesson_files = self.lesson.get_files() + cloned_qp = cloned_quiz.questionpaper_set.get() + self.all_files = LessonFile.objects.filter( + lesson_id__in=[self.lesson.id, cloned_lesson.id]) + + # Then + self.assertEqual(response.status_code, 200) + self.assertEqual(courses.last().creator, self.teacher) + self.assertEqual(courses.last().name, "Copy Of Python Course") + self.assertEqual(module.name, "Copy of demo module") + self.assertEqual(module.creator, self.teacher) + self.assertEqual(module.order, 0) + self.assertEqual(len(units), 2) + self.assertEqual(cloned_lesson.name, "Copy of demo lesson") + self.assertEqual(cloned_lesson.creator, self.teacher) + self.assertEqual(cloned_quiz.description, "Copy of demo quiz") + self.assertEqual(cloned_quiz.creator, self.teacher) + self.assertEqual(cloned_qp.__str__(), + "Question Paper for Copy of demo quiz") + self.assertEqual(os.path.basename(expected_lesson_files[0].file.name), + os.path.basename(actual_lesson_files[0].file.name)) + + for lesson_file in self.all_files: + file_path = lesson_file.file.path + if os.path.exists(file_path): + os.remove(file_path) + shutil.rmtree(os.path.dirname(file_path)) class TestAddCourse(TestCase): @@ -1951,7 +2062,8 @@ class TestAddCourse(TestCase): self.mod_group.user_set.add(self.user) self.mod_group.user_set.add(self.teacher) - self.course = Course.objects.create(name="Python Course", + self.course = Course.objects.create( + name="Python Course", enrollment="Enroll Request", creator=self.user) self.course.teachers.add(self.teacher) @@ -1989,8 +2101,7 @@ class TestAddCourse(TestCase): response = self.client.get(reverse('yaksh:add_course'), follow=True ) - redirect_destination = ('/exam/login/?next=/' - 'exam/manage/add_course/') + redirect_destination = ('/exam/login/?next=/exam/manage/add_course/') self.assertRedirects(response, redirect_destination) def test_add_course_denies_non_moderator(self): @@ -2001,10 +2112,7 @@ class TestAddCourse(TestCase): username=self.student.username, password=self.student_plaintext_pass ) - course_id = self.course.id - response = self.client.get(reverse('yaksh:add_course'), - follow=True - ) + response = self.client.get(reverse('yaksh:add_course'), follow=True) self.assertEqual(response.status_code, 404) def test_add_course_get(self): @@ -2029,13 +2137,14 @@ class TestAddCourse(TestCase): password=self.user_plaintext_pass ) - response = self.client.post(reverse('yaksh:add_course'), + response = self.client.post( + reverse('yaksh:add_course'), data={'name': 'new_demo_course_1', - 'active': True, - 'enrollment': 'open', - 'start_enroll_time': '2016-01-10 09:00:15', - 'end_enroll_time': '2016-01-15 09:00:15', - } + 'active': True, + 'enrollment': 'open', + 'start_enroll_time': '2016-01-10 09:00:15', + 'end_enroll_time': '2016-01-15 09:00:15', + } ) new_course = Course.objects.latest('created_on') self.assertEqual(new_course.name, 'new_demo_course_1') @@ -2054,14 +2163,15 @@ class TestAddCourse(TestCase): password=self.teacher_plaintext_pass ) - response = self.client.post(reverse('yaksh:edit_course', - kwargs={"course_id": self.course.id}), + response = self.client.post( + reverse('yaksh:edit_course', + kwargs={"course_id": self.course.id}), data={'name': 'Teacher_course', - 'active': True, - 'enrollment': 'open', - 'start_enroll_time': '2016-01-10 09:00:15', - 'end_enroll_time': '2016-01-15 09:00:15', - } + 'active': True, + 'enrollment': 'open', + 'start_enroll_time': '2016-01-10 09:00:15', + 'end_enroll_time': '2016-01-15 09:00:15', + } ) updated_course = Course.objects.get(id=self.course.id) self.assertEqual(updated_course.name, 'Teacher_course') @@ -2138,13 +2248,21 @@ class TestCourseDetail(TestCase): self.mod_group.user_set.add(self.user1) self.mod_group.user_set.add(self.user2) - self.user1_course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user1) + self.user1_course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user1 + ) self.learning_module = LearningModule.objects.create( name="test module", description="test description module", html_data="test html description module", creator=self.user1, order=1) self.user1_course.learning_module.add(self.learning_module) + self.lesson = Lesson.objects.create( + name="test lesson", description="test description", + creator=self.user1) + self.learning_unit1 = LearningUnit.objects.create( + order=1, type="lesson", lesson=self.lesson) + self.learning_module.learning_unit.add(self.learning_unit1) def tearDown(self): self.client.logout() @@ -2164,9 +2282,10 @@ class TestCourseDetail(TestCase): upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) # When - response = self.client.post(reverse('yaksh:upload_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) csv_file.close() # Then @@ -2188,9 +2307,10 @@ class TestCourseDetail(TestCase): upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) # When - response = self.client.post(reverse('yaksh:upload_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) csv_file.close() # Then @@ -2215,9 +2335,10 @@ class TestCourseDetail(TestCase): message = "The file uploaded is not a CSV file." # When - response = self.client.post(reverse('yaksh:upload_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) csv_file.close() # Then @@ -2233,15 +2354,17 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_some_headers_missing.csv") + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "users_some_headers_missing.csv") csv_file = open(csv_file_path, 'rb') upload_file = SimpleUploadedFile(csv_file_path, csv_file.read()) message = "The CSV file does not contain the required headers" # When - response = self.client.post(reverse('yaksh:upload_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) csv_file.close() # Then @@ -2257,21 +2380,24 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_with_no_values.csv") + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "users_with_no_values.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_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file}) csv_file.close() # Then self.assertEqual(response.status_code, 200) self.assertIn('upload_details', response.context) self.assertNotIn('message', response.context) - self.assertIn("No rows in the CSV file", response.context['upload_details']) + self.assertIn("No rows in the CSV file", + response.context['upload_details']) self.assertTemplateUsed(response, 'yaksh/course_detail.html') def test_upload_users_csv_with_missing_values(self): @@ -2292,14 +2418,17 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - csv_file_path = os.path.join(FIXTURES_DIR_PATH, "users_some_values_missing.csv") + csv_file_path = os.path.join(FIXTURES_DIR_PATH, + "users_some_values_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_users', - kwargs={'course_id': self.user1_course.id}), - data={'csv_file': upload_file}) + response = self.client.post( + reverse('yaksh:upload_users', + kwargs={'course_id': self.user1_course.id}), + data={'csv_file': upload_file} + ) csv_file.close() # Then @@ -2314,13 +2443,16 @@ class TestCourseDetail(TestCase): """ If not logged in redirect to login page """ - response = self.client.get(reverse('yaksh:course_detail', - kwargs={'course_id': self.user1_course.id} - ), + response = self.client.get( + reverse('yaksh:course_detail', + kwargs={'course_id': self.user1_course.id} + ), follow=True ) - redirect_destination = ('/exam/login/?next=/exam/' - 'manage/course_detail/{0}/'.format(self.user1_course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/manage/course_detail/{0}/'.format( + self.user1_course.id) + ) self.assertRedirects(response, redirect_destination) def test_course_detail_denies_non_moderator(self): @@ -2332,9 +2464,10 @@ class TestCourseDetail(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:course_detail', - kwargs={'course_id': self.user1_course.id} - ), + response = self.client.get( + reverse('yaksh:course_detail', + kwargs={'course_id': self.user1_course.id} + ), follow=True ) self.assertEqual(response.status_code, 404) @@ -2347,9 +2480,10 @@ class TestCourseDetail(TestCase): username=self.user2.username, password=self.user2_plaintext_pass ) - response = self.client.get(reverse('yaksh:course_detail', - kwargs={'course_id': self.user1_course.id} - ), + response = self.client.get( + reverse('yaksh:course_detail', + kwargs={'course_id': self.user1_course.id} + ), follow=True ) self.assertEqual(response.status_code, 404) @@ -2362,9 +2496,10 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.get(reverse('yaksh:course_detail', - kwargs={'course_id': self.user1_course.id} - ), + response = self.client.get( + reverse('yaksh:course_detail', + kwargs={'course_id': self.user1_course.id} + ), follow=True ) self.assertEqual(self.user1_course, response.context['course']) @@ -2379,7 +2514,8 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.get(reverse('yaksh:enroll_user', + response = self.client.get( + reverse('yaksh:enroll_user', kwargs={'course_id': self.user1_course.id, 'user_id': self.student.id}) ) @@ -2395,10 +2531,11 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.post(reverse('yaksh:enroll_users', + response = self.client.post( + reverse('yaksh:enroll_users', kwargs={'course_id': self.user1_course.id}), - data={'check': self.student1.id} - ) + data={'check': self.student1.id} + ) enrolled_student = self.user1_course.students.all() self.assertEqual(response.status_code, 200) self.assertSequenceEqual([self.student1], enrolled_student) @@ -2411,7 +2548,8 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.get(reverse('yaksh:reject_user', + response = self.client.get( + reverse('yaksh:reject_user', kwargs={'course_id': self.user1_course.id, 'user_id': self.student.id}) ) @@ -2427,10 +2565,11 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.post(reverse('yaksh:reject_users', + response = self.client.post( + reverse('yaksh:reject_users', kwargs={'course_id': self.user1_course.id}), - data={'check': self.student1.id} - ) + data={'check': self.student1.id} + ) enrolled_student = self.user1_course.rejected.all() self.assertEqual(response.status_code, 200) self.assertSequenceEqual([self.student1], enrolled_student) @@ -2440,9 +2579,10 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) - response = self.client.post(reverse('yaksh:toggle_course_status', + response = self.client.post( + reverse('yaksh:toggle_course_status', kwargs={'course_id': self.user1_course.id}) - ) + ) self.assertEqual(response.status_code, 302) course = Course.objects.get(name="Python Course") self.assertFalse(course.active) @@ -2496,7 +2636,7 @@ class TestCourseDetail(TestCase): attachment_file = mail.outbox[0].attachments[0][0] subject = mail.outbox[0].subject body = mail.outbox[0].alternatives[0][0] - recipients = mail.outbox[0].recipients() + recipients = mail.outbox[0].bcc self.assertEqual(attachment_file, "file.txt") self.assertEqual(subject, "test_bulk_mail") self.assertEqual(body, "Test_Mail") @@ -2548,12 +2688,82 @@ class TestCourseDetail(TestCase): username=self.user1.username, password=self.user1_plaintext_pass ) + self.user1_course.students.add(self.student) + + # Check student details when course is not started response = self.client.get(reverse('yaksh:course_status', kwargs={'course_id': self.user1_course.id})) self.assertEqual(response.status_code, 200) self.assertEqual(response.context['state'], "course_status") self.assertEqual(response.context['course'], self.user1_course) - self.assertEqual(response.context['modules'][0], self.learning_module) + student_details = response.context['student_details'][0] + student, grade, percent, current_unit = student_details + self.assertEqual(student.username, "demo_student") + self.assertEqual(grade, "NA") + self.assertEqual(percent, 0.0) + self.assertIsNone(current_unit) + + # Check student details when student starts the course + self.course_status = CourseStatus.objects.create( + course=self.user1_course, user=self.student) + response = self.client.get(reverse('yaksh:course_status', + kwargs={'course_id': self.user1_course.id})) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.context['state'], "course_status") + self.assertEqual(response.context['course'], self.user1_course) + student_details = response.context['student_details'][0] + student, grade, percent, current_unit = student_details + self.assertEqual(student.username, "demo_student") + self.assertIsNone(grade) + self.assertEqual(percent, 0) + self.assertIsNone(current_unit) + + self.user1_course.students.remove(self.student) + + def test_course_status_per_user(self): + """ Test course status for a particular student""" + self.client.login( + username=self.student.username, + password=self.student_plaintext_pass + ) + + # Denies student to view course status + response = self.client.get(reverse('yaksh:get_user_data', + kwargs={'course_id': self.user1_course.id, + 'student_id': self.student.id})) + err_msg = response.json()['user_data'].replace("\n", "").strip() + self.assertEqual(response.status_code, 200) + self.assertEqual(err_msg, "You are not a moderator") + + # Other Moderator Login + self.client.login( + username=self.user2.username, + password=self.user2_plaintext_pass + ) + response = self.client.get(reverse('yaksh:get_user_data', + kwargs={'course_id': self.user1_course.id, + 'student_id': self.student.id})) + err_msg = response.json()['user_data'].strip() + actual_err = ('You are neither course creator ' + 'nor course teacher for {0}'.format( + self.user1_course.name) + ) + self.assertEqual(response.status_code, 200) + self.assertEqual(err_msg, actual_err) + + # Actual course creator login + self.client.login( + username=self.user1.username, + password=self.user1_plaintext_pass + ) + response = self.client.get(reverse('yaksh:get_user_data', + kwargs={'course_id': self.user1_course.id, + 'student_id': self.student.id})) + self.assertEqual(response.status_code, 200) + data = response.json()['user_data'] + self.assertIn("Student_First_Name Student_Last_Name", data) + self.assertIn("Overall Course Progress", data) + self.assertIn("Per Module Progress", data) class TestEnrollRequest(TestCase): @@ -2613,8 +2823,10 @@ class TestEnrollRequest(TestCase): self.mod_group.user_set.add(self.user1) self.mod_group.user_set.add(self.user2) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user1) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user1 + ) def tearDown(self): self.client.logout() @@ -2627,13 +2839,16 @@ class TestEnrollRequest(TestCase): """ If not logged in redirect to login page """ - response = self.client.get(reverse('yaksh:enroll_request', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:enroll_request', + kwargs={'course_id': self.course.id} + ), follow=True ) - redirect_destination = ('/exam/login/?next=/exam' - '/enroll_request/{}/'.format(self.course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/enroll_request/{}/'.format( + self.course.id) + ) self.assertRedirects(response, redirect_destination) def test_enroll_request_get_for_student(self): @@ -2642,9 +2857,10 @@ class TestEnrollRequest(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:enroll_request', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:enroll_request', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertRedirects(response, '/exam/quizzes/') @@ -2655,9 +2871,10 @@ class TestEnrollRequest(TestCase): password=self.user2_plaintext_pass ) - response = self.client.get(reverse('yaksh:enroll_request', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:enroll_request', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertRedirects(response, '/exam/manage/courses/') @@ -2679,26 +2896,31 @@ class TestViewAnswerPaper(TestCase): self.user1 = User.objects.get(username="demo_user1") - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", - creator=self.user1) + self.course = Course.objects.create( + name="Python Course", enrollment="Enroll Request", + creator=self.user1 + ) - self.question = Question.objects.create(summary='Dummy', points=1, - type='code', user=self.user1) + self.question = Question.objects.create( + summary='Dummy', points=1, + type='code', user=self.user1 + ) self.quiz = Quiz.objects.create(time_between_attempts=0, description='demo quiz') self.user3 = User.objects.get(username="demo_user3") - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, - total_marks=1.0) + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0 + ) self.question_paper.fixed_questions.add(self.question) self.question_paper.save() - self.ans_paper = AnswerPaper.objects.create(user=self.user3, - attempt_number=1, question_paper=self.question_paper, - start_time=timezone.now(), user_ip='101.0.0.1', - end_time=timezone.now()+timezone.timedelta(minutes=20), - course=self.course) + self.ans_paper = AnswerPaper.objects.create( + user=self.user3, 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) + ) def tearDown(self): User.objects.all().delete() @@ -2710,15 +2932,17 @@ class TestViewAnswerPaper(TestCase): def test_anonymous_user(self): # Given, user not logged in - redirect_destination = ('/exam/login/?next=/exam' - '/view_answerpaper/{0}/{1}'.format( - self.question_paper.id, self.course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/view_answerpaper/{0}/{1}'.format( + self.question_paper.id, self.course.id) + ) # When - response = self.client.get(reverse('yaksh:view_answerpaper', - kwargs={'questionpaper_id': self.question_paper.id, - 'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:view_answerpaper', + kwargs={'questionpaper_id': self.question_paper.id, + 'course_id': self.course.id} + ), follow=True ) @@ -2738,10 +2962,11 @@ class TestViewAnswerPaper(TestCase): ) # When - response = self.client.get(reverse('yaksh:view_answerpaper', - kwargs={'questionpaper_id': self.question_paper.id, - 'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:view_answerpaper', + kwargs={'questionpaper_id': self.question_paper.id, + 'course_id': self.course.id} + ), follow=True ) @@ -2753,7 +2978,6 @@ class TestViewAnswerPaper(TestCase): user3 = User.objects.get(username="demo_user3") self.course.students.add(user3) self.course.save() - answerpaper = AnswerPaper.objects.get(pk=self.ans_paper.id) self.quiz.view_answerpaper = True self.quiz.save() self.client.login( @@ -2762,10 +2986,11 @@ class TestViewAnswerPaper(TestCase): ) # When - response = self.client.get(reverse('yaksh:view_answerpaper', - kwargs={'questionpaper_id': self.question_paper.id, - 'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:view_answerpaper', + kwargs={'questionpaper_id': self.question_paper.id, + 'course_id': self.course.id} + ), follow=True ) @@ -2775,19 +3000,18 @@ class TestViewAnswerPaper(TestCase): self.assertTrue('quiz' in response.context) self.assertTemplateUsed(response, 'yaksh/view_answerpaper.html') - # When, wrong question paper id - response = self.client.get(reverse('yaksh:view_answerpaper', - kwargs={'questionpaper_id': 190, - 'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:view_answerpaper', + kwargs={'questionpaper_id': 190, + 'course_id': self.course.id} + ), follow=True ) # Then self.assertEqual(response.status_code, 404) - def test_view_when_not_enrolled(self): # Given, user tries to view when not enrolled in the course user2 = User.objects.get(username="demo_user2") @@ -2801,10 +3025,11 @@ class TestViewAnswerPaper(TestCase): self.quiz.save() # When - response = self.client.get(reverse('yaksh:view_answerpaper', - kwargs={'questionpaper_id': self.question_paper.id, - 'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:view_answerpaper', + kwargs={'questionpaper_id': self.question_paper.id, + 'course_id': self.course.id} + ), follow=True ) @@ -2867,8 +3092,10 @@ class TestSelfEnroll(TestCase): self.mod_group.user_set.add(self.user1) self.mod_group.user_set.add(self.user2) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user1) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user1 + ) def tearDown(self): self.client.logout() @@ -2878,13 +3105,15 @@ class TestSelfEnroll(TestCase): self.course.delete() def test_self_enroll_denies_anonymous(self): - response = self.client.get(reverse('yaksh:self_enroll', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:self_enroll', + kwargs={'course_id': self.course.id} + ), follow=True ) - redirect_destination = ('/exam/login/?next=/exam' - '/self_enroll/{}/'.format(self.course.id)) + redirect_destination = ( + '/exam/login/?next=/exam/self_enroll/{}/'.format(self.course.id) + ) self.assertRedirects(response, redirect_destination) def test_enroll_request_get_for_student(self): @@ -2893,9 +3122,10 @@ class TestSelfEnroll(TestCase): password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:self_enroll', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:self_enroll', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertRedirects(response, '/exam/quizzes/') @@ -2906,9 +3136,10 @@ class TestSelfEnroll(TestCase): password=self.user2_plaintext_pass ) - response = self.client.get(reverse('yaksh:self_enroll', - kwargs={'course_id': self.course.id} - ), + response = self.client.get( + reverse('yaksh:self_enroll', + kwargs={'course_id': self.course.id} + ), follow=True ) self.assertRedirects(response, '/exam/manage/') @@ -2971,25 +3202,30 @@ class TestGrader(TestCase): self.mod_group.user_set.add(self.user1) self.mod_group.user_set.add(self.user2) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user1) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user1 + ) - self.question = Question.objects.create(summary='Dummy', points=1, - type='code', user=self.user1) + self.question = Question.objects.create( + summary='Dummy', points=1, type='code', user=self.user1 + ) self.quiz = Quiz.objects.create(time_between_attempts=0, description='demo quiz') - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, - total_marks=1.0) + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0 + ) self.question_paper.fixed_questions.add(self.question) self.question_paper.save() - self.answerpaper = AnswerPaper.objects.create(user=self.user2, - attempt_number=1, question_paper=self.question_paper, - start_time=timezone.now(), user_ip='101.0.0.1', - end_time=timezone.now()+timezone.timedelta(minutes=20), - course=self.course) + self.answerpaper = AnswerPaper.objects.create( + user=self.user2, 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), + ) def tearDown(self): User.objects.all().delete() @@ -3009,7 +3245,6 @@ class TestGrader(TestCase): # Then self.assertRedirects(response, redirect_destination) - def test_grader_denies_students(self): # Given self.client.login( @@ -3023,25 +3258,26 @@ class TestGrader(TestCase): # Then self.assertEqual(response.status_code, 404) - def test_regrade_denies_anonymous(self): # Given - redirect_destination = dedent('''\ - /exam/login/?next=/exam/manage/regrade/answerpaper/{}/{}/{}/'''.format( + url = "/exam/login/?next=/exam/manage/regrade/answerpaper" + redirect_destination = ( + url + "/{}/{}/{}/".format( self.course.id, self.question.id, self.answerpaper.id) ) # When - response = self.client.get(reverse('yaksh:regrade', - kwargs={'course_id': self.course.id, - 'question_id': self.question.id, - 'answerpaper_id': self.answerpaper.id}), - follow=True) + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'question_id': self.question.id, + 'answerpaper_id': self.answerpaper.id}), + follow=True + ) # Then self.assertRedirects(response, redirect_destination) - def test_regrade_denies_students(self): # Given self.client.login( @@ -3050,16 +3286,17 @@ class TestGrader(TestCase): ) # When - response = self.client.get(reverse('yaksh:regrade', - kwargs={'course_id': self.course.id, - 'question_id': self.question.id, - 'answerpaper_id': self.answerpaper.id}), - follow=True) + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'question_id': self.question.id, + 'answerpaper_id': self.answerpaper.id}), + follow=True + ) # Then self.assertEqual(response.status_code, 404) - def test_grader_by_moderator(self): # Given self.client.login( @@ -3068,15 +3305,13 @@ class TestGrader(TestCase): ) # When - response = self.client.get(reverse('yaksh:grader'), - follow=True) + response = self.client.get(reverse('yaksh:grader'), follow=True) # Then self.assertEqual(response.status_code, 200) self.assertTrue('courses' in response.context) self.assertTemplateUsed(response, 'yaksh/regrade.html') - def test_regrade_by_moderator(self): # Given self.client.login( @@ -3085,10 +3320,11 @@ class TestGrader(TestCase): ) # When - response = self.client.get(reverse('yaksh:regrade', - kwargs={'course_id': self.course.id, - 'question_id': self.question.id, - 'answerpaper_id': self.answerpaper.id}), + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'question_id': self.question.id, + 'answerpaper_id': self.answerpaper.id}), follow=True) # Then @@ -3097,6 +3333,32 @@ class TestGrader(TestCase): self.assertTrue('details' in response.context) self.assertTemplateUsed(response, 'yaksh/regrade.html') + # When + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'answerpaper_id': self.answerpaper.id}), + follow=True) + + # Then + self.assertEqual(response.status_code, 200) + self.assertTrue('courses' in response.context) + self.assertTrue('details' in response.context) + self.assertTemplateUsed(response, 'yaksh/regrade.html') + + # When + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'question_id': self.question.id, + 'questionpaper_id': self.question_paper.id}), + follow=True) + + # Then + self.assertEqual(response.status_code, 200) + self.assertTrue('courses' in response.context) + self.assertTrue('details' in response.context) + self.assertTemplateUsed(response, 'yaksh/regrade.html') def test_regrade_denies_moderator_not_in_course(self): # Given @@ -3105,15 +3367,19 @@ class TestGrader(TestCase): password=self.user2_plaintext_pass ) + self.mod_group.user_set.remove(self.user2) # When - response = self.client.get(reverse('yaksh:regrade', - kwargs={'course_id': self.course.id, - 'question_id': self.question.id, - 'answerpaper_id': self.answerpaper.id}), + response = self.client.get( + reverse('yaksh:regrade', + kwargs={'course_id': self.course.id, + 'question_id': self.question.id, + 'answerpaper_id': self.answerpaper.id}), follow=True) # Then self.assertEqual(response.status_code, 404) + self.mod_group.user_set.add(self.user2) + class TestPasswordReset(TestCase): def setUp(self): @@ -3144,7 +3410,8 @@ class TestPasswordReset(TestCase): POST request to password_reset view should return a valid response """ # When - response = self.client.post(reverse('password_reset'), + response = self.client.post( + reverse('password_reset'), data={ 'email': self.user1.email, } @@ -3166,7 +3433,8 @@ class TestPasswordReset(TestCase): ) # When - response = self.client.post(reverse('password_change'), + response = self.client.post( + reverse('password_change'), data={ 'old_password': self.user1_plaintext_pass, 'new_password1': 'new_demo1_pass', @@ -3175,7 +3443,8 @@ class TestPasswordReset(TestCase): ) # Then - self.assertIsNotNone(authenticate(username='demo_user1', password='new_demo1_pass')) + self.assertIsNotNone(authenticate(username='demo_user1', + password='new_demo1_pass')) self.assertEqual(response.status_code, 302) self.assertRedirects(response, '/exam/reset/password_change/done/') @@ -3236,8 +3505,10 @@ class TestModeratorDashboard(TestCase): ) self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) self.quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), @@ -3253,15 +3524,18 @@ class TestModeratorDashboard(TestCase): points=1.0, language="python", type="code", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question.id) ) self.question_paper.fixed_questions.add(self.question) # student answerpaper user_answer = "def add(a, b)\n\treturn a+b" - self.new_answer = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([]), marks=0.5) + self.new_answer = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]), marks=0.5 + ) self.new_answer.save() self.answerpaper = AnswerPaper.objects.create( user=self.student, question_paper=self.question_paper, @@ -3276,8 +3550,10 @@ class TestModeratorDashboard(TestCase): self.answerpaper.questions.add(self.question) # moderator trial answerpaper - self.trial_course = Course.objects.create(name="Trial Course", - enrollment="Enroll Request", creator=self.user, is_trial=True) + self.trial_course = Course.objects.create( + name="Trial Course", + enrollment="Enroll Request", creator=self.user, is_trial=True + ) self.trial_quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone), @@ -3293,8 +3569,10 @@ class TestModeratorDashboard(TestCase): ) self.trial_question_paper.fixed_questions.add(self.question) - self.new_answer1 = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([]), marks=0.5) + self.new_answer1 = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]), marks=0.5 + ) self.new_answer1.save() self.trial_answerpaper = AnswerPaper.objects.create( user=self.user, question_paper=self.trial_question_paper, @@ -3362,12 +3640,11 @@ class TestModeratorDashboard(TestCase): password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:manage'), - follow=True - ) + response = self.client.get(reverse('yaksh:manage'), follow=True) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/moderator_dashboard.html") - self.assertEqual(response.context['trial_paper'][0], self.trial_answerpaper) + self.assertEqual(response.context['trial_paper'][0], + self.trial_answerpaper) self.assertEqual(response.context['courses'][0], self.course) def test_moderator_dashboard_delete_trial_papers(self): @@ -3378,16 +3655,17 @@ class TestModeratorDashboard(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - self.course.is_trial=True + self.course.is_trial = True self.course.save() - response = self.client.post(reverse('yaksh:manage'), - data={'delete_paper': [self.trial_answerpaper.id]} - ) + response = self.client.post( + reverse('yaksh:manage'), + data={'delete_paper': [self.trial_answerpaper.id]} + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/moderator_dashboard.html") updated_answerpaper = AnswerPaper.objects.filter(user=self.user) - updated_quiz = Quiz.objects.filter( + updated_quiz = Quiz.objects.filter( description=self.trial_question_paper.quiz.description ) updated_course = Course.objects.filter( @@ -3396,6 +3674,7 @@ class TestModeratorDashboard(TestCase): self.assertSequenceEqual(updated_quiz, []) self.assertSequenceEqual(updated_course, []) + class TestUserLogin(TestCase): def setUp(self): self.client = Client() @@ -3428,10 +3707,11 @@ class TestUserLogin(TestCase): """ Check if user is successfully logged in """ - response = self.client.post(reverse('yaksh:login'), - data={'username': self.user1.username, - 'password': self.user1_plaintext_pass} - ) + response = self.client.post( + reverse('yaksh:login'), + data={'username': self.user1.username, + 'password': self.user1_plaintext_pass} + ) self.assertEqual(response.status_code, 302) self.assertRedirects(response, '/exam/quizzes/') @@ -3451,10 +3731,11 @@ class TestUserLogin(TestCase): Check email verified decorator to check for user login """ settings.IS_DEVELOPMENT = False - response = self.client.post(reverse('yaksh:login'), - data={'username': self.user1.username, - 'password': self.user1_plaintext_pass} - ) + response = self.client.post( + reverse('yaksh:login'), + data={'username': self.user1.username, + 'password': self.user1_plaintext_pass} + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "yaksh/activation_status.html") @@ -3502,8 +3783,10 @@ class TestDownloadcsv(TestCase): timezone='UTC' ) self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Enroll Request", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Enroll Request", creator=self.user + ) self.course.students.add(self.student) self.quiz = Quiz.objects.create( @@ -3520,15 +3803,18 @@ class TestDownloadcsv(TestCase): points=1.0, language="python", type="code", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question.id) ) self.question_paper.fixed_questions.add(self.question) # student answerpaper user_answer = "def add(a, b)\n\treturn a+b" - self.new_answer = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([]), marks=0.5) + self.new_answer = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]), marks=0.5 + ) self.new_answer.save() self.answerpaper = AnswerPaper.objects.create( user=self.student, question_paper=self.question_paper, @@ -3617,14 +3903,15 @@ class TestDownloadcsv(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:download_course_csv', - kwargs={'course_id': self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:download_course_csv', + kwargs={'course_id': self.course.id}), + follow=True + ) file_name = "{0}.csv".format(self.course.name.lower()) self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - 'attachment; filename="{0}"'.format(file_name)) + 'attachment; filename="{0}"'.format(file_name)) def test_download_quiz_csv(self): """ @@ -3634,23 +3921,24 @@ class TestDownloadcsv(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:download_quiz_csv', - kwargs={"course_id": self.course.id, - "quiz_id": self.quiz.id}), - - follow=True - ) - file_name = "{0}-{1}-attempt{2}.csv".format(self.course.name.replace('.', ''), - self.quiz.description.replace('.', ''), 1) + response = self.client.get( + reverse('yaksh:download_quiz_csv', + kwargs={"course_id": self.course.id, + "quiz_id": self.quiz.id}), + follow=True + ) + file_name = "{0}-{1}-attempt{2}.csv".format( + self.course.name.replace('.', ''), + self.quiz.description.replace('.', ''), 1 + ) self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - 'attachment; filename="{0}"'.format(file_name)) + 'attachment; filename="{0}"'.format(file_name)) class TestShowQuestions(TestCase): def setUp(self): self.client = Client() - tzone = pytz.timezone("utc") self.mod_group = Group.objects.create(name='moderator') # student self.student_plaintext_pass = 'student' @@ -3722,9 +4010,9 @@ class TestShowQuestions(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:show_questions'), - follow=True - ) + response = self.client.get( + reverse('yaksh:show_questions'), follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/showquestions.html') self.assertEqual(response.context['questions'][0], self.question) @@ -3737,14 +4025,15 @@ class TestShowQuestions(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.post(reverse('yaksh:show_questions'), - data={'question': [self.question.id], - 'download': 'download'} - ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'question': [self.question.id], + 'download': 'download'} + ) file_name = "{0}_questions.zip".format(self.user) self.assertEqual(response.status_code, 200) self.assertEqual(response.get('Content-Disposition'), - "attachment; filename={0}".format(file_name)) + "attachment; filename={0}".format(file_name)) zip_file = string_io(response.content) zipped_file = zipfile.ZipFile(zip_file, 'r') self.assertIsNone(zipped_file.testzip()) @@ -3752,15 +4041,15 @@ class TestShowQuestions(TestCase): zip_file.close() zipped_file.close() - response = self.client.post(reverse('yaksh:show_questions'), - data={'question': [], - 'download': 'download'} - ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'question': [], + 'download': 'download'} + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/showquestions.html') self.assertIn("download", response.context['msg']) - def test_upload_questions(self): """ Check for uploading questions zip file @@ -3771,30 +4060,32 @@ class TestShowQuestions(TestCase): ) ques_file = os.path.join(FIXTURES_DIR_PATH, "demo_questions.zip") f = open(ques_file, 'rb') - questions_file = SimpleUploadedFile(ques_file, f.read(), + questions_file = SimpleUploadedFile(ques_file, f.read(), content_type="application/zip") - response = self.client.post(reverse('yaksh:show_questions'), - data={'file': questions_file, - 'upload': 'upload'} - ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'file': questions_file, + 'upload': 'upload'} + ) summaries = ['Roots of quadratic equation', 'Print Output', 'Adding decimals', 'For Loop over String', 'Hello World in File', 'Extract columns from files', 'Check Palindrome', 'Add 3 numbers', 'Reverse a string' ] - uploaded_ques = Question.objects.filter(active=True, - summary__in=summaries, - user=self.user).count() + uploaded_ques = Question.objects.filter( + active=True, summary__in=summaries, + user=self.user).count() self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/showquestions.html') self.assertEqual(uploaded_ques, 9) f.close() dummy_file = SimpleUploadedFile("test.txt", b"test") - response = self.client.post(reverse('yaksh:show_questions'), - data={'file': dummy_file, - 'upload': 'upload'} - ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'file': dummy_file, + 'upload': 'upload'} + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/showquestions.html') self.assertIn("ZIP file", response.context['message']) @@ -3807,10 +4098,11 @@ class TestShowQuestions(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.post(reverse('yaksh:show_questions'), - data={'question': [self.question.id], - 'test': 'test'} - ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'question': [self.question.id], + 'test': 'test'} + ) trial_que_paper = QuestionPaper.objects.get( quiz__description="trial_questions" ) @@ -3824,18 +4116,19 @@ class TestShowQuestions(TestCase): def test_ajax_questions_filter(self): """ - Check for filter questions based type, marks and + Check for filter questions based type, marks and language of a question """ self.client.login( username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.post(reverse('yaksh:questions_filter'), - data={'question_type': 'mcq', - 'marks': '1.0', 'language': 'python' - } - ) + response = self.client.post( + reverse('yaksh:questions_filter'), + data={'question_type': 'mcq', + 'marks': '1.0', 'language': 'python' + } + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/ajax_question_filter.html') self.assertEqual(response.context['questions'][0], self.question1) @@ -3861,6 +4154,37 @@ class TestShowQuestions(TestCase): self.assertEqual(response.get('Content-Disposition'), 'attachment; filename="questions_dump.yaml"') + def test_delete_questions(self): + """ Test to check if questions are set to not active when deleted """ + self.client.login( + username=self.user.username, + password=self.user_plaintext_pass + ) + response = self.client.post( + reverse('yaksh:show_questions'), + data={'question': [self.question.id], + 'delete': 'delete'} + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'yaksh/showquestions.html') + updated_que = Question.objects.get(id=self.question.id) + self.assertFalse(updated_que.active) + + def test_search_tags(self): + """ Test to check if questions are obtained with tags """ + self.client.login( + username=self.user.username, + password=self.user_plaintext_pass + ) + self.question.tags.add('code') + response = self.client.post( + reverse('yaksh:show_questions'), + data={'question_tags': ['code']} + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'yaksh/showquestions.html') + self.assertEqual(response.context['questions'][0], self.question) + class TestShowStatistics(TestCase): def setUp(self): @@ -3909,8 +4233,10 @@ class TestShowStatistics(TestCase): # Add to moderator group self.mod_group.user_set.add(self.user) - self.course = Course.objects.create(name="Python Course", - enrollment="Open Enrollment", creator=self.user) + self.course = Course.objects.create( + name="Python Course", + enrollment="Open Enrollment", creator=self.user + ) self.quiz = Quiz.objects.create( start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone), @@ -3926,13 +4252,16 @@ class TestShowStatistics(TestCase): points=1.0, language="python", type="code", user=self.user ) - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, + self.question_paper = QuestionPaper.objects.create( + quiz=self.quiz, total_marks=1.0, fixed_question_order=str(self.question) ) self.question_paper.fixed_questions.add(self.question) user_answer = "def add(a, b)\n\treturn a+b" - self.new_answer = Answer(question=self.question, answer=user_answer, - correct=True, error=json.dumps([])) + self.new_answer = Answer( + question=self.question, answer=user_answer, + correct=True, error=json.dumps([]) + ) self.new_answer.save() self.answerpaper = AnswerPaper.objects.create( user=self.student, question_paper=self.question_paper, @@ -3965,11 +4294,12 @@ class TestShowStatistics(TestCase): username=self.student.username, password=self.student_plaintext_pass ) - response = self.client.get(reverse('yaksh:show_statistics', - kwargs={"questionpaper_id": self.question_paper.id, - "course_id": self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:show_statistics', + kwargs={"questionpaper_id": self.question_paper.id, + "course_id": self.course.id}), + follow=True + ) self.assertEqual(response.status_code, 404) def test_show_statistics_for_student(self): @@ -3980,18 +4310,19 @@ class TestShowStatistics(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:show_statistics', - kwargs={'questionpaper_id': self.question_paper.id, - "course_id": self.course.id}), - follow=True - ) + response = self.client.get( + reverse('yaksh:show_statistics', + kwargs={'questionpaper_id': self.question_paper.id, + "course_id": self.course.id}), + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/statistics_question.html') self.assertEqual(response.context['quiz'], self.quiz) self.assertEqual(response.context['attempts'][0], - self.answerpaper.attempt_number) + self.answerpaper.attempt_number) self.assertEqual(response.context['questionpaper_id'], - str(self.question_paper.id)) + str(self.question_paper.id)) def test_show_statistics_for_student_per_attempt(self): """ @@ -4001,16 +4332,18 @@ class TestShowStatistics(TestCase): username=self.user.username, password=self.user_plaintext_pass ) - response = self.client.get(reverse('yaksh:show_statistics', + response = self.client.get( + reverse('yaksh:show_statistics', kwargs={'questionpaper_id': self.question_paper.id, 'attempt_number': self.answerpaper.attempt_number, "course_id": self.course.id}), - follow=True - ) + follow=True + ) self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'yaksh/statistics_question.html') - self.assertSequenceEqual(response.context['question_stats'][self.question], - [1, 1]) + self.assertSequenceEqual( + response.context['question_stats'][self.question], [1, 1] + ) self.assertEqual(response.context['attempts'][0], 1) self.assertEqual(response.context['total'], 1) @@ -4040,6 +4373,24 @@ class TestQuestionPaper(TestCase): timezone='UTC' ) + self.user2_plaintext_pass = 'demo2' + self.user2 = User.objects.create_user( + username='demo_user2', + password=self.user_plaintext_pass, + first_name='first_name2', + last_name='last_name2', + email='demo2@test.com' + ) + + Profile.objects.create( + user=self.user2, + roll_number=11, + institute='IIT', + department='Chemical', + position='Student', + timezone='UTC' + ) + self.teacher_plaintext_pass = 'demo_teacher' self.teacher = User.objects.create_user( username='demo_teacher', @@ -4092,6 +4443,16 @@ class TestQuestionPaper(TestCase): self.learning_module.learning_unit.add(self.learning_unit.id) self.course.learning_module.add(self.learning_module) + # Questions for random set + self.random_que1 = Question.objects.create( + summary="Random 1", description="Test Random 1", + points=1.0, language="python", type="code", user=self.user + ) + self.random_que2 = Question.objects.create( + summary="Random 2", description="Test Random 2", + points=1.0, language="python", type="code", user=self.user + ) + # Mcq Question self.question_mcq = Question.objects.create( summary="Test_mcq_question", description="Test MCQ", @@ -4201,6 +4562,54 @@ class TestQuestionPaper(TestCase): self.learning_module.delete() self.learning_unit.delete() + def test_preview_questionpaper_correct(self): + self.client.login( + username=self.user.username, + password=self.user_plaintext_pass + ) + + # Should successfully preview question paper + response = self.client.get( + reverse('yaksh:preview_questionpaper', + kwargs={"questionpaper_id": self.question_paper.id} + ) + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'yaksh/preview_questionpaper.html') + self.assertEqual( + response.context['questions'], + self.questions_list + ) + self.assertEqual(response.context['paper'], self.question_paper) + + def test_preview_questionpaper_without_moderator(self): + self.client.login( + username=self.user2.username, + password=self.user_plaintext_pass + ) + + # Should raise an HTTP 404 response + response = self.client.get( + reverse('yaksh:preview_questionpaper', + kwargs={"questionpaper_id": self.question_paper.id} + ) + ) + self.assertEqual(response.status_code, 404) + + def test_preview_qustionpaper_without_quiz_owner(self): + self.client.login( + username=self.teacher.username, + password=self.teacher_plaintext_pass + ) + + # Should raise an HTTP 404 response + response = self.client.get( + reverse('yaksh:preview_questionpaper', + kwargs={"questionpaper_id": self.question_paper.id} + ) + ) + self.assertEqual(response.status_code, 404) + def test_mcq_attempt_right_after_wrong(self): """ Case:- Check if answerpaper and answer marks are updated after attempting same mcq question with wrong answer and then right @@ -4525,8 +4934,28 @@ class TestQuestionPaper(TestCase): "course_id": self.course.id, "questionpaper_id": self.question_paper.id}), data={"question_tags": search_tag}) + self.assertEqual(response.context["questions"][0], self.tagged_que) + # Add random questions in question paper + response = self.client.post( + reverse('yaksh:designquestionpaper', + kwargs={"quiz_id": self.quiz.id, + "course_id": self.course.id, + "questionpaper_id": self.question_paper.id}), + data={'random_questions': [self.random_que1.id, + self.random_que2.id], + 'marks': ['1.0'], 'question_type': ['code'], + '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) + class TestLearningModule(TestCase): def setUp(self): |