| # 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) |