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):
    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 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 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 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 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 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 = 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 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 testWithdrawProposalButton(self):
    self.timeline_helper.studentSignup()

    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)

    number_of_proposals = student.student_data.number_of_proposals

    suffix = "%s/%s/%d" % (
        self.gsoc.key().name(),
        student.key.parent().id(),
        proposal.key().id())

    # withdraw the proposal
    url = '/gsoc/proposal/status/' + suffix
    postdata = {'value': proposal_review_view.TOGGLE_BUTTON_IS_WITHDRAWN}
    response = self.post(url, postdata)

    self.assertResponseOK(response)

    # check that the student proposal is withdrawn
    proposal = GSoCProposal.get(proposal.key())
    self.assertEqual(proposal.status, proposal_model.STATUS_WITHDRAWN)

    # check that number of proposals is updated
    student = student.key.get()
    self.assertEqual(
        number_of_proposals - 1, student.student_data.number_of_proposals)

    # try withdrawing the proposal once more time
    url = '/gsoc/proposal/status/' + suffix
    postdata = {'value': proposal_review_view.TOGGLE_BUTTON_IS_WITHDRAWN}
    response = self.post(url, postdata)

    self.assertResponseOK(response)

    # check that the student proposal is still withdrawn
    proposal = GSoCProposal.get(proposal.key())
    self.assertEqual(proposal.status, proposal_model.STATUS_WITHDRAWN)

    # check that number of proposals is still the same
    student = student.key.get()
    self.assertEqual(
        number_of_proposals - 1, student.student_data.number_of_proposals)

    # resubmit the proposal
    url = '/gsoc/proposal/status/' + suffix
    postdata = {'value': proposal_review_view.TOGGLE_BUTTON_NOT_WITHDRAWN}
    response = self.post(url, postdata)

    self.assertResponseOK(response)

    # check that the student proposal is pending
    proposal = GSoCProposal.get(proposal.key())
    self.assertEqual(proposal.status, proposal_model.STATUS_PENDING)

    # check that number of proposals is increased again
    student = student.key.get()
    self.assertEqual(
        number_of_proposals, student.student_data.number_of_proposals)
    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 testWithdrawProposalButton(self):
        self.timeline_helper.studentSignup()

        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)

        number_of_proposals = student.student_data.number_of_proposals

        suffix = "%s/%s/%d" % (self.gsoc.key().name(),
                               student.key.parent().id(), proposal.key().id())

        # withdraw the proposal
        url = '/gsoc/proposal/status/' + suffix
        postdata = {'value': proposal_review_view.TOGGLE_BUTTON_IS_WITHDRAWN}
        response = self.post(url, postdata)

        self.assertResponseOK(response)

        # check that the student proposal is withdrawn
        proposal = GSoCProposal.get(proposal.key())
        self.assertEqual(proposal.status, proposal_model.STATUS_WITHDRAWN)

        # check that number of proposals is updated
        student = student.key.get()
        self.assertEqual(number_of_proposals - 1,
                         student.student_data.number_of_proposals)

        # try withdrawing the proposal once more time
        url = '/gsoc/proposal/status/' + suffix
        postdata = {'value': proposal_review_view.TOGGLE_BUTTON_IS_WITHDRAWN}
        response = self.post(url, postdata)

        self.assertResponseOK(response)

        # check that the student proposal is still withdrawn
        proposal = GSoCProposal.get(proposal.key())
        self.assertEqual(proposal.status, proposal_model.STATUS_WITHDRAWN)

        # check that number of proposals is still the same
        student = student.key.get()
        self.assertEqual(number_of_proposals - 1,
                         student.student_data.number_of_proposals)

        # resubmit the proposal
        url = '/gsoc/proposal/status/' + suffix
        postdata = {'value': proposal_review_view.TOGGLE_BUTTON_NOT_WITHDRAWN}
        response = self.post(url, postdata)

        self.assertResponseOK(response)

        # check that the student proposal is pending
        proposal = GSoCProposal.get(proposal.key())
        self.assertEqual(proposal.status, proposal_model.STATUS_PENDING)

        # check that number of proposals is increased again
        student = student.key.get()
        self.assertEqual(number_of_proposals,
                         student.student_data.number_of_proposals)