示例#1
0
    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)
示例#2
0
  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)
示例#3
0
    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)
示例#4
0
  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)
示例#6
0
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)
示例#8
0
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)