blob: 32d3ba13ed49254ac42aa2b9151e5ae4551e3bce [file] [log] [blame]
# Copyright 2013 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Unit tests for project manage view."""
import unittest
from datetime import date
from django import http
from seeder import profile as profile_seeder
from seeder import user as user_seeder
from soc.modules.gsoc.models import project_survey as project_survey_model
from summerofcode.logic import survey as survey_logic
from summerofcode.models import project as project_model
from summerofcode.views import project_manage as project_manage_view
from tests import profile_utils
from tests import survey_utils
from tests import test_utils
from tests.utils import project_utils
def _getProjectAssignMentorsUrl(project):
"""Returns URL to 'Project Assign Mentors' handler for
the specified project.
Args:
project: Project entity.
Returns:
The URL to 'Project Assign Mentors' handler.
"""
return '/gsoc/project/assign_mentors/%s/%s' % (
project.key.parent().id(), project.key.id())
def _getProjectFeaturingAllowedUrl(project_key):
"""Returns URL to 'Project Featuring Allowed' handler for the specified
project.
Args:
project_key: ndb.Key of the project entity.
Returns:
The URL to 'Project Featuring Allowed' handler.
"""
return '/gsoc/project/featuring_allowed/%s/%s' % (
project_key.parent().id(), project_key.id())
def _getProjectFeaturingNotAllowedUrl(project_key):
"""Returns URL to 'Project Featuring Not Allowed' handler for the specified
project.
Args:
project_key: ndb.Key of the project wntity.
Returns:
The URL to 'Project Featuring Not Allowed' handler.
"""
return '/gsoc/project/featuring_disallowed/%s/%s' % (
project_key.parent().id(), project_key.id())
class ManageProjectProgramAdminViewTest(test_utils.GSoCDjangoTestCase):
"""Unit tests for ManageProjectAdminView class."""
def setUp(self):
self.init()
def _seedProjectData(self):
# create a mentor
self.mentor = profile_seeder.seedProfile(
self.program.key(), mentor_for=[self.org.key])
# create a student with a project
self.student = profile_seeder.seedStudent(self.program)
self.project = project_utils.seedNDBProject(
self.student, self.program.key(), org_key=self.org.key,
mentor_key=self.mentor.key)
def _getUrl(self, project):
return '/gsoc/project/manage/admin/%s/%s' % (
project.key.parent().id(), project.key.id())
def testLoneUserAccessForbidden(self):
"""Tests that users without profiles cannot access the page."""
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
self._seedProjectData()
response = self.get(self._getUrl(self.project))
self.assertResponseForbidden(response)
self.assertErrorTemplatesUsed(response)
def testStudentAccessForbidden(self):
"""Tests that students cannot access the page."""
# try to access the page as a student who owns a project
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
student = profile_seeder.seedStudent(self.program, user=user)
# create a project
project = project_utils.seedNDBProject(
student, self.program.key(), org_key=self.org.key)
response = self.get(self._getUrl(project))
self.assertResponseForbidden(response)
self.assertErrorTemplatesUsed(response)
def testMentorAccessForbidden(self):
"""Tests that mentors cannot access the page."""
# try to access the page as a mentor who mentor a project
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
mentor = profile_seeder.seedProfile(
self.program.key(), user=user, mentor_for=[self.org.key])
# create a student with a project
student = profile_seeder.seedStudent(self.program)
project = project_utils.seedNDBProject(
student, self.program.key(), org_key=self.org.key,
mentor_key=mentor.key)
response = self.get(self._getUrl(project))
self.assertResponseForbidden(response)
self.assertErrorTemplatesUsed(response)
def testOrgAdminAccessForbidden(self):
"""Tests that org admins cannot access the page."""
# try to access the page as org admin for organization project
self._seedProjectData()
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
profile_seeder.seedProfile(
self.program.key(), user=user, admin_for=[self.org.key])
response = self.get(self._getUrl(self.project))
self.assertResponseForbidden(response)
self.assertErrorTemplatesUsed(response)
def testProgramAdminAccessGranted(self):
"""Tests that program hosts can access the page."""
self._seedProjectData()
user = user_seeder.seedUser(host_for=[self.program])
profile_utils.loginNDB(user)
response = self.get(self._getUrl(self.project))
self.assertResponseOK(response)
def testExtensionForms(self):
"""Tests that the response contains extension adequate forms."""
self._seedProjectData()
user = user_seeder.seedUser(host_for=[self.program])
profile_utils.loginNDB(user)
# check that no forms are present if there are no evaluations
response = self.get(self._getUrl(self.project))
self.assertListEqual(response.context['extension_forms'], [])
# check that only mideterm form is present for midterm evaluation
properties = {'link_id': project_survey_model.MIDTERM_EVAL}
survey = survey_utils.SurveyHelper(
self.gsoc, False).createStudentEvaluation(override=properties)
response = self.get(self._getUrl(self.project))
self.assertIn(project_manage_view.MIDTERM_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
self.assertNotIn(project_manage_view.FINAL_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
# check that only final form is present for final evaluation
survey.delete()
properties = {'link_id': project_survey_model.FINAL_EVAL}
survey = survey_utils.SurveyHelper(
self.gsoc, False).createStudentEvaluation(override=properties)
response = self.get(self._getUrl(self.project))
self.assertNotIn(project_manage_view.MIDTERM_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
self.assertIn(project_manage_view.FINAL_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
# check that both forms are present for two evaluations
properties = {'link_id': project_survey_model.MIDTERM_EVAL}
survey_utils.SurveyHelper(
self.gsoc, False).createStudentEvaluation(override=properties)
response = self.get(self._getUrl(self.project))
self.assertIn(project_manage_view.MIDTERM_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
self.assertIn(project_manage_view.FINAL_EXTENSION_FORM_NAME,
[form.name for form in response.context['extension_forms']])
def testPersonalExtensionIsSet(self):
"""Tests that personal extension is set for an evaluation."""
self._seedProjectData()
user = user_seeder.seedUser(host_for=[self.program])
profile_utils.loginNDB(user)
# seed midterm evaluation
properties = {'link_id': project_survey_model.MIDTERM_EVAL}
survey = survey_utils.SurveyHelper(
self.gsoc, False).createStudentEvaluation(override=properties)
# set personal extension
start_date = date.today()
end_date = date.today()
post_data = {
project_manage_view.MIDTERM_EXTENSION_FORM_NAME: 'test button',
'start_date': unicode(start_date),
'end_date': unicode(end_date)
}
response = self.post(self._getUrl(self.project), post_data)
self.assertResponseRedirect(response)
# check if personal extension is set properly
extension = survey_logic.getPersonalExtension(
self.student.key, survey.key())
self.assertIsNotNone(extension)
self.assertEqual(start_date, extension.start_date.date())
self.assertEqual(end_date, extension.end_date.date())
def testPersonalExtensionIsSetWithEmptyDate(self):
"""Tests that personal extension is set even if a date is empty."""
self._seedProjectData()
user = user_seeder.seedUser(host_for=[self.program])
profile_utils.loginNDB(user)
# seed midterm evaluation
properties = {'link_id': project_survey_model.MIDTERM_EVAL}
survey = survey_utils.SurveyHelper(
self.gsoc, False).createStudentEvaluation(override=properties)
# set personal extension with no end date
start_date = date.today()
post_data = {
project_manage_view.MIDTERM_EXTENSION_FORM_NAME: 'test button',
'start_date': unicode(start_date),
'end_date': unicode('')
}
response = self.post(self._getUrl(self.project), post_data)
self.assertResponseRedirect(response)
# check if personal extension is set properly
extension = survey_logic.getPersonalExtension(
self.student.key, survey.key())
self.assertIsNotNone(extension)
self.assertEqual(start_date, extension.start_date.date())
self.assertIsNone(extension.end_date)
# update the extension - this time with no start date
end_date = date.today()
post_data = {
project_manage_view.MIDTERM_EXTENSION_FORM_NAME: 'test button',
'start_date': unicode(''),
'end_date': unicode(end_date)
}
response = self.post(self._getUrl(self.project), post_data)
self.assertResponseRedirect(response)
# check if personal extension is set properly
updated_extension = survey_logic.getPersonalExtension(
self.student.key, survey.key())
self.assertIsNotNone(updated_extension)
self.assertIsNone(updated_extension.start_date)
self.assertEqual(end_date, updated_extension.end_date.date())
# check that updated extension is represented by the same entity
self.assertEqual(extension.key, updated_extension.key)
def testProjectStatusChanged(self):
"""Tests that status of the project is changed properly."""
user = user_seeder.seedUser(host_for=[self.program])
profile_utils.loginNDB(user)
student = profile_seeder.seedStudent(self.program)
project = project_utils.seedNDBProject(
student, self.program.key(), org_key=self.org.key)
# withdraw the project
post_data = {
project_manage_view.PROJECT_STATUS_FORM_NAME: 'test button',
'status': project_manage_view._STATUS_WITHDRAWN_ID,
}
response = self.post(self._getUrl(project), post_data)
self.assertResponseRedirect(response)
# check that the project is withdrawn
project = project.key.get()
self.assertEqual(project.status, project_model.Status.WITHDRAWN)
# accept the project again
post_data = {
project_manage_view.PROJECT_STATUS_FORM_NAME: 'test button',
'status': project_manage_view._STATUS_ACCEPTED_ID,
}
response = self.post(self._getUrl(project), post_data)
self.assertResponseRedirect(response)
# check that the project is withdrawn
project = project.key.get()
self.assertEqual(project.status, project_model.Status.ACCEPTED)
_TEST_NUMBER_OF_MENTORS = 3
class ProjectAssignMentorsTest(test_utils.GSoCDjangoTestCase):
"""Unit tests for ProjectAssignMentors class."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
self.init()
student = profile_seeder.seedStudent(self.program)
self.proposal = project_utils.seedNDBProject(
student.key, self.program.key(), org_key=self.org.key)
# TODO(daniel): enable this test when request handlers deal with
# QueryDict objects in tests
@unittest.SkipTest
def testsMentorsAssigned(self):
"""Tests that mentors are assigned properly."""
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
profile_seeder.seedProfile(
self.program.key(), user=user, admin_for=[self.org.key])
assign_mentor = []
for _ in range(_TEST_NUMBER_OF_MENTORS):
assign_mentor.append(
profile_seeder.seedProfile(
self.program.key(), mentor_for=[self.org.key]).key.urlsafe())
postdata = http.QueryDict('')
postdata = postdata.copy()
postdata.update({'assign_mentor': assign_mentor})
response = self.post(
_getProjectAssignMentorsUrl(self.project), postdata=postdata)
self.assertResponseRedirect(response)
class ProjectFeaturingAllowedTest(test_utils.GSoCDjangoTestCase):
"""Unit tests for ProjectFeaturingAllowed class."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
self.init()
student = profile_seeder.seedStudent(self.program)
self.project = project_utils.seedNDBProject(
student, self.program.key(), org_key=self.org.key,
is_featuring_allowed=False)
def testFeaturingAllowedSet(self):
"""Tests that featuring allowed is set to true properly."""
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
profile_seeder.seedProfile(
self.program.key(), user=user, admin_for=[self.org.key])
# make sure that is_featuring_allowed is False at this point
self.assertFalse(self.project.is_featuring_allowed)
url = _getProjectFeaturingAllowedUrl(self.project.key)
response = self.post(url)
self.assertResponseOK(response)
# check that is_featuring_allowed is True
project = self.project.key.get()
self.assertTrue(project.is_featuring_allowed)
# check that another request does not flip the value
response = self.post(url)
self.assertResponseOK(response)
project = self.project.key.get()
self.assertTrue(project.is_featuring_allowed)
class ProjectFeaturingNotAllowedTest(test_utils.GSoCDjangoTestCase):
"""Unit tests for ProjectFeaturingNotAllowed class."""
def setUp(self):
"""See unittest.TestCase.setUp for specification."""
self.init()
student = profile_seeder.seedStudent(self.program)
self.project = project_utils.seedNDBProject(
student, self.program.key(), org_key=self.org.key,
is_featuring_allowed=True)
def testFeaturingNotAllowedSet(self):
"""Tests that featuring allowed is set to false properly."""
user = user_seeder.seedUser()
profile_utils.loginNDB(user)
profile_seeder.seedProfile(
self.program.key(), user=user, admin_for=[self.org.key])
# make sure that is_featuring_allowed is True at this point
self.assertTrue(self.project.is_featuring_allowed)
url = _getProjectFeaturingNotAllowedUrl(self.project.key)
response = self.post(url)
self.assertResponseOK(response)
# check that is_featuring_allowed is False
project = self.project.key.get()
self.assertFalse(project.is_featuring_allowed)
# check that another request does not flip the value
response = self.post(url)
self.assertResponseOK(response)
project = self.project.key.get()
self.assertFalse(project.is_featuring_allowed)