def acceptProposals(self): """Set student proposals' acceptance state and make sure the organization has slots available. """ self.student1 = self.createStudent('*****@*****.**', n_proposals=2) self.student1_proposals = GSoCProposal.all().ancestor( self.student1.profile) self.student2 = self.createStudent('*****@*****.**', n_proposals=3) self.student2_proposals = GSoCProposal.all().ancestor( self.student2.profile) self.assertEqual(self.student1_proposals.count(), 2) self.assertEqual(self.student2_proposals.count(), 3) #accept 1 of 2 proposal of student1 proposal1 = self.student1_proposals[0] proposal1.accept_as_project = True proposal1.put() proposal2 = self.student1_proposals[1] proposal2.accept_as_project = False proposal2.put() #reject all proposals of student2 for proposal in self.student2_proposals: proposal.accept_as_project = False proposal.put() self.org.slots = 5 self.org.put() self.timeline.studentsAnnounced()
def testAcceptProposalButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() proposal = self.createProposal({ 'scope': student.profile, 'parent': student.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) self.data.createMentor(self.org) url = '/gsoc/proposal/accept/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) # fail if mentor tries to accept the proposal self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() self.assertFalse(proposal.accept_as_project) # accept the proposal as project when the org admin tries to accept # the proposal self.data.createOrgAdmin(self.org) response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertTrue(proposal.accept_as_project)
def testAcceptProposalButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() proposal = self.createProposal({'scope': student.profile, 'parent': student.profile}) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) self.data.createMentor(self.org) url = '/gsoc/proposal/accept/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) # fail if mentor tries to accept the proposal self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() self.assertFalse(proposal.accept_as_project) # accept the proposal as project when the org admin tries to accept # the proposal self.data.createOrgAdmin(self.org) response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertTrue(proposal.accept_as_project)
def _processEntity(self, entity): key_name = entity.key().name() parent = entity.scope properties = { 'abstract': entity.abstract, 'additional_info': entity.additional_info, 'content': entity.content, 'created_on': entity.created_on, 'is_publicly_visible': entity.is_publicly_visible, 'last_modified_on': entity.last_modified_on, 'mentor': entity.mentor, 'org': entity.org, 'possible_mentors': entity.possible_mentors, 'program': entity.program, 'status': entity.status, 'title': entity.title, } # check if the proposal has already been processed # this is a heristic, but we can assume that one student can't submit two # proposals at the very same time query = db.Query(GSoCProposal) query.ancestor(entity.scope) query.filter('created_on = ', entity.created_on) if query.get(): return # create a new GSoCProposal entity proposal = GSoCProposal(parent=parent, **properties) proposal.put() to_put = [] # convert all the comments for the old proposal query = db.Query(Review) query.filter('scope = ', entity) for comment in query: # get profile instance q = db.Query(GSoCProfile) q.ancestor(comment.author) q.filter('scope =', entity.program) author = q.get() if not author: # if, for some reason, there is no profile, we skip this comment import logging logging.warning('No profile for user %s.' % (comment.author.link_id)) continue properties = { 'author': author, 'content': comment.content, 'is_private': not comment.is_public, 'created': comment.created } new_comment = GSoCComment(parent=proposal, **properties) to_put.append(new_comment) db.run_in_transaction(db.put, to_put)
def getProposalsToBeAcceptedForOrg(org_entity, step_size=25): """Returns all StudentProposals which will be accepted into the program for the given organization. params: org_entity: the Organization for which the proposals should be checked step_size: optional parameter to specify the amount of Student Proposals that should be retrieved per roundtrip to the datastore returns: List with all StudentProposal which will be accepted into the program """ # check if there are already slots taken by this org q = GSoCProposal.all() q.filter('org', org_entity) q.filter('status', 'accepted') slots_left_to_assign = max(0, org_entity.slots - q.count()) if slots_left_to_assign == 0: # no slots left so return nothing return [] q = GSoCProposal.all() q.filter('org', org_entity) q.filter('status', 'pending') q.filter('accept_as_project', True) q.filter('has_mentor', True) q.order('-score') # We are not putting this into the filter because order and != do not mix # in GAE. proposals = q.fetch(slots_left_to_assign) offset = slots_left_to_assign # retrieve as many additional proposals as needed in case the top # N do not have a mentor assigned while len(proposals) < slots_left_to_assign: new_proposals = q.fetch(step_size, offset=offset) if not new_proposals: # we ran out of proposals` break proposals += new_proposals offset += step_size # cut off any superfluous proposals return proposals[:slots_left_to_assign]
def create_proposal_trx(): profile = data.ndb_profile.key.get() profile.student_data.number_of_proposals += 1 profile.put() proposal = GSoCProposal(parent=data.ndb_profile.key.to_old_key(), **proposal_properties) proposal.put() context = notifications.newProposalContext(data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def create_proposal_trx(): profile = data.ndb_profile.key.get() profile.student_data.number_of_proposals += 1 profile.put() proposal = GSoCProposal( parent=data.ndb_profile.key.to_old_key(), **proposal_properties) proposal.put() context = notifications.newProposalContext(data, proposal, to_emails) sub_txn = mailer.getSpawnMailTaskTxn(context, parent=proposal) sub_txn() return proposal
def testAssignMentor(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key, mentor=None) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.profile_id, proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) mentor = profile_utils.seedNDBProfile(self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/assign_mentor/' + suffix postdata = {'assign_mentor': mentor.key} response = self.post(url, postdata) self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() mentor_key = GSoCProposal.mentor.get_value_for_datastore(proposal) self.assertIsNone(mentor_key)
def getListData(self): idx = lists.getListIndex(self.request) if idx != 0: return None org = self.data.organization program = self.data.program # Hold all the accepted projects for orgs where this user is a member of accepted = [] # Hold all duplicates for either the entire program or the orgs of the user. duplicates = [] dupQ = GSoCProposalDuplicate.all() dupQ.filter('is_duplicate', True) dupQ.filter('org', org) dupQ.filter('program', program) accepted.extend([p.key() for p in getProposalsToBeAcceptedForOrg(org)]) duplicate_entities = dupQ.fetch(1000) for dup in duplicate_entities: duplicates.extend(dup.duplicates) q = GSoCProposal.all() q.filter('org', org) q.filter('program', program) starter = lists.keyStarter prefetcher = lists.modelPrefetcher(GSoCProposal, ['org'], parent=True) response_builder = lists.RawQueryContentResponseBuilder( self.request, self._list_config, q, starter, prefetcher=prefetcher) return response_builder.build(accepted, duplicates)
def testSubmitProposal(self): mentor = GSoCProfileHelper(self.gsoc, self.dev_test) mentor.createOtherUser('*****@*****.**') mentor.createMentor(self.org) mentor.notificationSettings( new_proposals=True, public_comments=True, private_comments=True) other_mentor = GSoCProfileHelper(self.gsoc, self.dev_test) other_mentor.createOtherUser('*****@*****.**') other_mentor.createMentor(self.org) other_mentor.notificationSettings() self.data.createStudent() self.data.notificationSettings() self.timeline.studentSignup() url = '/gsoc/proposal/submit/' + self.org.key().name() response = self.get(url) self.assertProposalTemplatesUsed(response) # test proposal POST override = { 'program': self.gsoc, 'score': 0, 'nr_scores': 0, 'mentor': None, 'org': self.org, 'status': 'pending', 'accept_as_project': False, 'is_editable_post_deadline': False, 'extra': None, 'has_mentor': False, } response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) self.assertEmailSent(to=mentor.profile.email, n=1) self.assertEmailNotSent(to=other_mentor.profile.email) proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal)
def testResubmitProposal(self): """Tests that a proposal is successfully resubmitted if possible.""" old_number_of_proposals = self.profile.student_data.number_of_proposals self.kwargs = { 'sponsor': self.sponsor.link_id, 'program': self.program.program_id, 'user': self.profile.profile_id, 'id': self.proposal.key().id() } request = http.HttpRequest() data = request_data.RequestData(request, None, self.kwargs) handler = proposal_review_view.ResubmitProposalHandler(None) with mock.patch.object( proposal_logic, 'canProposalBeResubmitted', return_value=True): response = handler.handle(data, None, None) self.assertEqual(response.status_code, httplib.OK) # check that the proposal is withdrawn proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, proposal_model.STATUS_PENDING) # check that number of proposals is updated profile = self.profile.key.get() self.assertEqual( old_number_of_proposals, profile.student_data.number_of_proposals - 1)
def rejectProposals(self, request, *args, **kwargs): """Reject proposals for an single organization. """ params = request.POST # Setup an artifical request deadline timekeeper = Timekeeper(20000) # Query proposals org = soc_org_model.SOCOrganization.get_by_id(params['org_key']) q = GSoCProposal.all() q.filter('org', org.key.to_old_key()) q.filter('status', 'pending') # Reject proposals try: for remain, proposal in timekeeper.iterate(q): logging.info("reject %s %s %s", remain, org.key.id(), proposal.key()) self.rejectProposal(proposal) # Requeue this task for continuation except DeadlineExceededError: taskqueue.add(url=request.path, params=params) # Exit this task successfully return responses.terminateTask()
def getListData(self): idx = lists.getListIndex(self.data.request) if idx != 0: return None program = self.data.program # Hold all the accepted projects for orgs where this user is a member of accepted = [] # Hold all duplicates for either the entire program or the orgs of the user. duplicates = [] dupQ = GSoCProposalDuplicate.all() dupQ.filter('is_duplicate', True) dupQ.filter('org', self.data.url_ndb_org.key.to_old_key()) dupQ.filter('program', program) accepted.extend( p.key() for p in getProposalsToBeAcceptedForOrg(self.data.url_ndb_org)) duplicate_entities = dupQ.fetch(1000) for dup in duplicate_entities: duplicates.extend(dup.duplicates) q = GSoCProposal.all() q.filter('org', self.data.url_ndb_org.key.to_old_key()) q.filter('program', program) starter = lists.keyStarter # TODO(daniel): enable prefetching from ndb models ('org', 'parent') # prefetcher = lists.ModelPrefetcher(GSoCProposal, [], parent=True) response_builder = lists.RawQueryContentResponseBuilder( self.data.request, self._list_config, q, starter, prefetcher=None) return response_builder.build(accepted, duplicates)
def testResubmitProposal(self): """Tests that a proposal is successfully resubmitted if possible.""" old_number_of_proposals = self.profile.student_data.number_of_proposals self.kwargs = { 'sponsor': self.sponsor.link_id, 'program': self.program.program_id, 'user': self.profile.profile_id, 'id': self.proposal.key().id() } request = http.HttpRequest() data = request_data.RequestData(request, None, self.kwargs) handler = proposal_review_view.ResubmitProposalHandler(None) with mock.patch.object(proposal_logic, 'canProposalBeResubmitted', return_value=True): response = handler.handle(data, None, None) self.assertEqual(response.status_code, httplib.OK) # check that the proposal is withdrawn proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, proposal_model.STATUS_PENDING) # check that number of proposals is updated profile = self.profile.key.get() self.assertEqual(old_number_of_proposals, profile.student_data.number_of_proposals - 1)
def proposalFromKwargs(self): self.profileFromKwargs() assert access_checker.isSet(self.data.url_profile) # can safely call int, since regexp guarnatees a number proposal_id = int(self.data.kwargs['id']) if not proposal_id: raise NotFound('Proposal id must be a positive number') self.data.proposal = GSoCProposal.get_by_id( proposal_id, parent=self.data.url_profile) if not self.data.proposal: raise NotFound('Requested proposal does not exist') org_key = GSoCProposal.org.get_value_for_datastore(self.data.proposal) self.data.proposal_org = self.data.getOrganization(org_key) parent_key = self.data.proposal.parent_key() if self.data.profile and parent_key == self.data.profile.key(): self.data.proposer = self.data.profile else: self.data.proposer = self.data.proposal.parent()
def testAssignMentor(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal( student.key, self.program.key(), org_key=self.org.key, mentor=None) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), student.profile_id, proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) mentor = profile_utils.seedNDBProfile( self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/assign_mentor/' + suffix postdata = {'assign_mentor': mentor.key} response = self.post(url, postdata) self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() mentor_key = GSoCProposal.mentor.get_value_for_datastore(proposal) self.assertIsNone(mentor_key)
def testUpdateProposal(self): """Test update proposals. """ mentor = GSoCProfileHelper(self.gsoc, self.dev_test) mentor.createOtherUser('*****@*****.**') mentor.createMentor(self.org) mentor.notificationSettings(proposal_updates=True) self.data.createStudentWithProposal(self.org, mentor.profile) self.data.notificationSettings() self.timeline.studentSignup() proposal = GSoCProposal.all().get() url = '/gsoc/proposal/update/%s/%s' % (self.gsoc.key().name(), proposal.key().id()) response = self.get(url) self.assertProposalTemplatesUsed(response) override = { 'program': self.gsoc, 'score': 0, 'nr_scores': 0, 'has_mentor': True, 'mentor': mentor.profile, 'org': self.org, 'status': 'pending', 'action': 'Update', 'is_publicly_visible': False, 'extra': None, 'accept_as_project': False, 'is_editable_post_deadline': False } response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) properties.pop('action') proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal) # after update last_modified_on should be updated which is not equal # to created_on self.assertNotEqual(proposal.created_on, proposal.last_modified_on) self.assertEmailSent(to=mentor.profile.email, n=1)
def checkAccess(self): self.check.isLoggedIn() self.check.isActiveStudent() self.data.proposal = GSoCProposal.get_by_id( int(self.data.kwargs['id']), parent=self.data.profile) self.check.canStudentUpdateProposal()
def checkAccess(self): self.check.isLoggedIn() self.check.isActiveStudent() self.data.proposal = GSoCProposal.get_by_id(int( self.data.kwargs['id']), parent=self.data.profile) self.check.canStudentUpdateProposal()
def testWishToMentorButton(self): user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) mentor = profile_utils.seedNDBProfile(self.program.key(), user=user, mentor_for=[self.org.key]) student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key) other_mentor = profile_utils.seedNDBProfile(self.program.key(), mentor_for=[self.org.key]) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.key.parent().id(), proposal.key().id()) url = '/gsoc/proposal/wish_to_mentor/' + suffix postdata = {'value': 'unchecked'} self.post(url, postdata) proposal = GSoCProposal.get(proposal.key()) self.assertIn(mentor.key.to_old_key(), proposal.possible_mentors) postdata = {'value': 'checked'} self.post(url, postdata) proposal = GSoCProposal.get(proposal.key()) self.assertNotIn(mentor.key.to_old_key(), proposal.possible_mentors) # TODO(daniel): this section (mentor retires) should go to another test other_mentor.mentor_for = [] other_mentor.put() proposal.possible_mentors.append(other_mentor.key.to_old_key()) proposal.put() url = '/gsoc/proposal/review/' + suffix self.get(url) proposal = GSoCProposal.get(proposal.key()) self.assertNotIn(other_mentor.key.to_old_key(), proposal.possible_mentors)
def testWishToMentorButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() self.data.createMentor(self.org) other_mentor = self.createMentorWithSettings( '*****@*****.**') proposal = self.createProposal({ 'scope': student.profile, 'parent': student.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/wish_to_mentor/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) proposal = GSoCProposal.all().get() self.assertTrue(self.data.profile.key() in proposal.possible_mentors) postdata = {'value': 'checked'} response = self.post(url, postdata) proposal = GSoCProposal.all().get() self.assertFalse(self.data.profile.key() in proposal.possible_mentors) other_mentor.profile.mentor_for = [] other_mentor.profile.put() proposal.possible_mentors.append(other_mentor.profile.key()) proposal.put() url = '/gsoc/proposal/review/' + suffix response = self.get(url) proposal = GSoCProposal.all().get() self.assertFalse( other_mentor.profile.key() in proposal.possible_mentors)
def testWishToMentorButton(self): user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) mentor = profile_utils.seedNDBProfile( self.program.key(), user=user, mentor_for=[self.org.key]) student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal( student.key, self.program.key(), org_key=self.org.key) other_mentor = profile_utils.seedNDBProfile( self.program.key(), mentor_for=[self.org.key]) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), student.key.parent().id(), proposal.key().id()) url = '/gsoc/proposal/wish_to_mentor/' + suffix postdata = {'value': 'unchecked'} self.post(url, postdata) proposal = GSoCProposal.get(proposal.key()) self.assertIn(mentor.key.to_old_key(), proposal.possible_mentors) postdata = {'value': 'checked'} self.post(url, postdata) proposal = GSoCProposal.get(proposal.key()) self.assertNotIn(mentor.key.to_old_key(), proposal.possible_mentors) # TODO(daniel): this section (mentor retires) should go to another test other_mentor.mentor_for = [] other_mentor.put() proposal.possible_mentors.append(other_mentor.key.to_old_key()) proposal.put() url = '/gsoc/proposal/review/' + suffix self.get(url) proposal = GSoCProposal.get(proposal.key()) self.assertNotIn(other_mentor.key.to_old_key(), proposal.possible_mentors)
def postHandler(self, data, withdraw=True): program = self.data.program for properties in data: if "full_project_key" not in properties: logging.warning("Missing key in '%s'" % properties) continue project_key = properties["full_project_key"] project = db.get(db.Key(project_key)) if not project: logging.warning("Project '%s' doesn't exist" % project_key) continue if withdraw and project.status == "withdrawn": logging.warning("Project '%s' already withdrawn" % project_key) continue if not withdraw and project.status == "accepted": logging.warning("Project '%s' already accepted" % project_key) continue profile = project.parent() profile_key = profile.key() qp = GSoCProposal.all() qp.ancestor(profile_key) qp.filter("org", project.org) # FIXME: ??? Mentors can change overtime so how does this work??? qp.filter("mentor IN", project.mentors) if withdraw: qp.filter("status", "accepted") else: qp.filter("status", "withdrawn") proposal = qp.get() def withdraw_or_accept_project_txn(): if withdraw: new_status = "withdrawn" new_number = 0 else: new_status = "accepted" new_number = 1 project.status = new_status proposal.status = new_status profile.number_of_projects = new_number db.put([proposal, project, profile]) db.run_in_transaction(withdraw_or_accept_project_txn) return True
def testWishToMentorButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() self.data.createMentor(self.org) other_mentor = self.createMentorWithSettings('*****@*****.**') proposal = self.createProposal({'scope': student.profile, 'parent': student.profile}) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/wish_to_mentor/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) proposal = GSoCProposal.all().get() self.assertTrue(self.data.profile.key() in proposal.possible_mentors) postdata = {'value': 'checked'} response = self.post(url, postdata) proposal = GSoCProposal.all().get() self.assertFalse(self.data.profile.key() in proposal.possible_mentors) other_mentor.profile.mentor_for = [] other_mentor.profile.put() proposal.possible_mentors.append(other_mentor.profile.key()) proposal.put() url = '/gsoc/proposal/review/' + suffix response = self.get(url) proposal = GSoCProposal.all().get() self.assertFalse(other_mentor.profile.key() in proposal.possible_mentors)
def createStudent(self): """Creates two new students the first one has a duplicate the second one has none. """ profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.student1 = profile_helper.createStudentWithProposals( self.org, self.mentor, 3) proposals = GSoCProposal.all().ancestor(self.student1).fetch(2) for p in proposals: p.accept_as_project = True p.put() profile_helper = GSoCProfileHelper(self.gsoc, self.dev_test) profile_helper.createOtherUser('*****@*****.**') self.student2 = profile_helper.createStudentWithProposals( self.org, self.mentor, 1) proposal = GSoCProposal.all().ancestor(self.student2).get() proposal.accept_as_project = True proposal.put()
def canStudentPropose(self): """Checks if the student is eligible to submit a proposal. """ # check if the timeline allows submitting proposals self.studentSignupActive() # check how many proposals the student has already submitted query = GSoCProposal.all() query.filter('scope = ', self.data.profile).ancestor(self.data.user) if query.count() >= self.data.program.apps_tasks_limit: # too many proposals access denied raise AccessViolation(DEF_MAX_PROPOSALS_REACHED)
def getProposalFromKwargs(kwargs): fields = ['sponsor', 'program', 'student'] key_name = '/'.join(kwargs[i] for i in fields) parent = db.Key.from_path('User', kwargs['student'], 'GSoCProfile', key_name) if not kwargs['id'].isdigit(): raise BadRequest("Proposal id is not numeric") id = int(kwargs['id']) return GSoCProposal.get_by_id(id, parent=parent)
def testAcceptProposalButton(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.key.parent().id(), proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile(self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/accept/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) # fail if mentor tries to accept the proposal self.assertResponseForbidden(response) proposal = GSoCProposal.get(proposal.key()) self.assertFalse(proposal.accept_as_project) # accept the proposal as project when the org admin tries to accept # the proposal user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile(self.program.key(), user=user, admin_for=[self.org.key]) response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertTrue(proposal.accept_as_project)
def testUpdateProposal(self): """Test update proposals. """ mentor = GSoCProfileHelper(self.gsoc, self.dev_test) mentor.createOtherUser('*****@*****.**') mentor.createMentor(self.org) mentor.notificationSettings(proposal_updates=True) self.data.createStudentWithProposal(self.org, mentor.profile) self.data.notificationSettings() self.timeline.studentSignup() proposal = GSoCProposal.all().get() url = '/gsoc/proposal/update/%s/%s' % ( self.gsoc.key().name(), proposal.key().id()) response = self.get(url) self.assertProposalTemplatesUsed(response) override = { 'program': self.gsoc, 'score': 0, 'nr_scores': 0, 'has_mentor': True, 'mentor': mentor.profile, 'org': self.org, 'status': 'pending', 'action': 'Update', 'is_publicly_visible': False, 'extra': None, 'accept_as_project': False, 'is_editable_post_deadline': False } response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) properties.pop('action') proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal) # after update last_modified_on should be updated which is not equal # to created_on self.assertNotEqual(proposal.created_on, proposal.last_modified_on) self.assertEmailSent(to=mentor.profile.email, n=1)
def testWithdrawProposalButton(self): self.data.createStudent() proposal = self.createProposal({ 'scope': self.data.profile, 'parent': self.data.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'withdrawn') url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseBadRequest(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'withdrawn') url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'checked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'pending')
def testAcceptProposalButton(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal( student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), student.key.parent().id(), proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile( self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/accept/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) # fail if mentor tries to accept the proposal self.assertResponseForbidden(response) proposal = GSoCProposal.get(proposal.key()) self.assertFalse(proposal.accept_as_project) # accept the proposal as project when the org admin tries to accept # the proposal user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile( self.program.key(), user=user, admin_for=[self.org.key]) response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertTrue(proposal.accept_as_project)
def testWithdrawProposalButton(self): self.data.createStudent() proposal = self.createProposal({'scope': self.data.profile, 'parent': self.data.profile}) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'withdrawn') url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseBadRequest(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'withdrawn') url = '/gsoc/proposal/withdraw/' + suffix postdata = {'value': 'checked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.status, 'pending')
def testUpdateProposal(self): """Test update proposals. """ self.data.createStudentWithProposal() self.timeline.studentSignup() proposal = GSoCProposal.all().get() url = "/gsoc/proposal/update/%s/%s" % (self.gsoc.key().name(), proposal.key().id()) response = self.client.get(url) self.assertProposalTemplatesUsed(response) override = {"program": self.gsoc, "score": 0, "mentor": None, "org": self.org, "status": "new"} response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response)
def testUpdateProposal(self): """Test update proposals. """ self.data.createStudentWithProposal() self.timeline.studentSignup() proposal = GSoCProposal.all().get() url = '/gsoc/proposal/update/%s/%s' % ( self.gsoc.key().name(), proposal.key().id()) response = self.client.get(url) self.assertProposalTemplatesUsed(response) override = {'program': self.gsoc, 'score': 0, 'mentor': None, 'org': self.org, 'status': 'new'} response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response)
def testSubmitProposal(self): self.data.createStudent() self.timeline.studentSignup() url = '/gsoc/proposal/submit/' + self.org.key().name() response = self.client.get(url) self.assertProposalTemplatesUsed(response) # test proposal POST override = {'program': self.gsoc, 'score': 0, 'mentor': None, 'org': self.org, 'status': 'new'} response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) # test review GET url = '/gsoc/proposal/review/' + suffix response = self.client.get(url) self.assertReviewTemplateUsed(response) # test comment POST from soc.modules.gsoc.models.comment import GSoCComment url = '/gsoc/proposal/comment/' + suffix override = {'author': self.data.profile, 'is_private': False} response, properties = self.modelPost(url, GSoCComment, override) self.assertResponseRedirect(response) comment = GSoCComment.all().get() self.assertPropertiesEqual(properties, comment) # Hacky self.data.createMentor(self.org) # test score POST from soc.modules.gsoc.models.score import GSoCScore url = '/gsoc/proposal/score/' + suffix override = {'author': self.data.profile, 'parent': proposal} response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().get() self.assertPropertiesEqual(properties, score)
def testSubmitProposal(self): self.data.createStudent() self.timeline.studentSignup() url = "/gsoc/proposal/submit/" + self.org.key().name() response = self.client.get(url) self.assertProposalTemplatesUsed(response) # test proposal POST override = {"program": self.gsoc, "score": 0, "mentor": None, "org": self.org, "status": "new"} response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal) suffix = "%s/%s/%d" % (self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) # test review GET url = "/gsoc/proposal/review/" + suffix response = self.client.get(url) self.assertReviewTemplateUsed(response) # test comment POST from soc.modules.gsoc.models.comment import GSoCComment url = "/gsoc/proposal/comment/" + suffix override = {"author": self.data.profile, "is_private": False} response, properties = self.modelPost(url, GSoCComment, override) self.assertResponseRedirect(response) comment = GSoCComment.all().get() self.assertPropertiesEqual(properties, comment) # Hacky self.data.createMentor(self.org) # test score POST from soc.modules.gsoc.models.score import GSoCScore url = "/gsoc/proposal/score/" + suffix override = {"author": self.data.profile, "parent": proposal} response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().get() self.assertPropertiesEqual(properties, score)
def clear(*args, **kwargs): """Removes all entities from the datastore. """ # TODO(dbentley): If there are more than 1000 instances of any model, # this method will not clear all instances. Instead, it should continually # call .all(), delete all those, and loop until .all() is empty. entities = itertools.chain(*[ Survey.all(), SurveyRecord.all(), GCIOrganization.all(), GSoCTimeline.all(), GCITimeline.all(), GSoCProgram.all(), GSoCProject.all(), GSoCProposal.all(), GCIProgram.all(), GCIScore.all(), GSoCStudentInfo.all(), GCIStudentInfo.all(), GCITask.all(), Sponsor.all(), Site.all(), Document.all(), # The below models are all subclasses of ndb.Model and therefore must # use .query() to return all instances instead of .all(). soc_org_model.SOCOrganization.query(), profile_model.Profile.query(), soc_profile.SOCStudentData.query(), user.User.query(), address.Address.query(), contact.Contact.query() ]) try: for entity in entities: if isinstance(entity, ndb.Model): entity.key.delete() else: entity.delete() except db.Timeout: return http.HttpResponseRedirect('#') memcache.flush_all() return http.HttpResponse('Done')
def getListData(self): """Returns the list data as requested by the current request. If the lists as requested is not supported by this component None is returned. """ idx = lists.getListIndex(self.request) if idx == 4: q = GSoCProposal.all() q.filter('org IN', self.data.mentor_for) starter = lists.keyModelStarter(GSoCProposal) response_builder = lists.RawQueryContentResponseBuilder( self.request, self._list_config, q, starter, prefetch=['org']) return response_builder.build() else: return None
def testPubliclyVisibleButton(self): self.data.createStudent() proposal = self.createProposal({'scope': self.data.profile, 'parent': self.data.profile}) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/publicly_visible/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertTrue(proposal.is_publicly_visible)
def clear(*args, **kwargs): """Removes all entities from the datastore. """ # TODO(dbentley): If there are more than 1000 instances of any model, # this method will not clear all instances. Instead, it should continually # call .all(), delete all those, and loop until .all() is empty. entities = itertools.chain(*[ Notification.all(), GCIStudent.all(), Survey.all(), SurveyRecord.all(), StudentProposal.all(), GSoCOrganization.all(), GCIOrganization.all(), GSoCTimeline.all(), GCITimeline.all(), GSoCProgram.all(), GSoCProfile.all(), GCIProfile.all(), GSoCProposal.all(), GCIProgram.all(), GCIScore.all(), GSoCStudentInfo.all(), GCIStudentInfo.all(), GCITask.all(), Host.all(), Sponsor.all(), User.all(), Site.all(), Document.all(), ]) try: for entity in entities: entity.delete() except db.Timeout: return http.HttpResponseRedirect('#') # pylint: disable=E1101 memcache.flush_all() return http.HttpResponse('Done')
def testPubliclyVisibleButton(self): self.data.createStudent() proposal = self.createProposal({ 'scope': self.data.profile, 'parent': self.data.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), self.data.user.key().name(), proposal.key().id()) url = '/gsoc/proposal/publicly_visible/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertTrue(proposal.is_publicly_visible)
def testPubliclyVisibleButton(self): user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) student = profile_utils.seedSOCStudent(self.program, user=user) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % (self.gsoc.key().name(), user.key.id(), proposal.key().id()) url = '/gsoc/proposal/publicly_visible/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertTrue(proposal.is_publicly_visible)
def testSubmitProposal(self): mentor = GSoCProfileHelper(self.gsoc, self.dev_test) mentor.createOtherUser('*****@*****.**') mentor.createMentor(self.org) mentor.notificationSettings(new_proposals=True, public_comments=True, private_comments=True) other_mentor = GSoCProfileHelper(self.gsoc, self.dev_test) other_mentor.createOtherUser('*****@*****.**') other_mentor.createMentor(self.org) other_mentor.notificationSettings() self.data.createStudent() self.data.notificationSettings() self.timeline.studentSignup() url = '/gsoc/proposal/submit/' + self.org.key().name() response = self.get(url) self.assertProposalTemplatesUsed(response) # test proposal POST override = { 'program': self.gsoc, 'score': 0, 'nr_scores': 0, 'mentor': None, 'org': self.org, 'status': 'pending', 'accept_as_project': False, 'is_editable_post_deadline': False, 'extra': None, 'has_mentor': False, } response, properties = self.modelPost(url, GSoCProposal, override) self.assertResponseRedirect(response) self.assertEmailSent(to=mentor.profile.email, n=1) self.assertEmailNotSent(to=other_mentor.profile.email) proposal = GSoCProposal.all().get() self.assertPropertiesEqual(properties, proposal)
def testPubliclyVisibleButton(self): user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) student = profile_utils.seedSOCStudent(self.program, user=user) proposal = proposal_utils.seedProposal( student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % ( self.gsoc.key().name(), user.key.id(), proposal.key().id()) url = '/gsoc/proposal/publicly_visible/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertTrue(proposal.is_publicly_visible)
def process(student_info): logging.debug("Converting student_info '%r'" % student_info.key()) proposals = GSoCProposal.all().ancestor(student_info.parent_key()).fetch(1000) projects = GSoCProject.all().ancestor(student_info.parent_key()).fetch(1000) proposals = [i for i in proposals if i.status != 'withdrawn'] projects = [i for i in projects if i.status != 'withdrawn'] nr_proposals = len(proposals) nr_projects = len(projects) orgs = [GSoCProject.org.get_value_for_datastore(i) for i in projects] student_info.number_of_proposals = nr_proposals student_info.number_of_projects = nr_projects student_info.project_for_orgs = orgs yield operation.db.Put(student_info) yield operation.counters.Increment("student_infos_converted") yield operation.counters.Increment("proposals_counted", delta=nr_proposals) yield operation.counters.Increment("projects_counted", delta=nr_projects)
def checkAccess(self): self.data.proposer_user = User.get_by_key_name( self.data.kwargs['student']) fields = ['sponsor', 'program', 'student'] key_name = '/'.join(self.data.kwargs[i] for i in fields) self.data.proposer_profile = GSoCProfile.get_by_key_name( key_name, parent=self.data.proposer_user) if not self.data.proposer_profile: raise NotFound('Requested user does not exist') self.data.proposal = GSoCProposal.get_by_id( int(self.data.kwargs['id']), parent=self.data.proposer_profile) if not self.data.proposal: raise NotFound('Requested proposal does not exist') self.data.proposal_org = self.data.proposal.org self.check.canAccessProposalEntity() self.mutator.commentVisible()
def testIgnoreProposalButton(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.profile_id, proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile(self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/ignore/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() self.assertNotEqual(proposal.status, 'ignored')
def testAssignMentor(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() proposal = self.createProposal({ 'scope': student.profile, 'parent': student.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) self.data.createMentor(self.org) url = '/gsoc/proposal/assign_mentor/' + suffix postdata = {'assign_mentor': self.data.profile.key()} response = self.post(url, postdata) self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() self.assertEqual(proposal.mentor, None)
def testProposalModificationButton(self): student = profile_utils.seedSOCStudent(self.program) proposal = proposal_utils.seedProposal(student.key, self.program.key(), org_key=self.org.key) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.key.parent().id(), proposal.key().id()) user = profile_utils.seedNDBUser() profile_utils.loginNDB(user) profile_utils.seedNDBProfile(self.program.key(), user=user, mentor_for=[self.org.key]) url = '/gsoc/proposal/modification/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertTrue(proposal.is_editable_post_deadline)
def testProposalModificationButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() proposal = self.createProposal({ 'scope': student.profile, 'parent': student.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) self.data.createMentor(self.org) url = '/gsoc/proposal/modification/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertTrue(proposal.is_editable_post_deadline)
def testIgnoreProposalButton(self): student = GSoCProfileHelper(self.gsoc, self.dev_test) student.createOtherUser('*****@*****.**') student.createStudent() proposal = self.createProposal({ 'scope': student.profile, 'parent': student.profile }) suffix = "%s/%s/%d" % (self.gsoc.key().name(), student.user.key().name(), proposal.key().id()) self.data.createMentor(self.org) url = '/gsoc/proposal/ignore/' + suffix postdata = {'value': 'unchecked'} response = self.post(url, postdata) self.assertResponseForbidden(response) proposal = GSoCProposal.all().get() self.assertNotEqual(proposal.status, 'ignored')
def process(student_info): logging.debug("Converting student_info '%r'", student_info.key()) proposals = GSoCProposal.all().ancestor( student_info.parent_key()).fetch(1000) projects = GSoCProject.all().ancestor( student_info.parent_key()).fetch(1000) proposals = [i for i in proposals if i.status != 'withdrawn'] projects = [i for i in projects if i.status != 'withdrawn'] nr_proposals = len(proposals) nr_projects = len(projects) orgs = [GSoCProject.org.get_value_for_datastore(i) for i in projects] student_info.number_of_proposals = nr_proposals student_info.number_of_projects = nr_projects student_info.project_for_orgs = orgs yield operation.db.Put(student_info) yield operation.counters.Increment("student_infos_converted") yield operation.counters.Increment("proposals_counted", delta=nr_proposals) yield operation.counters.Increment("projects_counted", delta=nr_projects)