Merge lp://staging/~abentley/launchpad/bmp-iprivacy into lp://staging/launchpad

Proposed by Aaron Bentley
Status: Merged
Approved by: Gavin Panella
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp://staging/~abentley/launchpad/bmp-iprivacy
Merge into: lp://staging/launchpad
Diff against target: None lines
To merge this branch: bzr merge lp://staging/~abentley/launchpad/bmp-iprivacy
Reviewer Review Type Date Requested Status
Gavin Panella (community) code Approve
Review via email: mp+11442@code.staging.launchpad.net
To post a comment you must log in.
Revision history for this message
Aaron Bentley (abentley) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

= Summary =
Implement IPrivacy for BranchMergeProposal

== Proposed fix ==
Privacy for branch merge proposals is determined by the involved
branches: the source, target and optional dependent branch. If any are
private, the merge proposal is private.

== Pre-implementation notes ==
Pre-implementation was with thumper

== Implementation details ==
I also added a test that BranchMergeProposal implements
IBranchMergeProposal, as a drive-by.

== Tests ==
bin/test test_branchmergeproposals -t Privacy

== Demo and Q/A ==
Create a private branch. Propose it for merging. Note that the merge
proposal has the standard privacy bars.

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/code/configure.zcml
  lib/lp/code/interfaces/branchmergeproposal.py
  lib/lp/code/model/branchmergeproposal.py
  lib/lp/code/model/tests/test_branchmergeproposals.py

== Pylint notices ==

lib/lp/code/interfaces/branchmergeproposal.py
    27: [F0401] Unable to import 'lazr.lifecycle.event' (No module named
lifecycle)
    42: [F0401] Unable to import 'lazr.restful.fields' (No module named
restful)
    43: [F0401] Unable to import 'lazr.restful.declarations' (No module
named restful)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkqnyGgACgkQ0F+nu1YWqI2mIACaAv9Y1uhElpNOOFhOgoiT/aFY
V0gAn24bUSNXGGRCZxoWzYoL0VBhDHjM
=T23r
-----END PGP SIGNATURE-----

Revision history for this message
Gavin Panella (allenap) wrote :

> 115 +class TestBranchMergeProposalPrivacy(TestCaseWithFactory):
> 116 + """Ensure that BranchMergeProposal implements its interface."""

I think you need to change this to say "... implements IPrivacy" or something like that. Otherwise, nice branch.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/code/configure.zcml'
--- lib/lp/code/configure.zcml 2009-09-04 13:10:32 +0000
+++ lib/lp/code/configure.zcml 2009-09-09 15:16:45 +0000
@@ -189,6 +189,7 @@
189 dependent_branch189 dependent_branch
190 whiteboard190 whiteboard
191 queue_status191 queue_status
192 private
192 reviewer193 reviewer
193 reviewed_revision_id194 reviewed_revision_id
194 queuer195 queuer
195196
=== modified file 'lib/lp/code/interfaces/branchmergeproposal.py'
--- lib/lp/code/interfaces/branchmergeproposal.py 2009-09-09 02:18:01 +0000
+++ lib/lp/code/interfaces/branchmergeproposal.py 2009-09-09 15:16:45 +0000
@@ -28,11 +28,11 @@
28from zope.event import notify28from zope.event import notify
29from zope.interface import Attribute, Interface29from zope.interface import Attribute, Interface
30from zope.schema import (30from zope.schema import (
31 Bytes, Choice, Datetime, Int, Object, Text, TextLine)31 Bytes, Bool, Choice, Datetime, Int, Object, Text, TextLine)
3232
33from canonical.launchpad import _33from canonical.launchpad import _
34from canonical.launchpad.fields import PublicPersonChoice, Summary, Whiteboard34from canonical.launchpad.fields import PublicPersonChoice, Summary, Whiteboard
35from canonical.launchpad.interfaces import IBug35from canonical.launchpad.interfaces import IBug, IPrivacy
36from lp.code.enums import BranchMergeProposalStatus, CodeReviewVote36from lp.code.enums import BranchMergeProposalStatus, CodeReviewVote
37from lp.code.interfaces.branch import IBranch37from lp.code.interfaces.branch import IBranch
38from lp.registry.interfaces.person import IPerson38from lp.registry.interfaces.person import IPerson
@@ -85,7 +85,7 @@
85 )85 )
8686
8787
88class IBranchMergeProposal(Interface):88class IBranchMergeProposal(IPrivacy):
89 """Branch merge proposals show intent of landing one branch on another."""89 """Branch merge proposals show intent of landing one branch on another."""
9090
91 export_as_webservice_entry()91 export_as_webservice_entry()
@@ -121,6 +121,15 @@
121 "If this is the same as the target branch, then "121 "If this is the same as the target branch, then "
122 "leave this field blank.")))122 "leave this field blank.")))
123123
124 # This is redefined from IPrivacy.private because the attribute is
125 # read-only. The value is determined by the involved branches.
126 private = exported(
127 Bool(
128 title=_("Proposal is confidential"), required=False,
129 readonly=True, default=False,
130 description=_(
131 "If True, this proposal is visible only to subscribers.")))
132
124 whiteboard = Whiteboard(133 whiteboard = Whiteboard(
125 title=_('Whiteboard'), required=False,134 title=_('Whiteboard'), required=False,
126 description=_('Notes about the merge.'))135 description=_('Notes about the merge.'))
127136
=== modified file 'lib/lp/code/model/branchmergeproposal.py'
--- lib/lp/code/model/branchmergeproposal.py 2009-09-09 02:18:01 +0000
+++ lib/lp/code/model/branchmergeproposal.py 2009-09-09 15:16:45 +0000
@@ -117,6 +117,13 @@
117 enum=BranchMergeProposalStatus, notNull=True,117 enum=BranchMergeProposalStatus, notNull=True,
118 default=BranchMergeProposalStatus.WORK_IN_PROGRESS)118 default=BranchMergeProposalStatus.WORK_IN_PROGRESS)
119119
120 @property
121 def private(self):
122 return (
123 self.source_branch.private or self.target_branch.private or
124 (self.dependent_branch is not None and
125 self.dependent_branch.private))
126
120 reviewer = ForeignKey(127 reviewer = ForeignKey(
121 dbName='reviewer', foreignKey='Person',128 dbName='reviewer', foreignKey='Person',
122 storm_validator=validate_public_person, notNull=False,129 storm_validator=validate_public_person, notNull=False,
123130
=== modified file 'lib/lp/code/model/tests/test_branchmergeproposals.py'
--- lib/lp/code/model/tests/test_branchmergeproposals.py 2009-09-09 02:18:01 +0000
+++ lib/lp/code/model/tests/test_branchmergeproposals.py 2009-09-09 15:16:45 +0000
@@ -24,6 +24,7 @@
24 DatabaseFunctionalLayer, LaunchpadFunctionalLayer, LaunchpadZopelessLayer)24 DatabaseFunctionalLayer, LaunchpadFunctionalLayer, LaunchpadZopelessLayer)
25from lazr.lifecycle.event import ObjectModifiedEvent25from lazr.lifecycle.event import ObjectModifiedEvent
2626
27from canonical.launchpad.interfaces import IPrivacy
27from canonical.launchpad.interfaces.message import IMessageJob28from canonical.launchpad.interfaces.message import IMessageJob
28from canonical.launchpad.webapp.testing import verifyObject29from canonical.launchpad.webapp.testing import verifyObject
29from lp.code.event.branchmergeproposal import (30from lp.code.event.branchmergeproposal import (
@@ -33,11 +34,12 @@
33 ANONYMOUS, import_secret_test_key, login, syncUpdate)34 ANONYMOUS, import_secret_test_key, login, syncUpdate)
34from lp.code.enums import (35from lp.code.enums import (
35 BranchMergeProposalStatus, BranchSubscriptionNotificationLevel,36 BranchMergeProposalStatus, BranchSubscriptionNotificationLevel,
36 BranchType, CodeReviewNotificationLevel, CodeReviewVote)37 BranchType, CodeReviewNotificationLevel, CodeReviewVote,
38 BranchVisibilityRule)
37from lp.code.interfaces.branchmergeproposal import (39from lp.code.interfaces.branchmergeproposal import (
38 BadStateTransition,40 BadStateTransition,
39 BRANCH_MERGE_PROPOSAL_FINAL_STATES as FINAL_STATES,41 BRANCH_MERGE_PROPOSAL_FINAL_STATES as FINAL_STATES,
40 IBranchMergeProposalGetter, IBranchMergeProposalJob,42 IBranchMergeProposal, IBranchMergeProposalGetter, IBranchMergeProposalJob,
41 ICreateMergeProposalJob, ICreateMergeProposalJobSource,43 ICreateMergeProposalJob, ICreateMergeProposalJobSource,
42 IMergeProposalCreatedJob, notify_modified, WrongBranchMergeProposal)44 IMergeProposalCreatedJob, notify_modified, WrongBranchMergeProposal)
43from lp.code.model.branchmergeproposaljob import (45from lp.code.model.branchmergeproposaljob import (
@@ -56,6 +58,51 @@
56from lp.testing.mail_helpers import pop_notifications58from lp.testing.mail_helpers import pop_notifications
5759
5860
61class TestBranchMergeProposalInterface(TestCaseWithFactory):
62 """Ensure that BranchMergeProposal implements its interface."""
63
64 layer = DatabaseFunctionalLayer
65
66 def test_BranchMergeProposal_implements_interface(self):
67 """Ensure that BranchMergeProposal implements its interface."""
68 bmp = self.factory.makeBranchMergeProposal()
69 verifyObject(IBranchMergeProposal, bmp)
70
71
72class TestBranchMergeProposalPrivacy(TestCaseWithFactory):
73 """Ensure that BranchMergeProposal implements its interface."""
74
75 layer = DatabaseFunctionalLayer
76
77 def test_BranchMergeProposal_implements_interface(self):
78 """Ensure that BranchMergeProposal implements privacy."""
79 bmp = self.factory.makeBranchMergeProposal()
80 verifyObject(IPrivacy, bmp)
81
82 @staticmethod
83 def setPrivate(branch):
84 """Force a branch to be private."""
85 login_person(branch.owner)
86 branch.product.setBranchVisibilityTeamPolicy(
87 branch.owner, BranchVisibilityRule.PRIVATE)
88 branch.setPrivate(True)
89
90 def test_private(self):
91 """Private flag should be True if True for any involved branch."""
92 bmp = self.factory.makeBranchMergeProposal()
93 self.assertFalse(bmp.private)
94 self.setPrivate(bmp.source_branch)
95 self.assertTrue(bmp.private)
96 bmp.source_branch.setPrivate(False)
97 self.setPrivate(bmp.target_branch)
98 self.assertTrue(bmp.private)
99 bmp.target_branch.setPrivate(False)
100 removeSecurityProxy(bmp).dependent_branch = self.factory.makeBranch(
101 product=bmp.source_branch.product)
102 self.setPrivate(bmp.dependent_branch)
103 self.assertTrue(bmp.private)
104
105
59class TestBranchMergeProposalTransitions(TestCaseWithFactory):106class TestBranchMergeProposalTransitions(TestCaseWithFactory):
60 """Test the state transitions of branch merge proposals."""107 """Test the state transitions of branch merge proposals."""
61108