From c27d90bfa77fff2649ee203a14a3fd0d923e1e3d Mon Sep 17 00:00:00 2001
From: manish-kr
Date: Wed, 6 Jul 2016 21:56:18 -0700
Subject: Minor change in requirements.txt
While running the command `pip install -r requirements.txt` the following error is observed:
"InvalidRequirement: Invalid requirement, parse error at "u',' "
Fix:
Removed ',' after each module name in requirements.txt to fix the error.---
requirements.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index 2ace8a9..d3aa19a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
-django==1.9.5,
-mysql-python==1.2.5,
-django-taggit==0.18.1,
+django==1.9.5
+mysql-python==1.2.5
+django-taggit==0.18.1
pytz==2016.4
--
cgit
From 9800ef3dd309089c41e74cf2120f9b0f4eef6fa8 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Thu, 7 Jul 2016 16:23:52 +0530
Subject: Minor change: Display reset button only if it is code question
---
yaksh/templates/yaksh/question.html | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html
index b8be99f..54fb30b 100644
--- a/yaksh/templates/yaksh/question.html
+++ b/yaksh/templates/yaksh/question.html
@@ -189,13 +189,14 @@ function call_skip(url)
{% else %}
+
+
{% endif %}
{% if paper.unanswered.all|length != 1 %}
{% endif %}
-
-
+
--
cgit
From 47a1d4589b9f549892939f62879604713dbe772a Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Tue, 24 May 2016 20:40:21 +0530
Subject: Add tests for views
---
yaksh/models.py | 4 +
yaksh/test_views.py | 621 ++++++++++++++++++++++++++++++++++++++++++++++++++++
yaksh/urls.py | 17 +-
yaksh/views.py | 36 +--
4 files changed, 642 insertions(+), 36 deletions(-)
create mode 100644 yaksh/test_views.py
diff --git a/yaksh/models.py b/yaksh/models.py
index 7035d1e..cc63615 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -58,6 +58,10 @@ def get_model_class(model):
return model_class
+def has_profile(user):
+ """ check if user has profile """
+ return True if hasattr(user, 'profile') else False
+
###############################################################################
class CourseManager(models.Manager):
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
new file mode 100644
index 0000000..42b7f34
--- /dev/null
+++ b/yaksh/test_views.py
@@ -0,0 +1,621 @@
+from datetime import datetime
+
+from django.contrib.auth.models import Group
+from django.core.urlresolvers import reverse
+from django.test import TestCase
+from django.test import Client
+
+from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\
+ QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\
+ StdoutBasedTestCase, has_profile
+
+
+class TestProfile(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ # Create User without profile
+ self.user1_plaintext_pass = 'demo1'
+ self.user1 = User.objects.create_user(
+ username='demo_user1',
+ password=self.user1_plaintext_pass,
+ email='demo1@test.com'
+ )
+
+ # Create User with profile
+ self.user2_plaintext_pass = 'demo2'
+ self.user2 = User.objects.create_user(
+ username='demo_user2',
+ password=self.user2_plaintext_pass,
+ first_name='first_name',
+ last_name='last_name',
+ email='demo2@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user2,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Student'
+ )
+
+ def tearDown(self):
+ self.client.logout()
+ self.user1.delete()
+ self.user2.delete()
+
+ def test_has_profile_for_user_without_profile(self):
+ """
+ If no profile exists for user passed as argument return False
+ """
+ has_profile_status = has_profile(self.user1)
+ self.assertFalse(has_profile_status)
+
+ def test_has_profile_for_user_with_profile(self):
+ """
+ If profile exists for user passed as argument return True
+ """
+ has_profile_status = has_profile(self.user2)
+ self.assertTrue(has_profile_status)
+
+
+ def test_view_profile_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:view_profile'), follow=True)
+ redirect_destination = '/exam/login/?next=%2Fexam%2Fviewprofile%2F'
+ self.assertRedirects(response, redirect_destination)
+
+ def test_view_profile_get_for_user_without_profile(self):
+ """
+ If no profile exists a blank profile form will be displayed
+ """
+ self.client.login(
+ username=self.user1.username,
+ password=self.user1_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:view_profile'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/editprofile.html')
+
+ def test_view_profile_get_for_user_with_profile(self):
+ """
+ If profile exists a viewprofile.html template will be rendered
+ """
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:view_profile'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/view_profile.html')
+
+ def test_edit_profile_post(self):
+ """
+ POST request to edit_profile view should update the user's profile
+ """
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+ response = self.client.post(reverse('yaksh:edit_profile'),
+ data={
+ 'user': self.user2,
+ 'first_name': 'new_first_name',
+ 'last_name': 'new_last_name',
+ 'roll_number': 20,
+ 'institute': 'new_institute',
+ 'department': 'Aerospace',
+ 'position': 'new_position'
+ }
+ )
+ updated_profile_user = User.objects.get(id=self.user2.id)
+ updated_profile = Profile.objects.get(user=updated_profile_user)
+ self.assertEqual(updated_profile_user.first_name, 'new_first_name')
+ self.assertEqual(updated_profile_user.last_name, 'new_last_name')
+ self.assertEqual(updated_profile.roll_number, '20')
+ self.assertEqual(updated_profile.institute, 'new_institute')
+ self.assertEqual(updated_profile.department, 'Aerospace')
+ self.assertEqual(updated_profile.position, 'new_position')
+
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/profile_updated.html')
+
+ def test_edit_profile_get(self):
+ """
+ GET request to edit profile should display profile form
+ """
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:edit_profile'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/editprofile.html')
+
+class TestAddQuiz(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # 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'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # 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.pre_req_quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+
+ self.quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+
+ def tearDown(self):
+ self.client.logout()
+ self.user.delete()
+ self.student.delete()
+ self.quiz.delete()
+ self.pre_req_quiz.delete()
+ self.course.delete()
+
+ def test_view_profile_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:add_quiz'), follow=True)
+ redirect_destination = '/exam/login/?next=%2Fexam%2Fmanage%2Faddquiz%2F'
+ self.assertRedirects(response, redirect_destination)
+
+ def test_view_profile_denies_non_moderator(self):
+ """
+ If not moderator in redirect to login page
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:add_quiz'), follow=True)
+ self.assertEqual(response.status_code, 404)
+
+ def test_add_quiz_get(self):
+ """
+ GET request to add question should display add quiz form
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:add_quiz'))
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_quiz.html')
+ self.assertIsNotNone(response.context['form'])
+
+ def test_add_quiz_post_existing_quiz(self):
+ """
+ POST request to add quiz should edit quiz if quiz exists
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.post(reverse('yaksh:edit_quiz',
+ kwargs={'quiz_id': self.quiz.id}),
+ data={
+ 'start_date_time': datetime(2016, 1, 10, 9, 0, 15, 0),
+ 'end_date_time': datetime(2016, 1, 15, 9, 0, 15, 0),
+ 'duration': 30,
+ 'active': False,
+ 'attempts_allowed': 5,
+ 'time_between_attempts': 1,
+ 'description': 'updated demo quiz',
+ 'pass_criteria': 40,
+ 'language': 'java',
+ 'prerequisite': self.pre_req_quiz.id,
+ 'course': self.course.id
+ }
+ )
+
+ updated_quiz = Quiz.objects.get(id=self.quiz.id)
+ self.assertEqual(updated_quiz.start_date_time,
+ datetime(2016, 1, 10, 9, 0, 15, 0)
+ )
+ self.assertEqual(updated_quiz.end_date_time,
+ datetime(2016, 1, 15, 9, 0, 15, 0)
+ )
+ self.assertEqual(updated_quiz.duration, 30)
+ self.assertEqual(updated_quiz.active, False)
+ self.assertEqual(updated_quiz.attempts_allowed, 5)
+ 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/')
+
+ def test_add_quiz_post_new_quiz(self):
+ """
+ POST request to add quiz should add new quiz if no quiz exists
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.post(reverse('yaksh:add_quiz'),
+ data={
+ 'start_date_time': datetime(2016, 1, 10, 9, 0, 15, 0),
+ 'end_date_time': datetime(2016, 1, 15, 9, 0, 15, 0),
+ 'duration': 50,
+ 'active': True,
+ 'attempts_allowed': -1,
+ 'time_between_attempts': 2,
+ 'description': 'new demo quiz',
+ 'pass_criteria': 50,
+ 'language': 'python',
+ 'prerequisite': self.pre_req_quiz.id,
+ 'course': self.course.id
+ }
+ )
+
+
+ quiz_list = Quiz.objects.all().order_by('-id')
+ new_quiz = quiz_list[0]
+ self.assertEqual(new_quiz.start_date_time,
+ datetime(2016, 1, 10, 9, 0, 15, 0)
+ )
+ self.assertEqual(new_quiz.end_date_time,
+ datetime(2016, 1, 15, 9, 0, 15, 0)
+ )
+ self.assertEqual(new_quiz.duration, 50)
+ self.assertEqual(new_quiz.active, True)
+ self.assertEqual(new_quiz.attempts_allowed, -1)
+ 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/designquestionpaper/')
+
+class TestAddTeacher(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # 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'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # 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.pre_req_quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+
+ self.quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+
+ def tearDown(self):
+ self.client.logout()
+ self.user.delete()
+ self.student.delete()
+ self.quiz.delete()
+ self.pre_req_quiz.delete()
+ self.course.delete()
+
+ def test_add_teacher_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ redirect_destination = ('/exam/login/?next=%2Fexam'
+ '%2Fmanage%2Faddteacher%2F{0}%2F'.format(self.course.id))
+ self.assertRedirects(response, redirect_destination)
+
+ def test_add_teacher_denies_non_moderator(self):
+ """
+ If not moderator redirect to login page
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_add_teacher_get(self):
+ """
+ GET request to add teacher should display list of teachers
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ 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')
+ self.assertEqual(response.context['course'], self.course)
+
+ def test_add_teacher_post(self):
+ """
+ POST request to add teacher should add teachers to a course
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ teacher_id_list = []
+
+ for i in range(5):
+ teacher = User.objects.create_user(
+ username='demo_teacher{}'.format(i),
+ password='demo_teacher_pass{}'.format(i),
+ first_name='teacher_first_name{}'.format(i),
+ last_name='teacher_last_name{}'.format(i),
+ email='demo{}@test.com'.format(i)
+ )
+
+ teacher_profile = Profile.objects.create(
+ user=teacher,
+ roll_number='T{}'.format(i),
+ institute='IIT',
+ department='Chemical',
+ position='Teacher'
+ )
+ teacher_id_list.append(teacher.id)
+
+ response = self.client.post(reverse('yaksh:add_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
+ data={'check': teacher_id_list}
+ )
+
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/addteacher.html')
+ self.assertEqual(response.context['status'], True)
+ for t_id in teacher_id_list:
+ teacher_object = User.objects.get(id=t_id)
+ self.assertIn(teacher_object, response.context['teachers_added'])
+ self.assertIn(teacher_object, self.course.teachers.all())
+
+class TestRemoveTeacher(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # 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'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # 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.pre_req_quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+
+ self.quiz = Quiz.objects.create(
+ start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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
+ )
+ def tearDown(self):
+ self.client.logout()
+ self.user.delete()
+ self.student.delete()
+ self.quiz.delete()
+ self.pre_req_quiz.delete()
+ self.course.delete()
+
+ def test_remove_teacher_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:remove_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ redirect_destination = ('/exam/login/?next=%2Fexam'
+ '%2Fmanage%2Fremove_teachers%2F{0}%2F'.format(self.course.id))
+ self.assertRedirects(response, redirect_destination)
+
+ def test_remove_teacher_denies_non_moderator(self):
+ """
+ If not moderator redirect to login page
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:remove_teacher',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_remove_teacher_post(self):
+ """
+ POST request should remove moderator from course
+ """
+ teacher_id_list = []
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+
+ for i in range(5):
+ teacher = User.objects.create_user(
+ username='remove_teacher{}'.format(i),
+ password='remove_teacher_pass{}'.format(i),
+ first_name='remove_teacher_first_name{}'.format(i),
+ last_name='remove_teacher_last_name{}'.format(i),
+ email='remove_teacher{}@test.com'.format(i)
+ )
+
+ teacher_profile = Profile.objects.create(
+ user=teacher,
+ roll_number='RT{}'.format(i),
+ institute='IIT',
+ department='Aeronautical',
+ position='Teacher'
+ )
+ 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}
+ ),
+ data={'remove': teacher_id_list}
+ )
+
+ self.assertEqual(response.status_code, 302)
+ redirect_destination = '/exam/manage/courses/'
+ self.assertRedirects(response, redirect_destination)
+ for t_id in teacher_id_list:
+ teacher = User.objects.get(id=t_id)
+ self.assertNotIn(teacher, self.course.teachers.all())
\ No newline at end of file
diff --git a/yaksh/urls.py b/yaksh/urls.py
index d7b56e4..3aff9a4 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -4,6 +4,7 @@ from django.contrib.auth.views import password_reset, password_reset_confirm,\
password_reset_done, password_reset_complete, password_change,\
password_change_done
+app_name = 'yaksh'
urlpatterns = [
url(r'^forgotpassword/$', password_reset, name="password_reset"),
url(r'^password_reset/(?P
[0-9A-Za-z]+)-(?P.+)/$',
@@ -19,7 +20,7 @@ urlpatterns = [
]
urlpatterns += [
url(r'^$', views.index),
- url(r'^login/$', views.user_login),
+ url(r'^login/$', views.user_login, name='login'),
url(r'^quizzes/$', views.quizlist_user),
url(r'^results/$', views.results_user),
url(r'^start/$', views.start),
@@ -42,8 +43,8 @@ urlpatterns += [
url(r'^manage/$', views.prof_manage),
url(r'^manage/addquestion/$', views.add_question),
url(r'^manage/addquestion/(?P\d+)/$', views.edit_question),
- url(r'^manage/addquiz/$', views.add_quiz),
- url(r'^manage/addquiz/(?P\d+)/$', views.add_quiz),
+ url(r'^manage/addquiz/$', views.add_quiz, name='add_quiz'),
+ url(r'^manage/addquiz/(?P\d+)/$', views.add_quiz, name='edit_quiz'),
url(r'^manage/gradeuser/$', views.grade_user),
url(r'^manage/gradeuser/(?P\d+)/$',views.grade_user),
url(r'^manage/gradeuser/(?P\d+)/(?P\d+)/$',views.grade_user),
@@ -57,7 +58,7 @@ urlpatterns += [
url(r'^manage/user_data/(?P\d+)/(?P\d+)/$',
views.user_data),
url(r'^manage/user_data/(?P\d+)/$', views.user_data),
- url(r'^manage/designquestionpaper/$', views.design_questionpaper),
+ url(r'^manage/designquestionpaper/$', views.design_questionpaper, name='design_questionpaper'),
url(r'^manage/designquestionpaper/(?P\d+)/$',\
views.design_questionpaper),
url(r'^manage/statistics/question/(?P\d+)/$',
@@ -78,17 +79,17 @@ urlpatterns += [
url(r'manage/toggle_status/(?P\d+)/$', views.toggle_course_status),
url(r'^ajax/questionpaper/(?P.+)/$', views.ajax_questionpaper),
url(r'^ajax/questions/filter/$', views.ajax_questions_filter),
- url(r'^editprofile/$', views.edit_profile),
- url(r'^viewprofile/$', views.view_profile),
+ url(r'^editprofile/$', views.edit_profile, name='edit_profile'),
+ url(r'^viewprofile/$', views.view_profile, name='view_profile'),
url(r'^manage/enroll/(?P\d+)/$', views.enroll),
url(r'manage/enroll/rejected/(?P\d+)/$',
views.enroll, {'was_rejected': True}),
url(r'manage/enrolled/reject/(?P\d+)/$',
views.reject, {'was_enrolled': True}),
url(r'^manage/searchteacher/(?P\d+)/$', views.search_teacher),
- url(r'^manage/addteacher/(?P\d+)/$', views.add_teacher),
+ url(r'^manage/addteacher/(?P\d+)/$', views.add_teacher, name='add_teacher'),
url(r'^manage/allotted_course/$', views.allotted_courses),
- url(r'^manage/remove_teachers/(?P\d+)/$', views.remove_teachers),
+ url(r'^manage/remove_teachers/(?P\d+)/$', views.remove_teachers, name='remove_teacher'),
url(r'^manage/download_questions/$', views.show_all_questions),
url(r'^manage/upload_questions/$', views.show_all_questions),
url(r'^manage/(?P[\w\-]+)/(?P\d+)/$', views.test_quiz)
diff --git a/yaksh/views.py b/yaksh/views.py
index e2ff84f..87e8bf6 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -7,6 +7,7 @@ from datetime import datetime
import collections
import csv
from django.http import HttpResponse
+from django.core.urlresolvers import reverse
from django.contrib.auth import login, logout, authenticate
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
@@ -22,12 +23,13 @@ from taggit.models import Tag
from itertools import chain
import json
# Local imports.
-from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course
-from yaksh.models import Profile, Answer, AnswerPaper, User, TestCase
+from yaksh.models import get_model_class, Quiz, Question, QuestionPaper,\
+ QuestionSet, Course, Profile, Answer, AnswerPaper, User, TestCase,\
+ has_profile
from yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\
- QuestionForm, RandomQuestionForm,\
- QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\
- get_object_form
+ QuestionForm, RandomQuestionForm,\
+ QuestionFilterForm, CourseForm, ProfileForm, UploadFileForm,\
+ get_object_form
from yaksh.xmlrpc_clients import code_server
from settings import URL_ROOT
from yaksh.models import AssignmentUpload
@@ -70,10 +72,6 @@ def is_moderator(user):
if user.groups.filter(name='moderator').count() == 1:
return True
-def has_profile(user):
- """ check if user has profile """
- return True if hasattr(user, 'profile') else False
-
def add_to_group(users):
""" add users to moderator group """
group = Group.objects.get(name="moderator")
@@ -232,7 +230,7 @@ def add_quiz(request, quiz_id=None):
form = QuizForm(request.POST, user=user)
if form.is_valid():
form.save()
- return my_redirect("/exam/manage/designquestionpaper")
+ return my_redirect(reverse('yaksh:design_questionpaper'))
else:
quiz = Quiz.objects.get(id=quiz_id)
form = QuizForm(request.POST, user=user, instance=quiz)
@@ -240,10 +238,6 @@ def add_quiz(request, quiz_id=None):
form.save()
context["quiz_id"] = quiz_id
return my_redirect("/exam/manage/")
-
- context["form"] = form
- return my_render_to_response('yaksh/add_quiz.html', context,
- context_instance=ci)
else:
if quiz_id is None:
form = QuizForm(user=user)
@@ -794,20 +788,6 @@ def monitor(request, questionpaper_id=None):
context_instance=ci)
-@login_required
-def show_all_users(request):
- """Shows all the users who have taken various exams/quiz."""
-
- user = request.user
- if not user.is_authenticated() or not is_moderator(user):
- raise Http404('You are not allowed to view this page !')
- user = User.objects.filter(username__contains="")
- questionpaper = AnswerPaper.objects.all()
- context = {'question': questionpaper}
- return my_render_to_response('yaksh/showusers.html', context,
- context_instance=RequestContext(request))
-
-
@csrf_exempt
def ajax_questions_filter(request):
"""Ajax call made when filtering displayed questions."""
--
cgit
From 4cd9882c2e0e294b86e447e769bea6f66f69ff28 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Wed, 25 May 2016 18:31:46 +0530
Subject: Add further tests for views
---
yaksh/models.py | 2 +-
yaksh/test_views.py | 494 ++++++++++++++++++++++++++++++++++++++++++++++++++--
yaksh/urls.py | 16 +-
yaksh/views.py | 13 +-
4 files changed, 493 insertions(+), 32 deletions(-)
diff --git a/yaksh/models.py b/yaksh/models.py
index cc63615..ba092b8 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -163,7 +163,7 @@ class Profile(models.Model):
department = models.CharField(max_length=64)
position = models.CharField(max_length=64)
timezone = models.CharField(max_length=64,
- choices=[(tz, tz) for tz in pytz.common_timezones])
+ choices=[(tz, tz) for tz in pytz.common_timezones])
###############################################################################
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 42b7f34..73a3f4f 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -1,4 +1,5 @@
from datetime import datetime
+import pytz
from django.contrib.auth.models import Group
from django.core.urlresolvers import reverse
@@ -37,7 +38,8 @@ class TestProfile(TestCase):
roll_number=10,
institute='IIT',
department='Chemical',
- position='Student'
+ position='Student',
+ timezone='UTC'
)
def tearDown(self):
@@ -108,7 +110,8 @@ class TestProfile(TestCase):
'roll_number': 20,
'institute': 'new_institute',
'department': 'Aerospace',
- 'position': 'new_position'
+ 'position': 'new_position',
+ 'timezone': 'UTC'
}
)
updated_profile_user = User.objects.get(id=self.user2.id)
@@ -156,7 +159,8 @@ class TestAddQuiz(TestCase):
roll_number=10,
institute='IIT',
department='Chemical',
- position='Moderator'
+ position='Moderator',
+ timezone='UTC'
)
# Create Student
@@ -244,11 +248,12 @@ class TestAddQuiz(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
+ tzone = pytz.timezone('UTC')
response = self.client.post(reverse('yaksh:edit_quiz',
kwargs={'quiz_id': self.quiz.id}),
data={
- 'start_date_time': datetime(2016, 1, 10, 9, 0, 15, 0),
- 'end_date_time': datetime(2016, 1, 15, 9, 0, 15, 0),
+ 'start_date_time': '2016-01-10 09:00:15', #datetime(2016, 1, 10, 9, 0, 15, 0, tzone),
+ 'end_date_time': '2016-01-15 09:00:15', #datetime(2016, 1, 15, 9, 0, 15, 0, tzone),
'duration': 30,
'active': False,
'attempts_allowed': 5,
@@ -263,10 +268,10 @@ class TestAddQuiz(TestCase):
updated_quiz = Quiz.objects.get(id=self.quiz.id)
self.assertEqual(updated_quiz.start_date_time,
- datetime(2016, 1, 10, 9, 0, 15, 0)
+ datetime(2016, 1, 10, 9, 0, 15, 0, tzone)
)
self.assertEqual(updated_quiz.end_date_time,
- datetime(2016, 1, 15, 9, 0, 15, 0)
+ datetime(2016, 1, 15, 9, 0, 15, 0, tzone)
)
self.assertEqual(updated_quiz.duration, 30)
self.assertEqual(updated_quiz.active, False)
@@ -289,10 +294,12 @@ class TestAddQuiz(TestCase):
username=self.user.username,
password=self.user_plaintext_pass
)
+
+ tzone = pytz.timezone('UTC')
response = self.client.post(reverse('yaksh:add_quiz'),
data={
- 'start_date_time': datetime(2016, 1, 10, 9, 0, 15, 0),
- 'end_date_time': datetime(2016, 1, 15, 9, 0, 15, 0),
+ 'start_date_time': '2016-01-10 09:00:15', #datetime(2016, 1, 10, 9, 0, 15, 0, tzone),
+ 'end_date_time': '2016-01-15 09:00:15', #datetime(2016, 1, 15, 9, 0, 15, 0, tzone),
'duration': 50,
'active': True,
'attempts_allowed': -1,
@@ -304,15 +311,13 @@ class TestAddQuiz(TestCase):
'course': self.course.id
}
)
-
-
quiz_list = Quiz.objects.all().order_by('-id')
new_quiz = quiz_list[0]
self.assertEqual(new_quiz.start_date_time,
- datetime(2016, 1, 10, 9, 0, 15, 0)
+ datetime(2016, 1, 10, 9, 0, 15, 0, tzone)
)
self.assertEqual(new_quiz.end_date_time,
- datetime(2016, 1, 15, 9, 0, 15, 0)
+ datetime(2016, 1, 15, 9, 0, 15, 0, tzone)
)
self.assertEqual(new_quiz.duration, 50)
self.assertEqual(new_quiz.active, True)
@@ -348,7 +353,8 @@ class TestAddTeacher(TestCase):
roll_number=10,
institute='IIT',
department='Chemical',
- position='Moderator'
+ position='Moderator',
+ timezone='UTC'
)
# Create Student
@@ -464,7 +470,8 @@ class TestAddTeacher(TestCase):
roll_number='T{}'.format(i),
institute='IIT',
department='Chemical',
- position='Teacher'
+ position='Teacher',
+ timezone='UTC'
)
teacher_id_list.append(teacher.id)
@@ -503,7 +510,8 @@ class TestRemoveTeacher(TestCase):
roll_number=10,
institute='IIT',
department='Chemical',
- position='Moderator'
+ position='Moderator',
+ timezone='UTC'
)
# Create Student
@@ -602,7 +610,8 @@ class TestRemoveTeacher(TestCase):
roll_number='RT{}'.format(i),
institute='IIT',
department='Aeronautical',
- position='Teacher'
+ position='Teacher',
+ timezone='UTC'
)
teacher_id_list.append(teacher.id)
self.course.teachers.add(teacher)
@@ -618,4 +627,453 @@ class TestRemoveTeacher(TestCase):
self.assertRedirects(response, redirect_destination)
for t_id in teacher_id_list:
teacher = User.objects.get(id=t_id)
- self.assertNotIn(teacher, self.course.teachers.all())
\ No newline at end of file
+ self.assertNotIn(teacher, self.course.teachers.all())
+
+
+class TestCourses(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # Create Moderator with profile
+ self.user1_plaintext_pass = 'demo1'
+ self.user1 = User.objects.create_user(
+ username='demo_user1',
+ password=self.user1_plaintext_pass,
+ first_name='user1_first_name',
+ last_name='user1_last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user1,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ self.user2_plaintext_pass = 'demo2'
+ self.user2 = User.objects.create_user(
+ username='demo_user2',
+ password=self.user2_plaintext_pass,
+ first_name='user2_first_name',
+ last_name='user2_last_name',
+ email='demo2@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user2,
+ roll_number=10,
+ institute='IIT',
+ department='Aeronautical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # Add to moderator group
+ 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.user2_course = Course.objects.create(name="Java Course",
+ enrollment="Enroll Request", creator=self.user2)
+
+ def tearDown(self):
+ self.client.logout()
+ self.user1.delete()
+ self.user2.delete()
+ self.student.delete()
+ self.user1_course.delete()
+ self.user2_course.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=%2Fexam'
+ '%2Fmanage%2Fcourses%2F')
+ self.assertRedirects(response, redirect_destination)
+
+ def test_courses_denies_non_moderator(self):
+ """
+ If not moderator redirect to login page
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:courses'),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_courses_get(self):
+ """
+ GET request should return courses page
+ """
+ self.client.login(
+ username=self.user1.username,
+ password=self.user1_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:courses'),
+ follow=True
+ )
+
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/courses.html')
+ self.assertIn(self.user1_course, response.context['courses'])
+ self.assertNotIn(self.user2_course, response.context['courses'])
+
+
+class TestCourseDetail(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # Create Moderator with profile
+ self.user1_plaintext_pass = 'demo1'
+ self.user1 = User.objects.create_user(
+ username='demo_user1',
+ password=self.user1_plaintext_pass,
+ first_name='user1_first_name',
+ last_name='user1_last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user1,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ self.user2_plaintext_pass = 'demo2'
+ self.user2 = User.objects.create_user(
+ username='demo_user2',
+ password=self.user2_plaintext_pass,
+ first_name='user2_first_name',
+ last_name='user2_last_name',
+ email='demo2@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user2,
+ roll_number=10,
+ institute='IIT',
+ department='Aeronautical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # Add to moderator group
+ 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)
+
+ def tearDown(self):
+ self.client.logout()
+ self.user1.delete()
+ self.user2.delete()
+ self.student.delete()
+ self.user1_course.delete()
+
+ def test_course_detail_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:add_course'),
+ follow=True
+ )
+ redirect_destination = ('/exam/login/?next=%2Fexam'
+ '%2Fmanage%2Fadd_course%2F')
+ self.assertRedirects(response, redirect_destination)
+
+ def test_course_detail_denies_non_moderator(self):
+ """
+ If not moderator redirect to 404
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:add_course'),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_course_detail_denies_unrelated_moderators(self):
+ """
+ If not creator of course or related teacher redirect to 404
+ """
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:course_detail',
+ kwargs={'course_id': self.user1_course.id}
+ ),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_course_detail_get(self):
+ """
+ If not creator of course or related teacher redirect to 404
+ """
+ self.client.login(
+ username=self.user1.username,
+ password=self.user1_plaintext_pass
+ )
+ 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'])
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/course_detail.html')
+
+class TestEnrollRequest(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # Create Moderator with profile
+ self.user1_plaintext_pass = 'demo1'
+ self.user1 = User.objects.create_user(
+ username='demo_user1',
+ password=self.user1_plaintext_pass,
+ first_name='user1_first_name',
+ last_name='user1_last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user1,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ self.user2_plaintext_pass = 'demo2'
+ self.user2 = User.objects.create_user(
+ username='demo_user2',
+ password=self.user2_plaintext_pass,
+ first_name='user2_first_name',
+ last_name='user2_last_name',
+ email='demo2@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user2,
+ roll_number=10,
+ institute='IIT',
+ department='Aeronautical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # Add to moderator group
+ 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)
+
+ def tearDown(self):
+ self.client.logout()
+ self.user1.delete()
+ self.user2.delete()
+ self.student.delete()
+ self.course.delete()
+
+ def test_enroll_request_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ redirect_destination = ('/exam/login/?next=%2Fexam'
+ '%2Fenroll_request%2F{}%2F'.format(self.course.id))
+ self.assertRedirects(response, redirect_destination)
+
+ def test_enroll_request_get_for_student(self):
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertRedirects(response, '/exam/quizzes/')
+
+ def test_enroll_request_get_for_moderator(self):
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:enroll_request',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertRedirects(response, '/exam/manage/')
+
+
+class TestSelfEnroll(TestCase):
+ def setUp(self):
+ self.client = Client()
+
+ self.mod_group = Group.objects.create(name='moderator')
+
+ # Create Moderator with profile
+ self.user1_plaintext_pass = 'demo1'
+ self.user1 = User.objects.create_user(
+ username='demo_user1',
+ password=self.user1_plaintext_pass,
+ first_name='user1_first_name',
+ last_name='user1_last_name',
+ email='demo@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user1,
+ roll_number=10,
+ institute='IIT',
+ department='Chemical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ self.user2_plaintext_pass = 'demo2'
+ self.user2 = User.objects.create_user(
+ username='demo_user2',
+ password=self.user2_plaintext_pass,
+ first_name='user2_first_name',
+ last_name='user2_last_name',
+ email='demo2@test.com'
+ )
+
+ Profile.objects.create(
+ user=self.user2,
+ roll_number=10,
+ institute='IIT',
+ department='Aeronautical',
+ position='Moderator',
+ timezone='UTC'
+ )
+
+ # Create Student
+ self.student_plaintext_pass = 'demo_student'
+ self.student = User.objects.create_user(
+ username='demo_student',
+ password=self.student_plaintext_pass,
+ first_name='student_first_name',
+ last_name='student_last_name',
+ email='demo_student@test.com'
+ )
+
+ # Add to moderator group
+ 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)
+
+ def tearDown(self):
+ self.client.logout()
+ self.user1.delete()
+ self.user2.delete()
+ self.student.delete()
+ self.course.delete()
+
+ def test_self_enroll_denies_anonymous(self):
+ response = self.client.get(reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ redirect_destination = ('/exam/login/?next=%2Fexam'
+ '%2Fself_enroll%2F{}%2F'.format(self.course.id))
+ self.assertRedirects(response, redirect_destination)
+
+ def test_enroll_request_get_for_student(self):
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertRedirects(response, '/exam/quizzes/')
+
+ def test_enroll_request_get_for_moderator(self):
+ self.client.login(
+ username=self.user2.username,
+ password=self.user2_plaintext_pass
+ )
+
+ response = self.client.get(reverse('yaksh:self_enroll',
+ kwargs={'course_id': self.course.id}
+ ),
+ follow=True
+ )
+ self.assertRedirects(response, '/exam/manage/')
diff --git a/yaksh/urls.py b/yaksh/urls.py
index 3aff9a4..fa1713c 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -21,7 +21,7 @@ urlpatterns = [
urlpatterns += [
url(r'^$', views.index),
url(r'^login/$', views.user_login, name='login'),
- url(r'^quizzes/$', views.quizlist_user),
+ url(r'^quizzes/$', views.quizlist_user, name='quizlist_user'),
url(r'^results/$', views.results_user),
url(r'^start/$', views.start),
url(r'^start/(?P\d+)/$', views.start),
@@ -38,9 +38,9 @@ urlpatterns += [
views.skip),
url(r'^(?P\d+)/skip/(?P\d+)/(?P\d+)/(?P\d+)/$',
views.skip),
- url(r'^enroll_request/(?P\d+)/$', views.enroll_request),
- url(r'^self_enroll/(?P\d+)/$', views.self_enroll),
- url(r'^manage/$', views.prof_manage),
+ url(r'^enroll_request/(?P\d+)/$', views.enroll_request, name='enroll_request'),
+ url(r'^self_enroll/(?P\d+)/$', views.self_enroll, name='self_enroll'),
+ url(r'^manage/$', views.prof_manage, name='manage'),
url(r'^manage/addquestion/$', views.add_question),
url(r'^manage/addquestion/(?P\d+)/$', views.edit_question),
url(r'^manage/addquiz/$', views.add_quiz, name='add_quiz'),
@@ -67,9 +67,9 @@ urlpatterns += [
views.show_statistics),
url(r'^manage/monitor/download_csv/(?P\d+)/$',
views.download_csv),
- url(r'manage/courses/$', views.courses),
- url(r'manage/add_course/$', views.add_course),
- url(r'manage/course_detail/(?P\d+)/$', views.course_detail),
+ url(r'manage/courses/$', views.courses, name='courses'),
+ url(r'manage/add_course/$', views.add_course, name='add_course'),
+ url(r'manage/course_detail/(?P\d+)/$', views.course_detail, name='course_detail'),
url(r'manage/enroll/(?P\d+)/(?P\d+)/$', views.enroll),
url(r'manage/enroll/rejected/(?P\d+)/(?P\d+)/$',
views.enroll, {'was_rejected': True}),
@@ -94,5 +94,3 @@ urlpatterns += [
url(r'^manage/upload_questions/$', views.show_all_questions),
url(r'^manage/(?P[\w\-]+)/(?P\d+)/$', views.test_quiz)
]
-
-
diff --git a/yaksh/views.py b/yaksh/views.py
index 87e8bf6..56746b0 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -69,7 +69,7 @@ def get_user_dir(user):
def is_moderator(user):
"""Check if the user is having moderator rights"""
- if user.groups.filter(name='moderator').count() == 1:
+ if user.groups.filter(name='moderator').exists():
return True
def add_to_group(users):
@@ -219,7 +219,6 @@ def edit_question(request, question_id=None):
def add_quiz(request, quiz_id=None):
"""To add a new quiz in the database.
Create a new quiz and store it."""
-
user = request.user
ci = RequestContext(request)
if not is_moderator(user):
@@ -612,7 +611,10 @@ def enroll_request(request, course_id):
ci = RequestContext(request)
course = get_object_or_404(Course, pk=course_id)
course.request(user)
- return my_redirect('/exam/manage/')
+ if is_moderator(user):
+ return my_redirect('/exam/manage/')
+ else:
+ return my_redirect('/exam/quizzes/')
@login_required
@@ -623,7 +625,10 @@ def self_enroll(request, course_id):
if course.is_self_enroll():
was_rejected = False
course.enroll(was_rejected, user)
- return my_redirect('/exam/manage/')
+ if is_moderator(user):
+ return my_redirect('/exam/manage/')
+ else:
+ return my_redirect('/exam/quizzes/')
@login_required
--
cgit
From 5e54ec5bbdcb79224d29226cfbbf852e3c3d7339 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Fri, 10 Jun 2016 16:53:17 +0530
Subject: Fix Django versions in travis.yml and minor test errors
---
.travis.yml | 4 ++--
online_test/urls.py | 2 +-
yaksh/models.py | 2 +-
yaksh/urls.py | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 6a4c8cf..508336d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,8 +4,8 @@ python:
- "2.7"
env:
- - DJANGO=1.6.4
- - DJANGO=1.9
+ - DJANGO=1.8.13
+ - DJANGO=1.9.5
# command to install dependencies
install:
diff --git a/online_test/urls.py b/online_test/urls.py
index 9c55574..4d8c042 100644
--- a/online_test/urls.py
+++ b/online_test/urls.py
@@ -9,5 +9,5 @@ urlpatterns = [
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
- url(r'^exam/', include('yaksh.urls')),
+ url(r'^exam/', include('yaksh.urls', namespace='yaksh', app_name='yaksh')),
]
diff --git a/yaksh/models.py b/yaksh/models.py
index ba092b8..c48eef1 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -42,7 +42,7 @@ test_case_types = (
attempts = [(i, i) for i in range(1, 6)]
attempts.append((-1, 'Infinite'))
-days_between_attempts = ((j, j) for j in range(401))
+days_between_attempts = [(j, j) for j in range(401)]
test_status = (
('inprogress', 'Inprogress'),
diff --git a/yaksh/urls.py b/yaksh/urls.py
index fa1713c..7a41f95 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -4,7 +4,7 @@ from django.contrib.auth.views import password_reset, password_reset_confirm,\
password_reset_done, password_reset_complete, password_change,\
password_change_done
-app_name = 'yaksh'
+# app_name = 'yaksh'
urlpatterns = [
url(r'^forgotpassword/$', password_reset, name="password_reset"),
url(r'^password_reset/(?P[0-9A-Za-z]+)-(?P.+)/$',
--
cgit
From 2986a8a92b0548b3e7e960aea1c175bb4eddac11 Mon Sep 17 00:00:00 2001
From: ankitjavalkar
Date: Fri, 8 Jul 2016 14:33:06 +0530
Subject: Add timezones while creating quizzes in view tests
---
yaksh/test_views.py | 48 +++++++++++++++++++++++++++---------------------
1 file changed, 27 insertions(+), 21 deletions(-)
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 73a3f4f..d673ac3 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -142,7 +142,8 @@ class TestAddQuiz(TestCase):
def setUp(self):
self.client = Client()
- self.mod_group = Group.objects.create(name='moderator')
+ self.mod_group = Group.objects.create(name='moderator')
+ tzone = pytz.timezone('UTC')
# Create Moderator with profile
self.user_plaintext_pass = 'demo'
@@ -180,8 +181,8 @@ class TestAddQuiz(TestCase):
enrollment="Enroll Request", creator=self.user)
self.pre_req_quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
@@ -190,8 +191,8 @@ class TestAddQuiz(TestCase):
)
self.quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
@@ -252,8 +253,8 @@ class TestAddQuiz(TestCase):
response = self.client.post(reverse('yaksh:edit_quiz',
kwargs={'quiz_id': self.quiz.id}),
data={
- 'start_date_time': '2016-01-10 09:00:15', #datetime(2016, 1, 10, 9, 0, 15, 0, tzone),
- 'end_date_time': '2016-01-15 09:00:15', #datetime(2016, 1, 15, 9, 0, 15, 0, tzone),
+ 'start_date_time': '2016-01-10 09:00:15',
+ 'end_date_time': '2016-01-15 09:00:15',
'duration': 30,
'active': False,
'attempts_allowed': 5,
@@ -298,8 +299,8 @@ class TestAddQuiz(TestCase):
tzone = pytz.timezone('UTC')
response = self.client.post(reverse('yaksh:add_quiz'),
data={
- 'start_date_time': '2016-01-10 09:00:15', #datetime(2016, 1, 10, 9, 0, 15, 0, tzone),
- 'end_date_time': '2016-01-15 09:00:15', #datetime(2016, 1, 15, 9, 0, 15, 0, tzone),
+ 'start_date_time': '2016-01-10 09:00:15',
+ 'end_date_time': '2016-01-15 09:00:15',
'duration': 50,
'active': True,
'attempts_allowed': -1,
@@ -336,7 +337,8 @@ class TestAddTeacher(TestCase):
def setUp(self):
self.client = Client()
- self.mod_group = Group.objects.create(name='moderator')
+ self.mod_group = Group.objects.create(name='moderator')
+ tzone = pytz.timezone('UTC')
# Create Moderator with profile
self.user_plaintext_pass = 'demo'
@@ -374,8 +376,8 @@ class TestAddTeacher(TestCase):
enrollment="Enroll Request", creator=self.user)
self.pre_req_quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
@@ -384,8 +386,8 @@ class TestAddTeacher(TestCase):
)
self.quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
@@ -493,7 +495,8 @@ class TestRemoveTeacher(TestCase):
def setUp(self):
self.client = Client()
- self.mod_group = Group.objects.create(name='moderator')
+ self.mod_group = Group.objects.create(name='moderator')
+ tzone = pytz.timezone('UTC')
# Create Moderator with profile
self.user_plaintext_pass = 'demo'
@@ -531,8 +534,8 @@ class TestRemoveTeacher(TestCase):
enrollment="Enroll Request", creator=self.user)
self.pre_req_quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
@@ -541,8 +544,8 @@ class TestRemoveTeacher(TestCase):
)
self.quiz = Quiz.objects.create(
- start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0),
- end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0),
+ 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,
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
@@ -623,8 +626,11 @@ class TestRemoveTeacher(TestCase):
)
self.assertEqual(response.status_code, 302)
- redirect_destination = '/exam/manage/courses/'
- self.assertRedirects(response, redirect_destination)
+ redirect_destination = '/exam/manage/courses'
+ self.assertRedirects(response, redirect_destination,
+ status_code=302,
+ target_status_code=301
+ )
for t_id in teacher_id_list:
teacher = User.objects.get(id=t_id)
self.assertNotIn(teacher, self.course.teachers.all())
--
cgit