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 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 testReviewProposal(self): mentor = self.createMentorWithSettings('*****@*****.**', {'new_proposals' :True, 'public_comments': True, 'private_comments' :True}) self.data.createStudent() self.data.notificationSettings() self.timeline.studentSignup() 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()) # test review GET url = '/gsoc/proposal/review/' + suffix response = self.get(url) self.assertReviewTemplateUsed(response) self.assertNotContains( response, '<p class="status"><strong>Status:</strong> Pending</p>') # 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) self.assertEmailSent(to=mentor.profile.email, n=1) self.assertEmailNotSent(to=self.data.profile.email) self.data.deleteProfile() 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, 'value': 1} response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().get() self.assertPropertiesEqual(properties, score) proposal = GSoCProposal.all().get() self.assertEqual(1, proposal.score) self.assertEqual(1, proposal.nr_scores) # test updating score override['value'] = 4 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(4, proposal.score) self.assertEqual(1, proposal.nr_scores) # test removing score override['value'] = 0 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(0, proposal.score) self.assertEqual(0, proposal.nr_scores)
def testReviewProposal(self): mentor = self.createMentorWithSettings( '*****@*****.**', { 'new_proposals': True, 'public_comments': True, 'private_comments': True }) self.data.createStudent() self.data.notificationSettings() self.timeline.studentSignup() 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()) # test review GET url = '/gsoc/proposal/review/' + suffix response = self.get(url) self.assertReviewTemplateUsed(response) self.assertNotContains( response, '<p class="status"><strong>Status:</strong> Pending</p>') # 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) self.assertEmailSent(to=mentor.profile.email, n=1) self.assertEmailNotSent(to=self.data.profile.email) self.data.deleteProfile() 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, 'value': 1 } response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().get() self.assertPropertiesEqual(properties, score) proposal = GSoCProposal.all().get() self.assertEqual(1, proposal.score) self.assertEqual(1, proposal.nr_scores) # test updating score override['value'] = 4 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(4, proposal.score) self.assertEqual(1, proposal.nr_scores) # test removing score override['value'] = 0 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.all().get() self.assertEqual(0, proposal.score) self.assertEqual(0, proposal.nr_scores)
def convertGSoCProfileDBEntityGroup(profile_key): """Converts DB based part of entity group associated with the specified profile. Args: profile_key: db.Key of the profile to process """ # map that associate old keys with new ones which are created during # the conversion conversion_map = {} to_delete = [] do_put = True proposals = GSoCProposal.all().ancestor(profile_key).fetch(1000) for proposal in proposals: # update GSoCProposal.parent new_proposal = _convertParent(proposal) # update GSoCProposal.possible_mentors new_proposal.possible_mentors = _convertListProperty( GSoCProposal.possible_mentors, new_proposal) # update GSoCProposal.mentor new_proposal.mentor = _convertReferenceProperty( GSoCProposal.mentor, new_proposal) to_delete.append(proposal) if do_put: new_proposal.put() conversion_map[proposal.key()] = new_proposal.key() comments = GSoCComment.all().ancestor(proposal).fetch(1000) for comment in comments: # update GSoCComment.parent new_comment = _convertParent(comment, parent=new_proposal.key()) # update GSoCComment.author new_comment.author = _convertReferenceProperty( GSoCComment.author, new_comment) if do_put: new_comment.put() to_delete.append(comment) scores = GSoCScore.all().ancestor(proposal).fetch(1000) for score in scores: # update GSoCScore.parent new_score = _convertParent(score, parent=new_proposal.key()) # update GSoCScore.author new_score.author = _convertReferenceProperty(GSoCScore.author, new_score) if do_put: new_score.put() to_delete.append(score) projects = GSoCProject.all().ancestor(profile_key).fetch(1000) for project in projects: # update GSoCProject.parent new_project = _convertParent(project) # update GSoCProject.mentors new_project.mentors = _convertListProperty(GSoCProject.mentors, new_project) # update GSoCProject.proposal proposal_key = GSoCProject.proposal.get_value_for_datastore(project) if proposal_key: new_project.proposal = conversion_map.get( GSoCProject.proposal.get_value_for_datastore(project)) if do_put: new_project.put() conversion_map[project.key()] = new_project.key() to_delete.append(project) grading_records = GSoCGradingRecord.all().ancestor(project.key()) for grading_record in grading_records: # update GSoCGradingProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing grading_project_survey_record_key = ( GSoCGradingRecord.mentor_record.get_value_for_datastore( grading_record)) if grading_project_survey_record_key: grading_project_survey_record = GSoCGradingProjectSurveyRecord.get( grading_project_survey_record_key) if grading_project_survey_record: grading_project_survey_record.project = new_project.key() if do_put: grading_project_survey_record.put() # update GSoCProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing project_survey_record_key = ( GSoCGradingRecord.student_record.get_value_for_datastore( grading_record)) if project_survey_record_key: project_survey_record = GSoCProjectSurveyRecord.get( project_survey_record_key) if project_survey_record: project_survey_record.project = new_project.key() if do_put: project_survey_record.put() # update GSoCGradingRecord.parent new_grading_record = _convertParent( grading_record, parent=new_project.key()) if do_put: new_grading_record.put() code_samples = GSoCCodeSample.all().ancestor(project.key()) for code_sample in code_samples: # update GSoCCodeSample.parent new_code_sample = _convertParent(code_sample, parent=new_project.key()) if do_put: new_code_sample.put() to_delete.append(code_sample) db.delete(to_delete)
def testReviewProposal(self): self.timeline_helper.studentSignup() # TODO(daniel): Re-seed settings when they are added. # {'notify_new_proposals' :True, 'notify_public_comments': True, # 'notify_private_comments' :True} mentor = profile_utils.seedNDBProfile( self.program.key(), mentor_for=[self.org.key]) 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(), student.key.parent().id(), proposal.key().id()) # test review GET url = '/gsoc/proposal/review/' + suffix response = self.get(url) self.assertResponseOK(response) self.assertReviewTemplateUsed(response) self.assertNotContains( response, '<p class="status"><strong>Status:</strong> Pending</p>') # test comment POST from soc.modules.gsoc.models.comment import GSoCComment url = '/gsoc/proposal/comment/' + suffix override = {'author': student.key.to_old_key(), 'is_private': False} response, properties = self.modelPost(url, GSoCComment, override) self.assertResponseRedirect(response) comment = GSoCComment.all().ancestor(proposal).get() author_key = ndb.Key.from_old_key( GSoCComment.author.get_value_for_datastore(comment)) self.assertEqual(author_key, student.key) # TODO(daniel): notifications # self.assertEmailSent(to=mentor.email) # TODO(daniel): add assertEmailNotSent to DjangoTestCase # self.assertEmailNotSent(to=self.profile_helper.profile.email) # login as a mentor profile_utils.loginNDB(mentor.key.parent().get()) # test score POST from soc.modules.gsoc.models.score import GSoCScore url = '/gsoc/proposal/score/' + suffix override = { 'author': mentor.key.to_old_key(), 'parent': proposal, 'value': 1} response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().ancestor(proposal).get() author_key = ndb.Key.from_old_key( GSoCScore.author.get_value_for_datastore(score)) self.assertEqual(author_key, mentor.key) self.assertEqual(1, score.value) proposal = GSoCProposal.all().get() self.assertEqual(1, proposal.score) self.assertEqual(1, proposal.nr_scores) # test updating score override['value'] = 4 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertEqual(4, proposal.score) self.assertEqual(1, proposal.nr_scores) # test removing score override['value'] = 0 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertEqual(0, proposal.score) self.assertEqual(0, proposal.nr_scores)
def convertGSoCProfileDBEntityGroup(profile_key): """Converts DB based part of entity group associated with the specified profile. Args: profile_key: db.Key of the profile to process """ # map that associate old keys with new ones which are created during # the conversion conversion_map = {} to_delete = [] do_put = True proposals = GSoCProposal.all().ancestor(profile_key).fetch(1000) for proposal in proposals: # update GSoCProposal.parent new_proposal = _convertParent(proposal) # update GSoCProposal.possible_mentors new_proposal.possible_mentors = _convertListProperty( GSoCProposal.possible_mentors, new_proposal) # update GSoCProposal.mentor new_proposal.mentor = _convertReferenceProperty( GSoCProposal.mentor, new_proposal) to_delete.append(proposal) if do_put: new_proposal.put() conversion_map[proposal.key()] = new_proposal.key() comments = GSoCComment.all().ancestor(proposal).fetch(1000) for comment in comments: # update GSoCComment.parent new_comment = _convertParent(comment, parent=new_proposal.key()) # update GSoCComment.author new_comment.author = _convertReferenceProperty( GSoCComment.author, new_comment) if do_put: new_comment.put() to_delete.append(comment) scores = GSoCScore.all().ancestor(proposal).fetch(1000) for score in scores: # update GSoCScore.parent new_score = _convertParent(score, parent=new_proposal.key()) # update GSoCScore.author new_score.author = _convertReferenceProperty( GSoCScore.author, new_score) if do_put: new_score.put() to_delete.append(score) projects = GSoCProject.all().ancestor(profile_key).fetch(1000) for project in projects: # update GSoCProject.parent new_project = _convertParent(project) # update GSoCProject.mentors new_project.mentors = _convertListProperty(GSoCProject.mentors, new_project) # update GSoCProject.proposal proposal_key = GSoCProject.proposal.get_value_for_datastore(project) if proposal_key: new_project.proposal = conversion_map.get( GSoCProject.proposal.get_value_for_datastore(project)) if do_put: new_project.put() conversion_map[project.key()] = new_project.key() to_delete.append(project) grading_records = GSoCGradingRecord.all().ancestor(project.key()) for grading_record in grading_records: # update GSoCGradingProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing grading_project_survey_record_key = ( GSoCGradingRecord.mentor_record.get_value_for_datastore( grading_record)) if grading_project_survey_record_key: grading_project_survey_record = GSoCGradingProjectSurveyRecord.get( grading_project_survey_record_key) if grading_project_survey_record: grading_project_survey_record.project = new_project.key() if do_put: grading_project_survey_record.put() # update GSoCProjectSurveyRecord.project # this is another entity group, but XG transaction does the thing project_survey_record_key = ( GSoCGradingRecord.student_record.get_value_for_datastore( grading_record)) if project_survey_record_key: project_survey_record = GSoCProjectSurveyRecord.get( project_survey_record_key) if project_survey_record: project_survey_record.project = new_project.key() if do_put: project_survey_record.put() # update GSoCGradingRecord.parent new_grading_record = _convertParent(grading_record, parent=new_project.key()) if do_put: new_grading_record.put() code_samples = GSoCCodeSample.all().ancestor(project.key()) for code_sample in code_samples: # update GSoCCodeSample.parent new_code_sample = _convertParent(code_sample, parent=new_project.key()) if do_put: new_code_sample.put() to_delete.append(code_sample) db.delete(to_delete)
def testReviewProposal(self): self.timeline_helper.studentSignup() # TODO(daniel): Re-seed settings when they are added. # {'notify_new_proposals' :True, 'notify_public_comments': True, # 'notify_private_comments' :True} mentor = profile_utils.seedNDBProfile(self.program.key(), mentor_for=[self.org.key]) 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(), student.key.parent().id(), proposal.key().id()) # test review GET url = '/gsoc/proposal/review/' + suffix response = self.get(url) self.assertResponseOK(response) self.assertReviewTemplateUsed(response) self.assertNotContains( response, '<p class="status"><strong>Status:</strong> Pending</p>') # test comment POST from soc.modules.gsoc.models.comment import GSoCComment url = '/gsoc/proposal/comment/' + suffix override = {'author': student.key.to_old_key(), 'is_private': False} response, properties = self.modelPost(url, GSoCComment, override) self.assertResponseRedirect(response) comment = GSoCComment.all().ancestor(proposal).get() author_key = ndb.Key.from_old_key( GSoCComment.author.get_value_for_datastore(comment)) self.assertEqual(author_key, student.key) # TODO(daniel): notifications # self.assertEmailSent(to=mentor.email) # TODO(daniel): add assertEmailNotSent to DjangoTestCase # self.assertEmailNotSent(to=self.profile_helper.profile.email) # login as a mentor profile_utils.loginNDB(mentor.key.parent().get()) # test score POST from soc.modules.gsoc.models.score import GSoCScore url = '/gsoc/proposal/score/' + suffix override = { 'author': mentor.key.to_old_key(), 'parent': proposal, 'value': 1 } response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) score = GSoCScore.all().ancestor(proposal).get() author_key = ndb.Key.from_old_key( GSoCScore.author.get_value_for_datastore(score)) self.assertEqual(author_key, mentor.key) self.assertEqual(1, score.value) proposal = GSoCProposal.all().get() self.assertEqual(1, proposal.score) self.assertEqual(1, proposal.nr_scores) # test updating score override['value'] = 4 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertEqual(4, proposal.score) self.assertEqual(1, proposal.nr_scores) # test removing score override['value'] = 0 response, properties = self.modelPost(url, GSoCScore, override) self.assertResponseOK(response) proposal = GSoCProposal.get(proposal.key()) self.assertEqual(0, proposal.score) self.assertEqual(0, proposal.nr_scores)