def setUpEventListeners(self):
     """Install a listener for events emitted during the test."""
     self.collected_events = []
     if hasattr(self, 'modified_event_listener'):
         # Event listeners is already registered.
         return
     self.modified_event_listener = TestEventListener(
         IQuestion, IObjectModifiedEvent, self.collectEvent)
     self.created_event_listener = TestEventListener(
         IQuestionMessage, IObjectCreatedEvent, self.collectEvent)
    def setUp(self):
        # Use an admin to get launchpad.Edit on all the branches to easily
        # approve and reject the proposals.
        super(TestCodeReviewKarma, self).setUp('*****@*****.**')
        # The way the zope infrastructure works is that we can register
        # subscribers easily, but there is no way to unregister them (bug
        # 2338).  TestEventListener does this with by setting a property to
        # stop calling the callback function.  Instead of ending up with a
        # whole pile of registered inactive event listeners, we just
        # reactivate the one we have if there is one.
        if self.karma_listener is None:
            self.karma_listener = TestEventListener(IPerson,
                                                    IKarmaAssignedEvent,
                                                    self._on_karma_assigned)
        else:
            self.karma_listener._active = True

        self.karma_events = []
    def setUp(self):
        # Use an admin to get launchpad.Edit on all the branches to easily
        # approve and reject the proposals.
        super(TestCodeReviewKarma, self).setUp('*****@*****.**')
        # The way the zope infrastructure works is that we can register
        # subscribers easily, but there is no way to unregister them (bug
        # 2338).  TestEventListener does this with by setting a property to
        # stop calling the callback function.  Instead of ending up with a
        # whole pile of registered inactive event listeners, we just
        # reactivate the one we have if there is one.
        if self.karma_listener is None:
            self.karma_listener = TestEventListener(
                IPerson, IKarmaAssignedEvent, self._on_karma_assigned)
        else:
            self.karma_listener._active = True

        self.karma_events = []
예제 #4
0
 def register_listener(self):
     """Register listener.  Must be `unregister`ed later."""
     self.listener = TestEventListener(
         IPerson, IKarmaAssignedEvent, self.receive)
예제 #5
0
class KarmaRecorder:
    """Helper that records selected karma events.

    Install with `register` (and don't forget to uninstall later with
    `unregister`).

    A list of karma events is accumulated in the `karma_events`
    property.
    """

    def __init__(self, person=None, action_name=None, product=None,
                 distribution=None, sourcepackagename=None):
        """Create a `KarmaRecorder`, but do not activate it yet.

        :param person: If given, record only karma for this `Person`.
        :param action_name: If given, record only karma with this action
            name (e.g. questionasked, sponsoruploadaccepted, bugfixed).
        :param product: If given, record only karma related to this
            `Product`.
        :param distribution: If given, record only karma related to this
            `Distribution`.
        :param sourcepackagename: If given, record only karma related to
            this `SourcePackageName`.
        """
        self.person = person
        self.action_name = action_name
        self.product = product
        self.distribution = distribution
        self.sourcepackagename = sourcepackagename

        self.karma_events = []

    def _filterFor(self, filter_value, event_value):
        """Does an event property value pass our filter for that property?"""
        return filter_value is None or event_value == filter_value

    def filter(self, karma):
        """Does `karma` match our filters?"""
        return (
            self._filterFor(self.person, karma.person) and
            self._filterFor(self.action_name, karma.action.name) and
            self._filterFor(self.product, karma.product) and
            self._filterFor(self.distribution, karma.distribution) and
            self._filterFor(self.sourcepackagename, karma.sourcepackagename))

    def record(self, karma):
        """Overridable: record the assignment of karma.

        The default action to record the karma object in
        `self.karma_events`, but feel free to override this with your
        own handler.
        """
        self.karma_events.append(karma)

    def receive(self, obj, event):
        """Process a karma event.

        Runs `filter` on the event and if it passes, `record`s it.
        """
        if self.filter(event.karma):
            self.record(event.karma)

    def register_listener(self):
        """Register listener.  Must be `unregister`ed later."""
        self.listener = TestEventListener(
            IPerson, IKarmaAssignedEvent, self.receive)

    def unregister_listener(self):
        """Unregister listener after `register`."""
        self.listener.unregister()
class TestCodeReviewKarma(TestCaseWithFactory):
    """Test the allocation of karma for revisions.

    As part of the confirmation that karma is allocated, this also confirms
    that the events are being fired, and the appropriate karma allocation
    functions have been registered correctly in the zcml.
    """

    layer = DatabaseFunctionalLayer
    karma_listener = None

    def setUp(self):
        # Use an admin to get launchpad.Edit on all the branches to easily
        # approve and reject the proposals.
        super(TestCodeReviewKarma, self).setUp('*****@*****.**')
        # The way the zope infrastructure works is that we can register
        # subscribers easily, but there is no way to unregister them (bug
        # 2338).  TestEventListener does this with by setting a property to
        # stop calling the callback function.  Instead of ending up with a
        # whole pile of registered inactive event listeners, we just
        # reactivate the one we have if there is one.
        if self.karma_listener is None:
            self.karma_listener = TestEventListener(IPerson,
                                                    IKarmaAssignedEvent,
                                                    self._on_karma_assigned)
        else:
            self.karma_listener._active = True

        self.karma_events = []

    def tearDown(self):
        self.karma_listener.unregister()
        super(TestCodeReviewKarma, self).tearDown()

    def _on_karma_assigned(self, object, event):
        # Store the karma event for checking in the test method.
        self.karma_events.append(event.karma)

    def assertOneKarmaEvent(self, receiver, action_name):
        # Make sure that there is one and only one karma event, and it is for
        # the right user and of the right type.
        self.assertEqual(1, len(self.karma_events))
        event = self.karma_events[0]
        self.assertEqual(receiver, event.person)
        self.assertEqual(action_name, event.action.name)

    def test_mergeProposalCreationAllocatesKarma(self):
        # Registering a branch merge proposal creates a karma event for the
        # registrant.
        source_branch = self.factory.makeProductBranch()
        target_branch = self.factory.makeProductBranch(
            product=source_branch.product)
        registrant = self.factory.makePerson()
        # We need to clear the karma event list before we add the landing
        # target as there would be other karma events for the branch
        # creations.
        self.karma_events = []
        # The normal SQLObject events use the logged in person.
        login_person(registrant)
        source_branch.addLandingTarget(registrant, target_branch)
        self.assertOneKarmaEvent(registrant, 'branchmergeproposed')

    def test_commentOnProposal(self):
        # Any person commenting on a code review gets a karma event.
        proposal = self.factory.makeBranchMergeProposal()
        commenter = self.factory.makePerson()
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewcomment')

    def test_reviewerCommentingOnProposal(self):
        # A reviewer commenting on a code review gets a different karma event
        # to non-reviewers commenting.
        proposal = self.factory.makeBranchMergeProposal()
        commenter = proposal.target_branch.owner
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewreviewercomment')

    def test_commentOnOwnProposal(self):
        # If the reviewer is also the registrant of the proposal, they just
        # get a normal code review comment karma event.
        commenter = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=commenter)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=commenter)
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewcomment')

    def test_approveCodeReview(self):
        # Approving a code review is a significant event, and as such gets its
        # own karma event.
        proposal = self.factory.makeBranchMergeProposal()
        reviewer = proposal.target_branch.owner
        self.karma_events = []
        proposal.approveBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergeapproved')

    def test_approvingOwnCodeReview(self):
        # Approving your own merge proposal isn't such a significant event.
        reviewer = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=reviewer)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=reviewer)
        self.karma_events = []
        proposal.approveBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergeapprovedown')

    def test_rejectedCodeReview(self):
        # Rejecting a code review is also a significant event, and as such
        # gets its own karma event.
        proposal = self.factory.makeBranchMergeProposal()
        reviewer = proposal.target_branch.owner
        self.karma_events = []
        proposal.rejectBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergerejected')

    def test_rejectedOwnCodeReview(self):
        # Rejecting your own merge proposal isn't such a significant event
        # either, and I don't know why someone would, but hey, people are
        # strange.
        reviewer = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=reviewer)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=reviewer)
        self.karma_events = []
        proposal.rejectBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergerejectedown')
class TestCodeReviewKarma(TestCaseWithFactory):
    """Test the allocation of karma for revisions.

    As part of the confirmation that karma is allocated, this also confirms
    that the events are being fired, and the appropriate karma allocation
    functions have been registered correctly in the zcml.
    """

    layer = DatabaseFunctionalLayer
    karma_listener = None

    def setUp(self):
        # Use an admin to get launchpad.Edit on all the branches to easily
        # approve and reject the proposals.
        super(TestCodeReviewKarma, self).setUp('*****@*****.**')
        # The way the zope infrastructure works is that we can register
        # subscribers easily, but there is no way to unregister them (bug
        # 2338).  TestEventListener does this with by setting a property to
        # stop calling the callback function.  Instead of ending up with a
        # whole pile of registered inactive event listeners, we just
        # reactivate the one we have if there is one.
        if self.karma_listener is None:
            self.karma_listener = TestEventListener(
                IPerson, IKarmaAssignedEvent, self._on_karma_assigned)
        else:
            self.karma_listener._active = True

        self.karma_events = []

    def tearDown(self):
        self.karma_listener.unregister()
        super(TestCodeReviewKarma, self).tearDown()

    def _on_karma_assigned(self, object, event):
        # Store the karma event for checking in the test method.
        self.karma_events.append(event.karma)

    def assertOneKarmaEvent(self, receiver, action_name):
        # Make sure that there is one and only one karma event, and it is for
        # the right user and of the right type.
        self.assertEqual(1, len(self.karma_events))
        event = self.karma_events[0]
        self.assertEqual(receiver, event.person)
        self.assertEqual(action_name, event.action.name)

    def test_mergeProposalCreationAllocatesKarma(self):
        # Registering a branch merge proposal creates a karma event for the
        # registrant.
        source_branch = self.factory.makeProductBranch()
        target_branch = self.factory.makeProductBranch(
            product=source_branch.product)
        registrant = self.factory.makePerson()
        # We need to clear the karma event list before we add the landing
        # target as there would be other karma events for the branch
        # creations.
        self.karma_events = []
        # The normal SQLObject events use the logged in person.
        login_person(registrant)
        source_branch.addLandingTarget(registrant, target_branch)
        self.assertOneKarmaEvent(registrant, 'branchmergeproposed')

    def test_commentOnProposal(self):
        # Any person commenting on a code review gets a karma event.
        proposal = self.factory.makeBranchMergeProposal()
        commenter = self.factory.makePerson()
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewcomment')

    def test_reviewerCommentingOnProposal(self):
        # A reviewer commenting on a code review gets a different karma event
        # to non-reviewers commenting.
        proposal = self.factory.makeBranchMergeProposal()
        commenter = proposal.target_branch.owner
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewreviewercomment')

    def test_commentOnOwnProposal(self):
        # If the reviewer is also the registrant of the proposal, they just
        # get a normal code review comment karma event.
        commenter = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=commenter)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=commenter)
        self.karma_events = []
        login_person(commenter)
        proposal.createComment(commenter, "A comment", "The review.")
        self.assertOneKarmaEvent(commenter, 'codereviewcomment')

    def test_approveCodeReview(self):
        # Approving a code review is a significant event, and as such gets its
        # own karma event.
        proposal = self.factory.makeBranchMergeProposal()
        reviewer = proposal.target_branch.owner
        self.karma_events = []
        proposal.approveBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergeapproved')

    def test_approvingOwnCodeReview(self):
        # Approving your own merge proposal isn't such a significant event.
        reviewer = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=reviewer)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=reviewer)
        self.karma_events = []
        proposal.approveBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergeapprovedown')

    def test_rejectedCodeReview(self):
        # Rejecting a code review is also a significant event, and as such
        # gets its own karma event.
        proposal = self.factory.makeBranchMergeProposal()
        reviewer = proposal.target_branch.owner
        self.karma_events = []
        proposal.rejectBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergerejected')

    def test_rejectedOwnCodeReview(self):
        # Rejecting your own merge proposal isn't such a significant event
        # either, and I don't know why someone would, but hey, people are
        # strange.
        reviewer = self.factory.makePerson()
        target_branch = self.factory.makeProductBranch(owner=reviewer)
        proposal = self.factory.makeBranchMergeProposal(
            target_branch=target_branch, registrant=reviewer)
        self.karma_events = []
        proposal.rejectBranch(reviewer, "A rev id.")
        self.assertOneKarmaEvent(reviewer, 'branchmergerejectedown')
예제 #8
0
 def register_listener(self):
     """Register listener.  Must be `unregister`ed later."""
     self.listener = TestEventListener(IPerson, IKarmaAssignedEvent,
                                       self.receive)
예제 #9
0
class KarmaRecorder:
    """Helper that records selected karma events.

    Install with `register` (and don't forget to uninstall later with
    `unregister`).

    A list of karma events is accumulated in the `karma_events`
    property.
    """
    def __init__(self,
                 person=None,
                 action_name=None,
                 product=None,
                 distribution=None,
                 sourcepackagename=None):
        """Create a `KarmaRecorder`, but do not activate it yet.

        :param person: If given, record only karma for this `Person`.
        :param action_name: If given, record only karma with this action
            name (e.g. questionasked, sponsoruploadaccepted, bugfixed).
        :param product: If given, record only karma related to this
            `Product`.
        :param distribution: If given, record only karma related to this
            `Distribution`.
        :param sourcepackagename: If given, record only karma related to
            this `SourcePackageName`.
        """
        self.person = person
        self.action_name = action_name
        self.product = product
        self.distribution = distribution
        self.sourcepackagename = sourcepackagename

        self.karma_events = []

    def _filterFor(self, filter_value, event_value):
        """Does an event property value pass our filter for that property?"""
        return filter_value is None or event_value == filter_value

    def filter(self, karma):
        """Does `karma` match our filters?"""
        return (self._filterFor(self.person, karma.person)
                and self._filterFor(self.action_name, karma.action.name)
                and self._filterFor(self.product, karma.product)
                and self._filterFor(self.distribution, karma.distribution)
                and self._filterFor(self.sourcepackagename,
                                    karma.sourcepackagename))

    def record(self, karma):
        """Overridable: record the assignment of karma.

        The default action to record the karma object in
        `self.karma_events`, but feel free to override this with your
        own handler.
        """
        self.karma_events.append(karma)

    def receive(self, obj, event):
        """Process a karma event.

        Runs `filter` on the event and if it passes, `record`s it.
        """
        if self.filter(event.karma):
            self.record(event.karma)

    def register_listener(self):
        """Register listener.  Must be `unregister`ed later."""
        self.listener = TestEventListener(IPerson, IKarmaAssignedEvent,
                                          self.receive)

    def unregister_listener(self):
        """Unregister listener after `register`."""
        self.listener.unregister()