summaryrefslogtreecommitdiff
path: root/yaksh/test_views.py
diff options
context:
space:
mode:
Diffstat (limited to 'yaksh/test_views.py')
-rw-r--r--yaksh/test_views.py1069
1 files changed, 957 insertions, 112 deletions
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 2dddcef..ad5b714 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -9,6 +9,7 @@ except ImportError:
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
@@ -23,7 +24,8 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\
AssignmentUpload, FileUpload, McqTestCase, IntegerTestCase, StringTestCase,\
- FloatTestCase, FIXTURES_DIR_PATH
+ FloatTestCase, FIXTURES_DIR_PATH, LearningModule, LearningUnit, Lesson,\
+ LessonFile
from yaksh.decorators import user_has_profile
@@ -492,8 +494,15 @@ class TestMonitor(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
+ self.learning_unit = LearningUnit.objects.create(
+ order=1, type="quiz", quiz=self.quiz)
+ self.learning_module = LearningModule.objects.create(
+ order=1, name="test module", description="test",
+ creator=self.user, check_prerequisite=False)
+ self.learning_module.learning_unit.add(self.learning_unit.id)
+ self.course.learning_module.add(self.learning_module)
self.question = Question.objects.create(
summary="Test_question", description="Add two numbers",
@@ -514,7 +523,7 @@ class TestMonitor(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- percent=1, marks_obtained=1
+ percent=1, marks_obtained=1, course=self.course
)
self.answerpaper.answers.add(self.new_answer)
self.answerpaper.questions_answered.add(self.question)
@@ -529,6 +538,8 @@ class TestMonitor(TestCase):
self.question.delete()
self.question_paper.delete()
self.new_answer.delete()
+ self.learning_module.delete()
+ self.learning_unit.delete()
def test_monitor_denies_student(self):
"""
@@ -568,7 +579,8 @@ class TestMonitor(TestCase):
password=self.user_plaintext_pass
)
response = self.client.get(reverse('yaksh:monitor',
- kwargs={'quiz_id': self.quiz.id}),
+ kwargs={'quiz_id': self.quiz.id,
+ 'course_id': self.course.id}),
follow=True
)
@@ -588,7 +600,8 @@ class TestMonitor(TestCase):
)
response = self.client.get(reverse('yaksh:user_data',
kwargs={'user_id':self.student.id,
- 'questionpaper_id': self.question_paper.id}),
+ 'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}),
follow=True
)
self.assertEqual(response.status_code, 200)
@@ -655,8 +668,15 @@ class TestGradeUser(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
+ self.learning_unit = LearningUnit.objects.create(
+ order=1, type="quiz", quiz=self.quiz)
+ self.learning_module = LearningModule.objects.create(
+ order=1, name="test module", description="test",
+ creator=self.user, check_prerequisite=False)
+ self.learning_module.learning_unit.add(self.learning_unit.id)
+ self.course.learning_module.add(self.learning_module)
self.question = Question.objects.create(
summary="Test_question", description="Add two numbers",
@@ -677,7 +697,7 @@ class TestGradeUser(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- marks_obtained=0.5
+ marks_obtained=0.5, course=self.course
)
self.answerpaper.answers.add(self.new_answer)
self.answerpaper.questions_answered.add(self.question)
@@ -693,6 +713,8 @@ class TestGradeUser(TestCase):
self.question.delete()
self.question_paper.delete()
self.new_answer.delete()
+ self.learning_module.delete()
+ self.learning_unit.delete()
def test_grade_user_denies_student(self):
"""
@@ -731,7 +753,8 @@ class TestGradeUser(TestCase):
password=self.user_plaintext_pass
)
response = self.client.get(reverse('yaksh:grade_user',
- kwargs={"quiz_id": self.quiz.id}),
+ kwargs={"quiz_id": self.quiz.id,
+ 'course_id': self.course.id}),
follow=True
)
self.assertEqual(response.status_code, 200)
@@ -751,6 +774,7 @@ class TestGradeUser(TestCase):
)
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
)
@@ -771,6 +795,7 @@ class TestGradeUser(TestCase):
)
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
)
@@ -778,6 +803,7 @@ class TestGradeUser(TestCase):
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}
)
@@ -848,9 +874,15 @@ class TestDownloadAssignment(TestCase):
end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
- description='demo_quiz', pass_criteria=40,
- language='Python', course=self.course
+ description='demo_quiz', pass_criteria=40
)
+ self.learning_unit = LearningUnit.objects.create(
+ order=1, type="quiz", quiz=self.quiz)
+ self.learning_module = LearningModule.objects.create(
+ order=1, name="test module", description="test",
+ creator=self.user, check_prerequisite=False)
+ self.learning_module.learning_unit.add(self.learning_unit.id)
+ self.course.learning_module.add(self.learning_module)
self.question = Question.objects.create(
summary="Test_question", description="Assignment Upload",
@@ -886,6 +918,8 @@ class TestDownloadAssignment(TestCase):
self.assignment2.delete()
self.quiz.delete()
self.course.delete()
+ self.learning_module.delete()
+ self.learning_unit.delete()
dir_name = self.quiz.description.replace(" ", "_")
file_path = os.sep.join((settings.MEDIA_ROOT, dir_name))
if os.path.exists(file_path):
@@ -999,24 +1033,13 @@ class TestAddQuiz(TestCase):
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),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
- duration=30, active=True, instructions="Demo Instructions",
- attempts_allowed=-1, time_between_attempts=0,
- description='pre requisite quiz', pass_criteria=40,
- language='Python', prerequisite=None,
- course=self.course
- )
-
self.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),
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', prerequisite=self.pre_req_quiz,
- course=self.course
+ creator=self.user
)
def tearDown(self):
@@ -1024,18 +1047,16 @@ class TestAddQuiz(TestCase):
self.user.delete()
self.student.delete()
self.quiz.delete()
- self.pre_req_quiz.delete()
self.course.delete()
def test_add_quiz_denies_anonymous(self):
"""
If not logged in redirect to login page
"""
- response = self.client.get(reverse('yaksh:add_quiz',
- kwargs={'course_id': self.course.id}),
+ response = self.client.get(reverse('yaksh:add_quiz'),
follow=True
)
- redirect_destination = '/exam/login/?next=/exam/manage/addquiz/{0}/'.format(self.course.id)
+ redirect_destination = '/exam/login/?next=/exam/manage/addquiz/'
self.assertRedirects(response, redirect_destination)
def test_add_quiz_denies_non_moderator(self):
@@ -1047,8 +1068,7 @@ class TestAddQuiz(TestCase):
password=self.student_plaintext_pass
)
course_id = self.course.id
- response = self.client.get(reverse('yaksh:add_quiz',
- kwargs={'course_id': self.course.id}),
+ response = self.client.get(reverse('yaksh:add_quiz'),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -1061,8 +1081,7 @@ class TestAddQuiz(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
- response = self.client.get(reverse('yaksh:add_quiz',
- kwargs={'course_id': self.course.id})
+ response = self.client.get(reverse('yaksh:add_quiz')
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'yaksh/add_quiz.html')
@@ -1078,7 +1097,7 @@ class TestAddQuiz(TestCase):
)
tzone = pytz.timezone('UTC')
response = self.client.post(reverse('yaksh:edit_quiz',
- kwargs={'course_id':self.course.id, 'quiz_id': self.quiz.id}),
+ 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',
@@ -1088,10 +1107,8 @@ class TestAddQuiz(TestCase):
'time_between_attempts': 1,
'description': 'updated demo quiz',
'pass_criteria': 40,
- 'language': 'java',
'instructions': "Demo Instructions",
- 'prerequisite': self.pre_req_quiz.id,
- 'course': self.course.id
+ 'weightage': 1.0
}
)
@@ -1108,12 +1125,9 @@ class TestAddQuiz(TestCase):
self.assertEqual(updated_quiz.time_between_attempts, 1)
self.assertEqual(updated_quiz.description, 'updated demo quiz')
self.assertEqual(updated_quiz.pass_criteria, 40)
- self.assertEqual(updated_quiz.language, 'java')
- self.assertEqual(updated_quiz.prerequisite, self.pre_req_quiz)
- self.assertEqual(updated_quiz.course, self.course)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/exam/manage/courses/')
+ self.assertRedirects(response, '/exam/manage/courses/all_quizzes/')
def test_add_quiz_post_new_quiz(self):
"""
@@ -1125,8 +1139,7 @@ class TestAddQuiz(TestCase):
)
tzone = pytz.timezone('UTC')
- response = self.client.post(reverse('yaksh:add_quiz',
- kwargs={"course_id": self.course.id}),
+ 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',
@@ -1136,10 +1149,8 @@ class TestAddQuiz(TestCase):
'time_between_attempts': 2,
'description': 'new demo quiz',
'pass_criteria': 50,
- 'language': 'python',
'instructions': "Demo Instructions",
- 'prerequisite': self.pre_req_quiz.id,
- 'course': self.course.id
+ 'weightage': 1.0
}
)
quiz_list = Quiz.objects.all().order_by('-id')
@@ -1156,12 +1167,23 @@ class TestAddQuiz(TestCase):
self.assertEqual(new_quiz.time_between_attempts, 2)
self.assertEqual(new_quiz.description, 'new demo quiz')
self.assertEqual(new_quiz.pass_criteria, 50)
- self.assertEqual(new_quiz.language, 'python')
- self.assertEqual(new_quiz.prerequisite, self.pre_req_quiz)
- self.assertEqual(new_quiz.course, self.course)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/exam/manage/courses/')
+ self.assertRedirects(response, '/exam/manage/courses/all_quizzes/')
+
+ def test_show_all_quizzes(self):
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:show_all_quizzes'),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context['type'], "quiz")
+ self.assertEqual(response.context['quizzes'][0], self.quiz)
+ self.assertTemplateUsed(response, "yaksh/courses.html")
class TestAddTeacher(TestCase):
@@ -1212,8 +1234,7 @@ class TestAddTeacher(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
- language='Python', prerequisite=None,
- course=self.course
+ creator=self.user
)
self.quiz = Quiz.objects.create(
@@ -1222,8 +1243,7 @@ class TestAddTeacher(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', prerequisite=self.pre_req_quiz,
- course=self.course
+ creator=self.user
)
def tearDown(self):
@@ -1372,8 +1392,7 @@ class TestRemoveTeacher(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
- language='Python', prerequisite=None,
- course=self.course
+ creator=self.user
)
self.quiz = Quiz.objects.create(
@@ -1382,8 +1401,7 @@ class TestRemoveTeacher(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', prerequisite=self.pre_req_quiz,
- course=self.course
+ creator=self.user
)
def tearDown(self):
self.client.logout()
@@ -1520,16 +1538,43 @@ class TestCourses(TestCase):
last_name='student_last_name',
email='demo_student@test.com'
)
+ Profile.objects.create(
+ user=self.student,
+ roll_number=10,
+ institute='IIT',
+ department='Aeronautical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ self.teacher_plaintext_pass = 'teacher'
+ self.teacher = User.objects.create_user(
+ username='teacher',
+ password=self.teacher_plaintext_pass,
+ first_name='teacher_first_name',
+ last_name='teacher_last_name',
+ email='demo_teacher@test.com'
+ )
# Add to moderator group
self.mod_group.user_set.add(self.user1)
self.mod_group.user_set.add(self.user2)
+ self.mod_group.user_set.add(self.teacher)
+
+ # Create a learning module to add to course
+ self.learning_module = LearningModule.objects.create(
+ order=0, name="test module", description="module",
+ check_prerequisite=False, creator=self.teacher)
self.user1_course = Course.objects.create(name="Python Course",
enrollment="Enroll Request", creator=self.user1)
+ # Add teacher to user1 course
+ self.user1_course.teachers.add(self.teacher)
+
self.user2_course = Course.objects.create(name="Java Course",
enrollment="Enroll Request", creator=self.user2)
+ self.user2_course.learning_module.add(self.learning_module)
def tearDown(self):
self.client.logout()
@@ -1538,8 +1583,8 @@ class TestCourses(TestCase):
self.student.delete()
self.user1_course.delete()
self.user2_course.delete()
-
-
+ self.teacher.delete()
+ self.learning_module.delete()
def test_courses_denies_anonymous(self):
"""
@@ -1583,6 +1628,167 @@ class TestCourses(TestCase):
self.assertIn(self.user1_course, response.context['courses'])
self.assertNotIn(self.user2_course, response.context['courses'])
+ def test_teacher_can_design_course(self):
+ """ Check if teacher can design the course i.e add learning modules """
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+ response = self.client.post(
+ reverse('yaksh:design_course',
+ kwargs={"course_id": self.user1_course.id}),
+ data={"Add": "Add",
+ "module_list": [str(self.learning_module.id)]
+ })
+
+ # Test add learning module
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/design_course_session.html')
+ added_learning_module = self.user1_course.learning_module.all().first()
+ self.assertEqual(self.learning_module, added_learning_module)
+ self.assertEqual(added_learning_module.order, 1)
+
+ # Test change order of learning module
+ response = self.client.post(
+ reverse('yaksh:design_course',
+ kwargs={"course_id": self.user1_course.id}),
+ data={"Change": "Change", "ordered_list": ",".join(
+ [str(self.learning_module.id)+":"+"0"]
+ )}
+ )
+ updated_learning_module = LearningModule.objects.get(
+ id=self.learning_module.id)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/design_course_session.html')
+ self.assertEqual(updated_learning_module.order, 0)
+
+ # Test change check prerequisite
+ response = self.client.post(
+ reverse('yaksh:design_course',
+ kwargs={"course_id": self.user1_course.id}),
+ data={"Change_prerequisite": "Change_prerequisite",
+ "check_prereq": [str(self.learning_module.id)]
+ })
+ updated_learning_module = LearningModule.objects.get(
+ id=self.learning_module.id)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/design_course_session.html')
+ self.assertTrue(updated_learning_module.check_prerequisite)
+
+ # Test to remove learning module from course
+ response = self.client.post(
+ reverse('yaksh:design_course',
+ kwargs={"course_id": self.user1_course.id}),
+ data={"Remove": "Remove",
+ "delete_list": [str(self.learning_module.id)]
+ })
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/design_course_session.html')
+ self.assertFalse(self.user1_course.learning_module.all().exists())
+
+ def test_get_course_modules(self):
+ """ Test to check if student gets course modules """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:course_modules',
+ kwargs={"course_id": self.user1_course.id}),
+ follow=True
+ )
+ # Student is not allowed if not enrolled in the course
+ err_msg = "You are not enrolled for this course!"
+ self.assertEqual(response.context['msg'], err_msg)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "yaksh/quizzes_user.html")
+
+ # enroll student in the course
+ self.user1_course.students.add(self.student)
+ # deactivate the course and check if student is able to view course
+ self.user1_course.active = False
+ self.user1_course.save()
+ response = self.client.get(
+ reverse('yaksh:course_modules',
+ kwargs={"course_id": self.user1_course.id}),
+ follow=True
+ )
+ err_msg = "{0} is either expired or not active".format(
+ self.user1_course.name)
+ self.assertEqual(response.context['msg'], err_msg)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "yaksh/quizzes_user.html")
+
+ # activate the course and check if students gets course modules
+ self.user1_course.active = True
+ self.user1_course.save()
+ self.user1_course.learning_module.add(self.learning_module)
+ response = self.client.get(
+ reverse('yaksh:course_modules',
+ kwargs={"course_id": self.user1_course.id}),
+ follow=True
+ )
+ 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)
+
+ def test_duplicate_course(self):
+ """ Test To clone/duplicate course """
+
+ # Student Login
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(
+ reverse('yaksh:duplicate_course',
+ kwargs={"course_id": self.user2_course.id}),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ # Teacher Login
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+
+ # Denies teacher not added in the course
+ response = self.client.get(
+ reverse('yaksh:duplicate_course',
+ kwargs={"course_id": self.user2_course.id}),
+ follow=True
+ )
+ err_msg = "You do not have permissions"
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "yaksh/complete.html")
+ self.assertIn(err_msg, response.context['message'])
+
+ # Moderator/Course creator login
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+
+ # Allows creator to duplicate the course
+ response = self.client.get(
+ reverse('yaksh:duplicate_course',
+ kwargs={"course_id": self.user2_course.id}),
+ follow=True
+ )
+
+ self.assertEqual(response.status_code, 200)
+ 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)
+
class TestAddCourse(TestCase):
def setUp(self):
@@ -1632,8 +1838,7 @@ class TestAddCourse(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
- language='Python', prerequisite=None,
- course=self.course
+ creator=self.user
)
self.quiz = Quiz.objects.create(
@@ -1642,8 +1847,7 @@ class TestAddCourse(TestCase):
duration=30, active=True,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', prerequisite=self.pre_req_quiz,
- course=self.course
+ creator=self.user
)
def tearDown(self):
@@ -1714,7 +1918,8 @@ class TestAddCourse(TestCase):
self.assertEqual(new_course.enrollment, 'open')
self.assertEqual(new_course.active, True)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, '/exam/manage/')
+ self.assertRedirects(response, '/exam/manage/courses',
+ target_status_code=301)
class TestCourseDetail(TestCase):
@@ -2082,12 +2287,11 @@ class TestCourseDetail(TestCase):
response = self.client.post(reverse('yaksh:toggle_course_status',
kwargs={'course_id': self.user1_course.id})
)
- self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.status_code, 302)
course = Course.objects.get(name="Python Course")
self.assertFalse(course.active)
- self.assertEqual(self.user1_course, response.context['course'])
- self.assertEqual(response.status_code, 200)
- self.assertTemplateUsed(response, 'yaksh/course_detail.html')
+ self.assertRedirects(response, '/exam/manage/courses',
+ target_status_code=301)
def test_send_mail_to_course_students(self):
""" Check if bulk mail is sent to multiple students enrolled in a course
@@ -2150,6 +2354,27 @@ class TestCourseDetail(TestCase):
self.assertEqual(get_response.context['course'], self.user1_course)
self.assertEqual(get_response.context['state'], 'mail')
+ def test_download_users_template(self):
+ """ Test to check download users template """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ # Denies student to download users upload template
+ response = self.client.get(reverse('yaksh:download_sample_csv'))
+ self.assertEqual(response.status_code, 404)
+
+ # Moderator Login
+ self.client.login(
+ username=self.user1.username,
+ password=self.user1_plaintext_pass
+ )
+ 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"')
+
class TestEnrollRequest(TestCase):
def setUp(self):
@@ -2281,8 +2506,8 @@ class TestViewAnswerPaper(TestCase):
self.question = Question.objects.create(summary='Dummy', points=1,
type='code', user=self.user1)
- self.quiz = Quiz.objects.create(time_between_attempts=0, course=self.course,
- description='demo quiz', language='Python')
+ 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)
@@ -2292,7 +2517,8 @@ class TestViewAnswerPaper(TestCase):
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))
+ end_time=timezone.now()+timezone.timedelta(minutes=20),
+ course=self.course)
def tearDown(self):
User.objects.all().delete()
@@ -2305,11 +2531,13 @@ class TestViewAnswerPaper(TestCase):
def test_anonymous_user(self):
# Given, user not logged in
redirect_destination = ('/exam/login/?next=/exam'
- '/view_answerpaper/{0}/'.format(self.question_paper.id))
+ '/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}
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
),
follow=True
)
@@ -2331,7 +2559,8 @@ class TestViewAnswerPaper(TestCase):
# When
response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id}
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
),
follow=True
)
@@ -2354,7 +2583,8 @@ class TestViewAnswerPaper(TestCase):
# When
response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id}
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
),
follow=True
)
@@ -2368,7 +2598,8 @@ class TestViewAnswerPaper(TestCase):
# When, wrong question paper id
response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': 190}
+ kwargs={'questionpaper_id': 190,
+ 'course_id': self.course.id}
),
follow=True
)
@@ -2391,7 +2622,8 @@ class TestViewAnswerPaper(TestCase):
# When
response = self.client.get(reverse('yaksh:view_answerpaper',
- kwargs={'questionpaper_id': self.question_paper.id}
+ kwargs={'questionpaper_id': self.question_paper.id,
+ 'course_id': self.course.id}
),
follow=True
)
@@ -2565,8 +2797,8 @@ class TestGrader(TestCase):
self.question = Question.objects.create(summary='Dummy', points=1,
type='code', user=self.user1)
- self.quiz = Quiz.objects.create(time_between_attempts=0, course=self.course,
- description='demo quiz', language='Python')
+ 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)
@@ -2576,7 +2808,8 @@ class TestGrader(TestCase):
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))
+ end_time=timezone.now()+timezone.timedelta(minutes=20),
+ course=self.course)
def tearDown(self):
User.objects.all().delete()
@@ -2832,7 +3065,7 @@ class TestModeratorDashboard(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
self.question = Question.objects.create(
@@ -2856,20 +3089,22 @@ class TestModeratorDashboard(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- marks_obtained=0.5
+ marks_obtained=0.5, course=self.course
)
self.answerpaper.answers.add(self.new_answer)
self.answerpaper.questions_answered.add(self.question)
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_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),
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='trial quiz', pass_criteria=40,
- language='Python', course=self.course, is_trial=True
+ is_trial=True
)
self.trial_question_paper = QuestionPaper.objects.create(
@@ -2887,7 +3122,7 @@ class TestModeratorDashboard(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- marks_obtained=0.5
+ marks_obtained=0.5, course=self.trial_course
)
self.trial_answerpaper.answers.add(self.new_answer1)
self.trial_answerpaper.questions_answered.add(self.question)
@@ -2913,7 +3148,6 @@ class TestModeratorDashboard(TestCase):
follow=True
)
self.assertEqual(response.status_code, 200)
- self.assertRedirects(response, '/exam/quizzes/')
def test_moderator_dashboard_get_for_user_without_profile(self):
"""
@@ -2954,12 +3188,7 @@ class TestModeratorDashboard(TestCase):
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "yaksh/moderator_dashboard.html")
self.assertEqual(response.context['trial_paper'][0], self.trial_answerpaper)
- paper, answer_papers, users_passed, users_failed =\
- response.context['users_per_paper'][0]
- self.assertEqual(paper, self.question_paper)
- self.assertEqual(answer_papers[0], self.answerpaper)
- self.assertEqual(users_passed, 1)
- self.assertEqual(users_failed, 0)
+ self.assertEqual(response.context['courses'][0], self.course)
def test_moderator_dashboard_delete_trial_papers(self):
"""
@@ -2982,7 +3211,7 @@ class TestModeratorDashboard(TestCase):
description=self.trial_question_paper.quiz.description
)
updated_course = Course.objects.filter(
- name=self.trial_question_paper.quiz.course.name)
+ name=self.trial_course.name)
self.assertSequenceEqual(updated_answerpaper, [])
self.assertSequenceEqual(updated_quiz, [])
self.assertSequenceEqual(updated_course, [])
@@ -3103,7 +3332,7 @@ class TestDownloadcsv(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
self.question = Question.objects.create(
@@ -3127,7 +3356,7 @@ class TestDownloadcsv(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- marks_obtained=0.5
+ marks_obtained=0.5, course=self.course
)
self.answerpaper.answers.add(self.new_answer)
self.answerpaper.questions_answered.add(self.question)
@@ -3405,7 +3634,11 @@ class TestShowQuestions(TestCase):
trial_que_paper = QuestionPaper.objects.get(
quiz__description="trial_questions"
)
- redirection_url = "/exam/start/1/{}".format(trial_que_paper.id)
+ trial_course = Course.objects.get(name="trial_course")
+ trial_module = trial_course.learning_module.all()[0]
+ redirection_url = "/exam/start/1/{0}/{1}/{2}".format(
+ trial_module.id, trial_que_paper.id, trial_course.id
+ )
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, redirection_url, target_status_code=301)
@@ -3427,6 +3660,27 @@ class TestShowQuestions(TestCase):
self.assertTemplateUsed(response, 'yaksh/ajax_question_filter.html')
self.assertEqual(response.context['questions'][0], self.question1)
+ def test_download_question_yaml_template(self):
+ """ Test to check download question yaml template """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ # Denies student to download question yaml template
+ response = self.client.get(reverse('yaksh:download_yaml_template'))
+ self.assertEqual(response.status_code, 404)
+
+ # Moderator Login
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:download_yaml_template'))
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.get('Content-Disposition'),
+ 'attachment; filename="questions_dump.yaml"')
+
class TestShowStatistics(TestCase):
def setUp(self):
@@ -3484,7 +3738,7 @@ class TestShowStatistics(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
self.question = Question.objects.create(
@@ -3506,7 +3760,7 @@ class TestShowStatistics(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="completed", passed=True,
- percent=1, marks_obtained=1
+ percent=1, marks_obtained=1, course=self.course
)
self.answerpaper.answers.add(self.new_answer)
self.answerpaper.questions_answered.add(self.question)
@@ -3532,7 +3786,8 @@ class TestShowStatistics(TestCase):
password=self.student_plaintext_pass
)
response = self.client.get(reverse('yaksh:show_statistics',
- kwargs={"questionpaper_id": self.question_paper.id}),
+ kwargs={"questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id}),
follow=True
)
self.assertEqual(response.status_code, 404)
@@ -3546,7 +3801,8 @@ class TestShowStatistics(TestCase):
password=self.user_plaintext_pass
)
response = self.client.get(reverse('yaksh:show_statistics',
- kwargs={'questionpaper_id': self.question_paper.id}),
+ kwargs={'questionpaper_id': self.question_paper.id,
+ "course_id": self.course.id}),
follow=True
)
self.assertEqual(response.status_code, 200)
@@ -3567,7 +3823,8 @@ class TestShowStatistics(TestCase):
)
response = self.client.get(reverse('yaksh:show_statistics',
kwargs={'questionpaper_id': self.question_paper.id,
- 'attempt_number': self.answerpaper.attempt_number}),
+ 'attempt_number': self.answerpaper.attempt_number,
+ "course_id": self.course.id}),
follow=True
)
self.assertEqual(response.status_code, 200)
@@ -3616,9 +3873,17 @@ class TestQuestionPaper(TestCase):
duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
- language='Python', course=self.course
+ creator=self.user
)
+ self.learning_unit = LearningUnit.objects.create(
+ order=1, type="quiz", quiz=self.quiz)
+ self.learning_module = LearningModule.objects.create(
+ order=1, name="test module", description="module",
+ check_prerequisite=False, creator=self.user)
+ self.learning_module.learning_unit.add(self.learning_unit.id)
+ self.course.learning_module.add(self.learning_module)
+
# Mcq Question
self.question_mcq = Question.objects.create(
summary="Test_mcq_question", description="Test MCQ",
@@ -3706,7 +3971,7 @@ class TestQuestionPaper(TestCase):
start_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_time=datetime(2014, 10, 9, 10, 15, 15, 0, tzone),
user_ip="127.0.0.1", status="inprogress", passed=False,
- percent=0, marks_obtained=0
+ percent=0, marks_obtained=0, course=self.course
)
self.answerpaper.questions.add(*questions_list)
@@ -3720,6 +3985,8 @@ class TestQuestionPaper(TestCase):
self.question_mcc.delete()
self.question_int.delete()
self.question_paper.delete()
+ self.learning_module.delete()
+ self.learning_unit.delete()
def test_mcq_attempt_right_after_wrong(self):
""" Case:- Check if answerpaper and answer marks are updated after
@@ -3738,7 +4005,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcq.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
@@ -3753,7 +4022,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcq.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3778,7 +4049,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcq.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3793,7 +4066,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcq.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
@@ -3818,7 +4093,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcc.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3833,7 +4110,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_mcc.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
@@ -3858,7 +4137,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_int.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3873,7 +4154,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_int.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
@@ -3898,7 +4181,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_str.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3913,7 +4198,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_str.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
@@ -3938,7 +4225,9 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_float.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": right_user_answer}
)
@@ -3953,10 +4242,566 @@ class TestQuestionPaper(TestCase):
self.client.post(
reverse('yaksh:check',
kwargs={"q_id": self.question_float.id, "attempt_num": 1,
- "questionpaper_id": self.question_paper.id}),
+ "questionpaper_id": self.question_paper.id,
+ "course_id": self.course.id,
+ "module_id": self.learning_module.id}),
data={"answer": wrong_user_answer}
)
# Then
wrong_answer_paper = AnswerPaper.objects.get(id=self.answerpaper.id)
self.assertEqual(wrong_answer_paper.marks_obtained, 0)
+
+
+class TestLearningModule(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+ tzone = pytz.timezone('UTC')
+ # Create Moderator with profile
+ self.user_plaintext_pass = 'demo'
+ self.user = User.objects.create_user(
+ username='demo_user',
+ password=self.user_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create a student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@student.com'
+ )
+
+ # Create a teacher to add to the course
+ self.teacher_plaintext_pass = 'demo_teacher'
+ self.teacher = User.objects.create_user(
+ username='demo_teacher',
+ password=self.teacher_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@student.com'
+ )
+
+ # Add to moderator group
+ self.mod_group.user_set.add(self.user)
+ self.mod_group.user_set.add(self.teacher)
+
+ self.course = Course.objects.create(
+ name="Python Course",
+ enrollment="Open Enrollment", creator=self.user)
+
+ self.question = Question.objects.create(
+ summary="Test_question", description="Add two numbers",
+ points=1.0, language="python", type="code", user=self.user
+ )
+ self.quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
+ end_date_time=datetime(2199, 10, 9, 10, 8, 15, 0, tzone),
+ duration=30, active=True, instructions="Demo Instructions",
+ attempts_allowed=-1, time_between_attempts=0,
+ description='demo quiz', pass_criteria=40,
+ creator=self.user
+ )
+
+ self.question_paper = QuestionPaper.objects.create(
+ quiz=self.quiz,
+ total_marks=5.0, fixed_question_order=str(self.question.id)
+ )
+
+ self.question_paper.fixed_questions.add(self.question)
+
+ self.lesson = Lesson.objects.create(
+ name="test lesson", description="test description",
+ creator=self.user)
+ # create quiz learning unit
+ self.learning_unit = LearningUnit.objects.create(
+ order=0, type="quiz", quiz=self.quiz)
+ # create lesson learning unit
+ self.learning_unit1 = LearningUnit.objects.create(
+ order=1, type="lesson", lesson=self.lesson)
+ # create learning module
+ self.learning_module = LearningModule.objects.create(
+ order=0, name="test module", description="module",
+ check_prerequisite=False, creator=self.user)
+ self.learning_module.learning_unit.add(self.learning_unit)
+ self.learning_module.learning_unit.add(self.learning_unit1)
+ self.learning_module1 = LearningModule.objects.create(
+ order=0, name="my module", description="my description",
+ check_prerequisite=False, creator=self.user)
+ self.course.teachers.add(self.teacher)
+ self.course.learning_module.add(self.learning_module)
+
+ self.expected_url = "/exam/manage/courses/all_learning_module/"
+
+ def tearDown(self):
+ self.user.delete()
+ self.student.delete()
+ self.teacher.delete()
+ self.quiz.delete()
+ self.course.delete()
+ self.learning_unit.delete()
+ self.learning_module.delete()
+
+ def test_add_new_module_denies_non_moderator(self):
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ # Student tries to add learning module
+ response = self.client.post(reverse('yaksh:add_module'),
+ data={"name": "test module1",
+ "description": "my test1",
+ "Save": "Save"})
+ self.assertEqual(response.status_code, 404)
+
+ # Student tries to view learning modules
+ response = self.client.get(reverse('yaksh:show_all_modules'))
+ self.assertEqual(response.status_code, 404)
+
+ def test_add_new_module(self):
+ """ Check if new module is created """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+
+ # Test add new module
+ response = self.client.post(reverse('yaksh:add_module'),
+ data={"name": "test module1",
+ "description": "my test1",
+ "Save": "Save"})
+
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, self.expected_url)
+ 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.assertEqual(learning_module.html_data,
+ Markdown().convert("my test1"))
+
+ def test_edit_module(self):
+ """ Check if existing module is editable """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+
+ # Test add new module
+ response = self.client.post(
+ reverse('yaksh:edit_module',
+ kwargs={"module_id": self.learning_module.id}),
+ data={"name": "test module2",
+ "description": "my test2",
+ "Save": "Save"})
+
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, self.expected_url)
+ learning_module = LearningModule.objects.get(name="test module2")
+ self.assertEqual(learning_module.description, "my test2")
+ self.assertEqual(learning_module.creator, self.user)
+ self.assertFalse(learning_module.check_prerequisite)
+ self.assertEqual(learning_module.html_data,
+ Markdown().convert("my test2"))
+
+ def test_show_all_modules(self):
+ """Try to get all learning modules"""
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:show_all_modules'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/courses.html')
+ self.assertEqual(response.context['type'], "learning_module")
+ self.assertEqual(response.context['learning_modules'][0],
+ self.learning_module)
+
+ def test_teacher_can_edit_module(self):
+ """ Check if teacher can edit the module """
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+ response = self.client.post(
+ reverse('yaksh:edit_module',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id}),
+ data={"name": "teacher module 2",
+ "description": "teacher module 2",
+ "Save": "Save"})
+
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, "/exam/manage/courses/")
+ learning_module = LearningModule.objects.get(name="teacher module 2")
+ self.assertEqual(learning_module.description, "teacher module 2")
+ self.assertEqual(learning_module.creator, self.user)
+
+ def test_teacher_can_design_module(self):
+ """ Check if teacher can design the module i.e add learning units """
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+ response = self.client.post(
+ reverse('yaksh:design_module',
+ kwargs={"module_id": self.learning_module1.id,
+ "course_id": self.course.id}),
+ data={"Add": "Add",
+ "choosen_list": ",".join([str(self.quiz.id)+":"+"quiz"])
+ })
+
+ # Test add learning unit
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_module.html')
+ learning_unit = self.learning_module1.learning_unit.all().first()
+ self.assertEqual(self.quiz, learning_unit.quiz)
+ self.assertEqual(learning_unit.type, "quiz")
+ self.assertEqual(learning_unit.order, 1)
+
+ # Test change order of learning unit
+ response = self.client.post(
+ reverse('yaksh:design_module',
+ kwargs={"module_id": self.learning_module1.id,
+ "course_id": self.course.id}),
+ data={"Change": "Change",
+ "ordered_list": ",".join([str(learning_unit.id)+":"+"0"])
+ })
+ updated_learning_unit = LearningUnit.objects.get(id=learning_unit.id)
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_module.html')
+ self.assertEqual(updated_learning_unit.order, 0)
+
+ # Test change check prerequisite
+ response = self.client.post(
+ reverse('yaksh:design_module',
+ kwargs={"module_id": self.learning_module1.id,
+ "course_id": self.course.id}),
+ data={"Change_prerequisite": "Change_prerequisite",
+ "check_prereq": [str(learning_unit.id)]
+ })
+ 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)
+
+ # Test to remove learning unit from learning module
+ response = self.client.post(
+ reverse('yaksh:design_module',
+ kwargs={"module_id": self.learning_module1.id,
+ "course_id": self.course.id}),
+ data={"Remove": "Remove",
+ "delete_list": [str(learning_unit.id)]
+ })
+ updated_learning_unit = LearningUnit.objects.filter(
+ id=learning_unit.id).exists()
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_module.html')
+ self.assertFalse(updated_learning_unit)
+ self.assertFalse(self.learning_module1.learning_unit.all().exists())
+
+ def test_get_learning_units_for_design(self):
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:design_module',
+ kwargs={"module_id": self.learning_module1.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_module.html')
+ self.assertEqual(response.context['quiz_les_list'], set())
+ self.assertEqual(len(response.context['learning_units']), 0)
+ self.assertEqual(response.context['status'], "design")
+ self.assertEqual(response.context['module_id'],
+ str(self.learning_module1.id))
+ self.assertEqual(response.context['course_id'], str(self.course.id))
+
+ def test_view_module(self):
+ """ Student tries to view a module containing learning units """
+
+ # Student is not enrolled in the course is thrown out
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:view_module',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 404)
+
+ # add student to the course
+ self.course.students.add(self.student.id)
+
+ # check if enrolled student can view module
+ response = self.client.get(
+ reverse('yaksh:view_module',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "yaksh/show_video.html")
+ self.assertEqual(response.context['learning_units'][0],
+ self.learning_unit)
+ self.assertEqual(response.context["state"], "module")
+ self.assertEqual(response.context["first_unit"], self.learning_unit)
+ self.assertEqual(response.context["user"], self.student)
+
+ def test_get_next_unit(self):
+ """ Check if we get correct next unit """
+
+ # Student who is not enrolled is thrown out
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:view_module',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 404)
+
+ # Enroll student in the course
+ self.course.students.add(self.student.id)
+
+ # Get First unit as next unit
+ response = self.client.get(
+ reverse('yaksh:next_unit',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id,
+ "current_unit_id": self.learning_unit.id,
+ "first_unit": "1"}),
+ follow=True)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context['attempt_num'], 1)
+ self.assertEqual(response.context["questionpaper"],
+ self.question_paper)
+ self.assertEqual(response.context["course"], self.course)
+ self.assertEqual(response.context["module"], self.learning_module)
+ self.assertEqual(response.context["user"], self.student)
+
+ # Get next unit after first unit
+ response = self.client.get(
+ reverse('yaksh:next_unit',
+ kwargs={"module_id": self.learning_module.id,
+ "course_id": self.course.id,
+ "current_unit_id": self.learning_unit.id}),
+ follow=True)
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context["state"], "lesson")
+ self.assertEqual(response.context["current_unit"].id,
+ self.learning_unit1.id)
+
+
+class TestLessons(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+ tzone = pytz.timezone('UTC')
+ # Create Moderator with profile
+ self.user_plaintext_pass = 'demo'
+ self.user = User.objects.create_user(
+ username='demo_user',
+ password=self.user_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create a student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@student.com'
+ )
+
+ # Create a teacher to add to the course
+ self.teacher_plaintext_pass = 'demo_teacher'
+ self.teacher = User.objects.create_user(
+ username='demo_teacher',
+ password=self.teacher_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo@student.com'
+ )
+
+ # Add to moderator group
+ self.mod_group.user_set.add(self.user)
+ self.mod_group.user_set.add(self.teacher)
+
+ 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),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
+ duration=30, active=True, instructions="Demo Instructions",
+ attempts_allowed=-1, time_between_attempts=0,
+ description='demo quiz', pass_criteria=40,
+ creator=self.user
+ )
+
+ self.lesson = Lesson.objects.create(
+ name="test lesson", description="test description",
+ creator=self.user)
+ self.learning_unit = LearningUnit.objects.create(
+ order=0, type="lesson", lesson=self.lesson)
+ self.learning_module = LearningModule.objects.create(
+ order=0, name="test module", description="module",
+ check_prerequisite=False, creator=self.user)
+ self.learning_module.learning_unit.add(self.learning_unit.id)
+ self.course.learning_module.add(self.learning_module.id)
+ self.course.teachers.add(self.teacher.id)
+
+ self.expected_url = "/exam/manage/courses/"
+
+ def tearDown(self):
+ self.user.delete()
+ self.student.delete()
+ self.teacher.delete()
+ self.quiz.delete()
+ self.course.delete()
+ self.learning_unit.delete()
+ self.learning_module.delete()
+ self.lesson.delete()
+
+ def test_edit_lesson_denies_non_moderator(self):
+ """ Student should not be allowed to edit lesson """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ # Student tries to edit lesson
+ response = self.client.get(
+ reverse('yaksh:edit_lesson',
+ kwargs={"lesson_id": self.lesson.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 404)
+
+ def test_teacher_can_edit_lesson(self):
+ """ Teacher should be allowed to edit lesson """
+ self.client.login(
+ username=self.teacher.username,
+ password=self.teacher_plaintext_pass
+ )
+ dummy_file = SimpleUploadedFile("test.txt", b"test")
+ response = self.client.post(
+ reverse('yaksh:edit_lesson',
+ kwargs={"lesson_id": self.lesson.id,
+ "course_id": self.course.id}),
+ data={"name": "updated lesson",
+ "description": "updated description",
+ "Lesson_files": dummy_file,
+ "Save": "Save"}
+ )
+
+ # Teacher edits existing lesson and adds file
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, self.expected_url)
+ updated_lesson = Lesson.objects.get(name="updated lesson")
+ self.assertEqual(updated_lesson.description, "updated description")
+ self.assertEqual(updated_lesson.creator, self.user)
+ self.assertEqual(updated_lesson.html_data,
+ Markdown().convert("updated description"))
+ lesson_files = LessonFile.objects.filter(
+ lesson=self.lesson).first()
+ self.assertIn("test.txt", lesson_files.file.name)
+ lesson_file_path = lesson_files.file.path
+ # Teacher removes the lesson file
+ response = self.client.post(
+ reverse('yaksh:edit_lesson',
+ kwargs={"lesson_id": self.lesson.id,
+ "course_id": self.course.id}),
+ data={"delete_files": [str(lesson_files.id)],
+ "Delete": "Delete"}
+ )
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, self.expected_url)
+ lesson_file_exists = LessonFile.objects.filter(
+ lesson=self.lesson).exists()
+ self.assertFalse(lesson_file_exists)
+ self.assertFalse(os.path.exists(lesson_file_path))
+
+ def test_show_lesson(self):
+ """ Student should be able to view lessons """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+ response = self.client.get(
+ reverse('yaksh:show_lesson',
+ kwargs={"lesson_id": self.lesson.id,
+ "module_id": self.learning_module.id,
+ "course_id": self.course.id}))
+ # Student is unable to view lesson
+ self.assertEqual(response.status_code, 404)
+
+ # Add student to course
+ self.course.students.add(self.student.id)
+ response = self.client.get(
+ reverse('yaksh:show_lesson',
+ kwargs={"lesson_id": self.lesson.id,
+ "module_id": self.learning_module.id,
+ "course_id": self.course.id}))
+ self.assertEqual(response.status_code, 200)
+ self.assertEqual(response.context["state"], "lesson")
+ self.assertEqual(response.context["current_unit"], self.learning_unit)
+
+ def test_show_all_lessons(self):
+ """ Moderator should be able to see all created lessons"""
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:show_all_lessons'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, "yaksh/courses.html")
+ self.assertEqual(response.context["type"], "lesson")
+ self.assertEqual(response.context["lessons"][0], self.lesson)
+
+ 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>')