Merge ~pappacena/launchpad:bugfix-private-mp-webhook-trigger into launchpad:master

Proposed by Thiago F. Pappacena
Status: Merged
Approved by: Thiago F. Pappacena
Approved revision: 7b57c36a9110dfad8377a006109ad5767cd0d79b
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~pappacena/launchpad:bugfix-private-mp-webhook-trigger
Merge into: launchpad:master
Diff against target: 133 lines (+55/-14)
2 files modified
lib/lp/code/model/branchmergeproposal.py (+5/-7)
lib/lp/code/model/tests/test_branchmergeproposal.py (+50/-7)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+387781@code.launchpad.net

Commit message

Fixing webhook trigger for private git repositories

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Needs Fixing
7b57c36... by Thiago F. Pappacena

Refactoring test code nad removing unused attribute from GitRef

Revision history for this message
Thiago F. Pappacena (pappacena) wrote :

cjwatson, pushed the requested changes.

I'll do the other test improvements in another MP, just to make it easier to review (I have made a good bunch of refactoring in the tests to remove some code duplication).

Feel free to approve this one only once the other MP is approved, if you think it will be necessary.

Revision history for this message
Thiago F. Pappacena (pappacena) wrote :
Revision history for this message
Colin Watson (cjwatson) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/code/model/branchmergeproposal.py b/lib/lp/code/model/branchmergeproposal.py
2index 5ebcf04..338cc29 100644
3--- a/lib/lp/code/model/branchmergeproposal.py
4+++ b/lib/lp/code/model/branchmergeproposal.py
5@@ -1,4 +1,4 @@
6-# Copyright 2009-2018 Canonical Ltd. This software is licensed under the
7+# Copyright 2009-2020 Canonical Ltd. This software is licensed under the
8 # GNU Affero General Public License version 3 (see the file LICENSE).
9
10 """Database class for branch merge proposals."""
11@@ -70,6 +70,7 @@ from lp.code.event.branchmergeproposal import (
12 BranchMergeProposalNeedsReviewEvent,
13 ReviewerNominatedEvent,
14 )
15+from lp.code.interfaces.branch import IBranch
16 from lp.code.interfaces.branchcollection import IAllBranches
17 from lp.code.interfaces.branchmergeproposal import (
18 BRANCH_MERGE_PROPOSAL_FINAL_STATES as FINAL_STATES,
19@@ -881,7 +882,7 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
20 BranchSubscriptionDiffSize.NODIFF,
21 CodeReviewNotificationLevel.FULL,
22 user)
23- if branch.stacked_on is not None:
24+ if IBranch.providedBy(branch) and branch.stacked_on is not None:
25 checked_branches.append(branch)
26 if branch.stacked_on not in checked_branches:
27 self._subscribeUserToStackedBranch(
28@@ -903,14 +904,11 @@ class BranchMergeProposal(SQLBase, BugLinkTargetMixin):
29 the reviewer if the branch is private and the reviewer is an open
30 team.
31 """
32- if self.source_branch is None:
33- # This only applies to Bazaar, which has stacked branches.
34- return
35- source = self.source_branch
36+ source = self.merge_source
37 if (not source.visibleByUser(reviewer) and
38 self._acceptable_to_give_visibility(source, reviewer)):
39 self._subscribeUserToStackedBranch(source, reviewer)
40- target = self.target_branch
41+ target = self.merge_target
42 if (not target.visibleByUser(reviewer) and
43 self._acceptable_to_give_visibility(source, reviewer)):
44 self._subscribeUserToStackedBranch(target, reviewer)
45diff --git a/lib/lp/code/model/tests/test_branchmergeproposal.py b/lib/lp/code/model/tests/test_branchmergeproposal.py
46index 8936574..7e380a3 100644
47--- a/lib/lp/code/model/tests/test_branchmergeproposal.py
48+++ b/lib/lp/code/model/tests/test_branchmergeproposal.py
49@@ -1,4 +1,4 @@
50-# Copyright 2009-2019 Canonical Ltd. This software is licensed under the
51+# Copyright 2009-2020 Canonical Ltd. This software is licensed under the
52 # GNU Affero General Public License version 3 (see the file LICENSE).
53
54 """Tests for BranchMergeProposals."""
55@@ -91,6 +91,7 @@ from lp.services.webapp import canonical_url
56 from lp.services.webhooks.testing import LogsScheduledWebhooks
57 from lp.services.xref.interfaces import IXRefSet
58 from lp.testing import (
59+ admin_logged_in,
60 ExpectedException,
61 launchpadlib_for,
62 login,
63@@ -1035,15 +1036,24 @@ class TestMergeProposalWebhooks(WithScenarios, TestCaseWithFactory):
64 self.useFixture(FeatureFixture(
65 {BRANCH_MERGE_PROPOSAL_WEBHOOKS_FEATURE_FLAG: "on"}))
66
67- def makeBranch(self, same_target_as=None):
68- kwargs = {}
69+ def makeBranch(self, same_target_as=None, information_type=None):
70+ # Create the product pillar and its access policy if information
71+ # type is "PROPRIETARY".
72+ if same_target_as is None:
73+ product = self.factory.makeProduct()
74+ if information_type == InformationType.PROPRIETARY:
75+ self.factory.makeAccessPolicy(product)
76+ else:
77+ same_target_as = removeSecurityProxy(same_target_as)
78+ product = (same_target_as.target if self.git else
79+ same_target_as.product)
80+
81+ kwargs = {"information_type": information_type}
82 if self.git:
83- if same_target_as is not None:
84- kwargs["target"] = same_target_as.target
85+ kwargs["target"] = product
86 return self.factory.makeGitRefs(**kwargs)[0]
87 else:
88- if same_target_as is not None:
89- kwargs["product"] = same_target_as.product
90+ kwargs["product"] = product
91 return self.factory.makeProductBranch(**kwargs)
92
93 def getWebhookTarget(self, branch):
94@@ -1102,6 +1112,39 @@ class TestMergeProposalWebhooks(WithScenarios, TestCaseWithFactory):
95 (hook, "merge-proposal:0.1",
96 MatchesDict(expected_redacted_payload))]))
97
98+ def test_create_private_repo_triggers_webhooks(self):
99+ # When a merge proposal is created, any relevant webhooks are
100+ # triggered even if the repository is proprietary.
101+ logger = self.useFixture(FakeLogger())
102+ source = self.makeBranch(information_type=InformationType.PROPRIETARY)
103+ target = self.makeBranch(
104+ same_target_as=source,
105+ information_type=InformationType.PROPRIETARY)
106+
107+ with admin_logged_in():
108+ # Create the web hook and the proposal.
109+ registrant = self.factory.makePerson()
110+ hook = self.factory.makeWebhook(
111+ target=self.getWebhookTarget(target),
112+ event_types=["merge-proposal:0.1"])
113+ proposal = source.addLandingTarget(
114+ registrant, target, needs_review=True)
115+ target_owner = target.owner
116+
117+ login_person(target_owner)
118+ delivery = hook.deliveries.one()
119+ expected_payload = {
120+ "merge_proposal": Equals(self.getURL(proposal)),
121+ "action": Equals("created"),
122+ "new": MatchesDict(self.getExpectedPayload(proposal)),
123+ }
124+ expected_redacted_payload = dict(
125+ expected_payload,
126+ new=MatchesDict(
127+ self.getExpectedPayload(proposal, redact=True)))
128+ self.assertCorrectDelivery(expected_payload, hook, delivery)
129+ self.assertCorrectLogging(expected_redacted_payload, hook, logger)
130+
131 def test_create_triggers_webhooks(self):
132 # When a merge proposal is created, any relevant webhooks are
133 # triggered.