| # Copyright 2014 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 proposal related views.""" |
| |
| import httplib |
| import json |
| import unittest |
| |
| from django import http |
| |
| from melange.request import exception |
| |
| from melange.models import profile as profile_model |
| |
| from seeder import profile as profile_seeder |
| from seeder import program as program_seeder |
| from seeder import sponsor as sponsor_seeder |
| from seeder import user as user_seeder |
| |
| from soc.modules.gsoc.views.helper import request_data |
| |
| from summerofcode.logic import proposal as proposal_logic |
| from summerofcode.models import proposal as proposal_model |
| from summerofcode.views import proposal_manage as proposal_manage_view |
| |
| from tests import org_utils |
| from tests import profile_utils |
| from tests import test_utils |
| from tests.utils import proposal_utils |
| |
| |
| # Proposal properties which are different from properties set by |
| # proposal_utils |
| _OTHER_PROPOSAL_PROPERTIES = { |
| 'title': u'Other Title', |
| 'abstract': u'Other Abstract', |
| 'additional_info': u'http://www.other.additional.info.com' |
| } |
| |
| # Proposal revision properties which are different from revision properties set by |
| # proposal_utils |
| _OTHER_PROPOSAL_REVISION_PROPERTIES = { |
| 'content': u'Other Content', |
| } |
| |
| |
| def _getListProposalRevisionsUrl(proposal): |
| """Returns URL to 'List Proposal Revisions' page for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'List Proposal Revisions' page. |
| """ |
| return '/gsoc/proposal/revisions/list/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| def _getListProposalRevisionsDiffUrl(proposal, revision1_id, revision2_id): |
| """Returns URL to 'List Proposal Revisions' page for the specified proposal. |
| This url is reached after the user is redirected after a POST request is |
| made. |
| |
| Args: |
| proposal: Proposal entity. |
| revision1_id: revision number of first proposal revision. |
| revision2_id: revision number of second proposal revision. |
| |
| Returns: |
| The URL to 'List Proposal Revisions' page which contains diff of two |
| proposal revisions. |
| """ |
| return '/gsoc/proposal/revisions/list/%s/%s/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id(), revision1_id, |
| revision2_id) |
| |
| def _getAcceptAsProjectUrl(proposal): |
| """Returns URL to 'Accept As Project' handler for the specified proposal. |
| |
| Args: |
| proposal: proposal_model.Proposal entity. |
| |
| Returns: |
| The URL to 'Accept As Project' handler. |
| """ |
| return '/gsoc/proposal/accept_as_project/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getRejectAsProjectUrl(proposal): |
| """Returns URL to 'Reject As Project' handler for the specified proposal. |
| |
| Args: |
| proposal: proposal_model.Proposal entity. |
| |
| Returns: |
| The URL to 'Reject As Project' handler. |
| """ |
| return '/gsoc/proposal/reject_as_project/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalPublicPageUrl(proposal): |
| """Returns URL to 'Proposal Public Page' handler for the specified proposal. |
| |
| Args: |
| proposal: proposal_model.Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Public Page' handler. |
| """ |
| return '/gsoc/proposal/public/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalReviewAsOrgMemberUrl(proposal): |
| """Returns URL to 'Proposal Review As Org Member' page for |
| the specified proposal. |
| |
| Args: |
| proposal: proposal_model.Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Review As Org Member' page. |
| """ |
| return '/gsoc/proposal/review/org/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalPossibleMentorAddUrl(proposal): |
| """Returns URL to 'Proposal Possible Mentor Add' handler for |
| the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Possible Mentor Add' handler. |
| """ |
| return '/gsoc/proposal/possible_mentor/add/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalPossibleMentorRemoveUrl(proposal): |
| """Returns URL to 'Proposal Possible Mentor Remove' handler for |
| the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Possible Mentor Remove' handler. |
| """ |
| return '/gsoc/proposal/possible_mentor/remove/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalIgnoreUrl(proposal): |
| """Returns URL to 'Proposal Ignore' handler for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Ignore' handler. |
| """ |
| return '/gsoc/proposal/ignore/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalUnignoreUrl(proposal): |
| """Returns URL to 'Proposal Unignore' handler for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Unignore' handler. |
| """ |
| return '/gsoc/proposal/unignore/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalWithdrawUrl(proposal): |
| """Returns URL to 'Proposal Withdraw' handler for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Withdraw' handler. |
| """ |
| return '/gsoc/proposal/withdraw/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalResubmitUrl(proposal): |
| """Returns URL to 'Proposal Resubmit' handler for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Resubmit' handler. |
| """ |
| return '/gsoc/proposal/resubmit/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalAssignMentorsUrl(proposal): |
| """Returns URL to 'Proposal Assign Mentors' handler for |
| the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Assign Mentors' handler. |
| """ |
| return '/gsoc/proposal/assign_mentors/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalEditablePostDeadlineUrl(proposal): |
| """Returns URL to 'Proposal Editable Post Deadline' handler for |
| the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Editable Post Deadline' handler. |
| """ |
| return '/gsoc/proposal/editable_post_deadline/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalUneditablePostDeadlineUrl(proposal): |
| """Returns URL to 'Proposal Uneditable Post Deadline' handler for |
| the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Uneditable Post Deadline' handler. |
| """ |
| return '/gsoc/proposal/uneditable_post_deadline/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| def _getProposalAdminAcceptUrl(proposal): |
| """Returns URL to 'Proposal Admin Accept' handler for the specified proposal. |
| |
| Args: |
| proposal: Proposal entity. |
| |
| Returns: |
| The URL to 'Proposal Admin Accept' handler. |
| """ |
| return '/gsoc/proposal/admin/accept/%s/%s' % ( |
| proposal.key.parent().id(), proposal.key.id()) |
| |
| |
| class IsMentorForUrlProposalOrganizationAccessCheckerTest(unittest.TestCase): |
| """Unit tests for IsMentorForUrlProposalOrganizationAccessChecker class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| sponsor = sponsor_seeder.seedSponsor() |
| self.program = program_seeder.seedGSoCProgram(sponsor_key=sponsor.key()) |
| self.org = org_utils.seedOrganization(self.program.key()) |
| |
| student = profile_seeder.seedStudent(self.program) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| kwargs = { |
| 'sponsor': sponsor.key().name(), |
| 'program': self.program.program_id, |
| 'user': student.profile_id, |
| 'id': proposal.key.id(), |
| } |
| self.data = request_data.RequestData(None, None, kwargs) |
| |
| def testMentorForProposalOrganizationAccessGranted(self): |
| """Tests that access is granted for mentor for the organization.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| access_checker = ( |
| proposal_manage_view.IsMentorForUrlProposalOrganizationAccessChecker()) |
| access_checker.checkAccess(self.data, None) |
| |
| def testNonMentorForProposalOrganizationAccessDenied(self): |
| """Tests that access is denied for non-mentor for the organization.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile(self.program.key(), user=user) |
| |
| access_checker = ( |
| proposal_manage_view.IsMentorForUrlProposalOrganizationAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| |
| class IsAdminForUrlProposalOrganizationAccessCheckerTest(unittest.TestCase): |
| """Unit tests for IsAdminForUrlProposalOrganizationAccessChecker class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| sponsor = sponsor_seeder.seedSponsor() |
| self.program = program_seeder.seedGSoCProgram(sponsor_key=sponsor.key()) |
| self.org = org_utils.seedOrganization(self.program.key()) |
| |
| student = profile_seeder.seedStudent(self.program) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| kwargs = { |
| 'sponsor': sponsor.key().name(), |
| 'program': self.program.program_id, |
| 'user': student.profile_id, |
| 'id': proposal.key.id(), |
| } |
| self.data = request_data.RequestData(None, None, kwargs) |
| |
| def testAdminForProposalOrganizationAccessGranted(self): |
| """Tests that access is granted for admin for the organization.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, admin_for=[self.org.key]) |
| |
| access_checker = ( |
| proposal_manage_view.IsAdminForUrlProposalOrganizationAccessChecker()) |
| access_checker.checkAccess(self.data, None) |
| |
| def testMentorForProposalOrganizationAccessDenied(self): |
| """Tests that access is denied for mentor for the organization.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| access_checker = ( |
| proposal_manage_view.IsAdminForUrlProposalOrganizationAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| def testLoneProfileAccessDenied(self): |
| """Tests that access is denied for non-admin for the organization.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile(self.program.key(), user=user) |
| |
| access_checker = ( |
| proposal_manage_view.IsAdminForUrlProposalOrganizationAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| |
| class ProposalAcceptAsProjectHandlerTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalAcceptAsProjectHandler class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| self.timeline_helper.studentSignup() |
| |
| def testAcceptAsProjectSet(self): |
| """Tests that accept_as_project property is correctly set to True.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, admin_for=[self.org.key]) |
| |
| student = profile_seeder.seedStudent(self.program) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key, |
| accept_as_project=False) |
| |
| response = self.post(_getAcceptAsProjectUrl(proposal)) |
| self.assertResponseOK(response) |
| |
| # check that proposal is updated |
| proposal = proposal.key.get() |
| self.assertTrue(proposal.accept_as_project) |
| |
| |
| class ProposalRejectAsProjectHandlerTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalRejectAsProjectHandler class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| self.timeline_helper.studentSignup() |
| |
| def testAcceptAsProjectUnset(self): |
| """Tests that accept_as_project property is correctly set to False.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, admin_for=[self.org.key]) |
| |
| student = profile_seeder.seedStudent(self.program) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key, |
| accept_as_project=True) |
| |
| response = self.post(_getRejectAsProjectUrl(proposal)) |
| self.assertResponseOK(response) |
| |
| # check that proposal is updated |
| proposal = proposal.key.get() |
| self.assertFalse(proposal.accept_as_project) |
| |
| |
| class IsUrlProposalPubliclyVisibleAccessCheckerTest(unittest.TestCase): |
| """Unit tests for IsUrlProposalPubliclyVisibleAccessChecker class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| sponsor = sponsor_seeder.seedSponsor() |
| self.program = program_seeder.seedGSoCProgram(sponsor_key=sponsor.key()) |
| self.org = org_utils.seedOrganization(self.program.key()) |
| |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| kwargs = { |
| 'sponsor': sponsor.key().name(), |
| 'program': self.program.program_id, |
| 'user': student.profile_id, |
| 'id': self.proposal.key.id(), |
| } |
| self.data = request_data.RequestData(None, None, kwargs) |
| |
| def testAccessGrantedForPublicVisibility(self): |
| """Tests that access is granted for a publicly visible proposal.""" |
| self.proposal.visibility = proposal_model.Visibility.PUBLIC |
| self.proposal.put() |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalPubliclyVisibleAccessChecker()) |
| access_checker.checkAccess(self.data, None) |
| |
| def testAccessDeniedForNonPublicVisibility(self): |
| """Tests that access is denied for a non publicly visible proposal.""" |
| self.proposal.visibility = proposal_model.Visibility.ORG_MEMBER |
| self.proposal.put() |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalPubliclyVisibleAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| |
| class IsUrlProposalVisibleForStudentAccessChecker(unittest.TestCase): |
| """Unit tests for IsUrlProposalVisibleForStudentAccessChecker class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| sponsor = sponsor_seeder.seedSponsor() |
| self.program = program_seeder.seedGSoCProgram(sponsor_key=sponsor.key()) |
| self.org = org_utils.seedOrganization(self.program.key()) |
| |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| kwargs = { |
| 'sponsor': sponsor.key().name(), |
| 'program': self.program.program_id, |
| 'user': student.profile_id, |
| 'id': self.proposal.key.id(), |
| } |
| self.data = request_data.RequestData(None, None, kwargs) |
| |
| def testAccessGrantedForProgramStudentVisibility(self): |
| """Tests that access is granted for proposals visible to students.""" |
| self.proposal.visibility = proposal_model.Visibility.STUDENT |
| self.proposal.put() |
| |
| # Log in as student |
| user = user_seeder.seedUser() |
| profile = profile_seeder.seedStudent(self.program, user=user) |
| profile_utils.loginNDB(user) |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalVisibleForStudentAccessChecker()) |
| access_checker.checkAccess(self.data, None) |
| |
| def testAccessDeniedForNonStudent(self): |
| """Tests that access is denied for non-student.""" |
| self.proposal.visibility = proposal_model.Visibility.STUDENT |
| self.proposal.put() |
| |
| # Log in as non-student |
| user = user_seeder.seedUser() |
| profile = profile_seeder.seedProfile(self.program.key(), user=user) |
| profile_utils.loginNDB(user) |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalVisibleForStudentAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| def testAccessDeniedForInactiveStudent(self): |
| """Tests that access is denied for non-student.""" |
| self.proposal.visibility = proposal_model.Visibility.STUDENT |
| self.proposal.put() |
| |
| # Log in as banned student |
| user = user_seeder.seedUser() |
| profile = profile_seeder.seedStudent(self.program, user=user) |
| profile.status = profile_model.Status.BANNED |
| profile.put() |
| profile_utils.loginNDB(user) |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalVisibleForStudentAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| def testAccessDeniedForNonProgramStudentVisibility(self): |
| """Tests that access is denied for proposals not visible to students.""" |
| self.proposal.visibility = proposal_model.Visibility.PUBLIC |
| self.proposal.put() |
| |
| # Log in as student |
| user = user_seeder.seedUser() |
| profile = profile_seeder.seedStudent(self.program, user=user) |
| profile_utils.loginNDB(user) |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalVisibleForStudentAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| self.proposal.visibility = proposal_model.Visibility.ORG_MEMBER |
| self.proposal.put() |
| |
| access_checker = ( |
| proposal_manage_view.IsUrlProposalVisibleForStudentAccessChecker()) |
| with self.assertRaises(exception.UserError) as context: |
| access_checker.checkAccess(self.data, None) |
| self.assertEqual(context.exception.status, httplib.FORBIDDEN) |
| |
| |
| class ProposalPublicPageTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalPublicPage class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key, |
| visibility=proposal_model.Visibility.PUBLIC) |
| |
| def testPageLoads(self): |
| """Tests that the page loads properly.""" |
| response = self.get(_getProposalPublicPageUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| |
| class ProposalPossibleMentorAddTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalPossibleMentorAdd class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testPossibleMentorAdded(self): |
| """Tests that a new possible mentor is added properly.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile = profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| response = self.post(_getProposalPossibleMentorAddUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the possible mentor is added |
| proposal = self.proposal.key.get() |
| self.assertIn(profile.key, proposal.possible_mentors) |
| |
| |
| class ProposalPossibleMentorRemoveTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalPossibleMentorRemove class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testPossibleMentorRemoved(self): |
| """Tests that a new possible mentor is added properly.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile = profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| self.proposal.possible_mentors = [profile.key] |
| self.proposal.put() |
| |
| response = self.post(_getProposalPossibleMentorRemoveUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the possible mentor is removed |
| proposal = self.proposal.key.get() |
| self.assertNotIn(profile.key, proposal.possible_mentors) |
| |
| |
| class ProposalIgnoreTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalIgnore class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testProposalIgnored(self): |
| """Tests that the proposal is marked as ignored.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, admin_for=[self.org.key]) |
| |
| response = self.post(_getProposalIgnoreUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is ignored |
| proposal = self.proposal.key.get() |
| self.assertTrue(proposal.is_ignored) |
| |
| |
| class ProposalUnignoreTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalUnignore class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testProposalUnignored(self): |
| """Tests that the proposal is no marked as ignored.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, admin_for=[self.org.key]) |
| |
| self.proposal.is_ignored = True |
| self.proposal.put() |
| |
| response = self.post(_getProposalUnignoreUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is not ignored |
| proposal = self.proposal.key.get() |
| self.assertFalse(proposal.is_ignored) |
| |
| |
| class ProposalWithdrawTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalWithdraw class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| |
| def testProposalWithdrawn(self): |
| """Tests that the proposal is withdrawn.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| student = profile_seeder.seedStudent(self.program, user=user) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| response = self.post(_getProposalWithdrawUrl(proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is withdrawn |
| proposal = proposal.key.get() |
| self.assertEqual(proposal.status, proposal_model.Status.WITHDRAWN) |
| |
| |
| class ProposalResubmitTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalResubmit class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| |
| def testProposalResubmitted(self): |
| """Tests that the proposal is submitted again.""" |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| student = profile_seeder.seedStudent(self.program, user=user) |
| proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key, |
| status=proposal_model.Status.WITHDRAWN) |
| |
| response = self.post(_getProposalResubmitUrl(proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is withdrawn |
| proposal = proposal.key.get() |
| self.assertEqual(proposal.status, proposal_model.Status.PENDING) |
| |
| |
| _TEST_NUMBER_OF_MENTORS = 3 |
| |
| class ProposalAssignMentorsTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalAssignMentors class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| 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( |
| _getProposalAssignMentorsUrl(self.proposal), postdata=postdata) |
| self.assertResponseRedirect(response) |
| |
| |
| class ProposalEditablePostDeadlineTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalEditablePostDeadline class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testProposalEditable(self): |
| """Tests that the proposal is marked as editable post deadline.""" |
| self.proposal.is_editable_post_deadline = False |
| self.proposal.put() |
| |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| response = self.post(_getProposalEditablePostDeadlineUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is editable |
| proposal = self.proposal.key.get() |
| self.assertTrue(proposal.is_editable_post_deadline) |
| |
| |
| class ProposalUneditablePostDeadlineTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalUneditablePostDeadline class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testProposalUneditable(self): |
| """Tests that the proposal is marked as uneditable post deadline.""" |
| self.proposal.is_editable_post_deadline = True |
| self.proposal.put() |
| |
| user = user_seeder.seedUser() |
| profile_utils.loginNDB(user) |
| profile_seeder.seedProfile( |
| self.program.key(), user=user, mentor_for=[self.org.key]) |
| |
| response = self.post(_getProposalUneditablePostDeadlineUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| # check that the proposal is editable |
| proposal = self.proposal.key.get() |
| self.assertFalse(proposal.is_editable_post_deadline) |
| |
| |
| class ProposalAdminAcceptTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ProposalAdminAccept class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testProposalAccepted(self): |
| """Tests the the proposal is accepted properly.""" |
| user = user_seeder.seedUser(host_for=[self.program]) |
| profile_utils.loginNDB(user) |
| |
| response = self.post(_getProposalAdminAcceptUrl(self.proposal)) |
| self.assertResponseRedirect( |
| response, |
| _getProposalReviewAsOrgMemberUrl(self.proposal) + '?verified=True') |
| |
| # check that the proposal now accepted |
| proposal = self.proposal.key.get() |
| self.assertEqual(proposal.status, proposal_model.Status.ACCEPTED) |
| |
| |
| class ListProposalRevisionsTest(test_utils.GSoCDjangoTestCase): |
| """Unit tests for ListProposalRevisions class.""" |
| |
| def setUp(self): |
| """See unittest.TestCase.setUp for specification.""" |
| self.init() |
| student = profile_seeder.seedStudent(self.program) |
| self.proposal = proposal_utils.seedNDBProposal( |
| student.key, self.program.key(), org_key=self.org.key) |
| |
| def testPageLoads(self): |
| """Tests that the page loads properly.""" |
| response = self.get(_getListProposalRevisionsUrl(self.proposal)) |
| self.assertResponseOK(response) |
| |
| def testListData(self): |
| """Tests that correct list data is loaded.""" |
| list_data = self.getListData( |
| _getListProposalRevisionsUrl(self.proposal), 0) |
| self.assertEqual(len(list_data), 1) |
| |
| # Proposal is updated and resubmitted |
| result = proposal_logic.updateProposal( |
| self.proposal.key, _OTHER_PROPOSAL_PROPERTIES, |
| proposal_revision_properties=_OTHER_PROPOSAL_REVISION_PROPERTIES) |
| self.assertTrue(result) |
| |
| list_data = self.getListData( |
| _getListProposalRevisionsUrl(self.proposal), 0) |
| self.assertEqual(len(list_data), 2) |
| |
| def testListPostButton(self): |
| """Tests that the list POST button is working correctly.""" |
| # Create second revision. |
| result = proposal_logic.updateProposal( |
| self.proposal.key, _OTHER_PROPOSAL_PROPERTIES, |
| proposal_revision_properties=_OTHER_PROPOSAL_REVISION_PROPERTIES) |
| self.assertTrue(result) |
| |
| list_data = self.getListData( |
| _getListProposalRevisionsUrl(self.proposal), 0) |
| revision1_key = list_data[0]['columns']['full_proposal_revision_key'] |
| revision2_key = list_data[1]['columns']['full_proposal_revision_key'] |
| |
| data = [ |
| {'full_proposal_revision_key': revision1_key}, |
| {'full_proposal_revision_key': revision2_key}] |
| data = json.dumps(data) |
| |
| postdata = { |
| 'data': data, |
| 'button_id': 'show_diff', |
| 'idx': 0, |
| } |
| response = self.post( |
| _getListProposalRevisionsUrl(self.proposal), postdata=postdata) |
| self.assertResponseOK(response) |
| |
| response = self.get(_getListProposalRevisionsDiffUrl(self.proposal, 0, 1)) |
| self.assertResponseOK(response) |