launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #02866
[Merge] lp:~wallyworld/launchpad/branch-picker-team-branches into lp:launchpad
Ian Booth has proposed merging lp:~wallyworld/launchpad/branch-picker-team-branches into lp:launchpad.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#407260 Translations export branch can't be team-owned
https://bugs.launchpad.net/bugs/407260
For more details, see:
https://code.launchpad.net/~wallyworld/launchpad/branch-picker-team-branches/+merge/52356
See bug 407260. This branch enhances the ownedBy() API on IBranchCollection to optionally return branches owned by a team of which the person is a member.
== Implementation ==
Added optional include_team_membership (defaults to False) parameter to ownedBy() API. If true, an extra clause is added to the filter to do the required work.
== Tests ==
Added new tests to code.model.tests.test_branchcollection.TestBranchCollectionFilters:
test_ownedBy_with_team_membership
test_ownedBy_and_inProduct_with_team_membership
Enhanced:
code.vocabularies.test.branch.txt
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/code/interfaces/branchcollection.py
lib/lp/code/model/branchcollection.py
lib/lp/code/model/tests/test_branchcollection.py
lib/lp/code/vocabularies/branch.py
lib/lp/code/vocabularies/tests/branch.txt
./lib/lp/code/interfaces/branchcollection.py
50: E301 expected 1 blank line, found 2
--
https://code.launchpad.net/~wallyworld/launchpad/branch-picker-team-branches/+merge/52356
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~wallyworld/launchpad/branch-picker-team-branches into lp:launchpad.
=== modified file 'lib/lp/code/interfaces/branchcollection.py'
--- lib/lp/code/interfaces/branchcollection.py 2011-03-03 01:13:47 +0000
+++ lib/lp/code/interfaces/branchcollection.py 2011-03-07 01:40:13 +0000
@@ -145,8 +145,12 @@
with a sourcepackage.
"""
- def ownedBy(person):
- """Restrict the collection to branches owned by 'person'."""
+ def ownedBy(person, include_team_membership=False):
+ """Restrict the collection to branches owned by 'person'.
+
+ :param include_team_membership: If True, the result will include
+ branches owned by teams of which the person is a member.
+ """
def registeredBy(person):
"""Restrict the collection to branches registered by 'person'."""
=== modified file 'lib/lp/code/model/branchcollection.py'
--- lib/lp/code/model/branchcollection.py 2011-03-03 03:04:30 +0000
+++ lib/lp/code/model/branchcollection.py 2011-03-07 01:40:13 +0000
@@ -14,6 +14,7 @@
And,
Count,
Desc,
+ In,
Join,
LeftJoin,
Or,
@@ -158,6 +159,7 @@
resultset = self.store.using(*tables).find(Branch, *expressions)
if not eager_load:
return resultset
+
def do_eager_load(rows):
branch_ids = set(branch.id for branch in rows)
if not branch_ids:
@@ -368,9 +370,18 @@
Branch.product == None,
Branch.sourcepackagename == None])
- def ownedBy(self, person):
+ def ownedBy(self, person, include_team_membership=False):
"""See `IBranchCollection`."""
- return self._filterBy([Branch.owner == person])
+ filter = Branch.owner == person
+ if include_team_membership:
+ subquery = Select(
+ TeamParticipation.teamID,
+ where=TeamParticipation.personID==person.id)
+ filter = Or(
+ filter,
+ In(Branch.ownerID, subquery))
+
+ return self._filterBy([filter])
def registeredBy(self, person):
"""See `IBranchCollection`."""
=== modified file 'lib/lp/code/model/tests/test_branchcollection.py'
--- lib/lp/code/model/tests/test_branchcollection.py 2011-01-27 14:02:38 +0000
+++ lib/lp/code/model/tests/test_branchcollection.py 2011-03-07 01:40:13 +0000
@@ -192,6 +192,17 @@
collection = self.all_branches.ownedBy(branch.owner)
self.assertEqual([branch], list(collection.getBranches()))
+ def test_ownedBy_with_team_membership(self):
+ # 'ownedBy' returns a new collection restricted to branches owned by
+ # any team of which the given person is a member.
+ person = self.factory.makePerson()
+ team = self.factory.makeTeam(members=[person])
+ branch = self.factory.makeAnyBranch(owner=team)
+ branch2 = self.factory.makeAnyBranch()
+ collection = self.all_branches.ownedBy(
+ person, include_team_membership=True)
+ self.assertEqual([branch], list(collection.getBranches()))
+
def test_in_product(self):
# 'inProduct' returns a new collection restricted to branches in the
# given product.
@@ -230,6 +241,26 @@
collection = self.all_branches.ownedBy(person).inProduct(product)
self.assertEqual([branch], list(collection.getBranches()))
+ def test_ownedBy_and_inProduct_with_team_membership(self):
+ # 'ownedBy' and 'inProduct' can combine to form a collection that is
+ # restricted to branches of a particular product owned by a particular
+ # person or team of which the person is a member.
+ person = self.factory.makePerson()
+ team = self.factory.makeTeam(members=[person])
+ product = self.factory.makeProduct()
+ branch = self.factory.makeProductBranch(product=product, owner=person)
+ branch2 = self.factory.makeProductBranch(product=product, owner=team)
+ branch3 = self.factory.makeAnyBranch(owner=person)
+ branch4 = self.factory.makeProductBranch(product=product)
+ collection = self.all_branches.inProduct(product).ownedBy(
+ person, include_team_membership=True)
+ self.assertEqual(
+ set([branch, branch2]), set(collection.getBranches()))
+ collection = self.all_branches.ownedBy(
+ person, include_team_membership=True).inProduct(product)
+ self.assertEqual(
+ set([branch, branch2]), set(collection.getBranches()))
+
def test_in_source_package(self):
# 'inSourcePackage' returns a new collection that only has branches in
# the given source package.
=== modified file 'lib/lp/code/vocabularies/branch.py'
--- lib/lp/code/vocabularies/branch.py 2011-03-03 01:13:47 +0000
+++ lib/lp/code/vocabularies/branch.py 2011-03-07 01:40:13 +0000
@@ -130,5 +130,7 @@
self.user = getUtility(ILaunchBag).user
def _getCollection(self):
- return getUtility(IAllBranches).ownedBy(self.user).withBranchType(
+ return getUtility(IAllBranches).ownedBy(
+ self.user, include_team_membership=True,
+ ).withBranchType(
BranchType.HOSTED)
=== modified file 'lib/lp/code/vocabularies/tests/branch.txt'
--- lib/lp/code/vocabularies/tests/branch.txt 2010-09-20 00:43:45 +0000
+++ lib/lp/code/vocabularies/tests/branch.txt 2011-03-07 01:40:13 +0000
@@ -130,6 +130,7 @@
>>> from lp.code.enums import BranchType
>>> a_user = factory.makePerson(name='a-branching-user')
+ >>> a_team = factory.makeTeam(name='a-team', members=[a_user])
>>> product1 = factory.makeProduct(name='product-one')
>>> mirrored_branch = factory.makeBranch(
... owner=a_user, product=product1, name='mirrored',
@@ -137,12 +138,15 @@
>>> product2 = factory.makeProduct(name='product-two')
>>> hosted_branch = factory.makeBranch(
... owner=a_user, product=product2, name='hosted')
+ >>> another_hosted_branch = factory.makeBranch(
+ ... owner=a_team, product=product2, name='another_hosted')
>>> foreign_branch = factory.makeBranch()
-It returns branches owned by the user, but not ones owned by others, nor
-ones that aren't hosted on Launchpad.
+It returns branches owned by the user, or teams a user belongs to, but not
+ones owned by others, nor ones that aren't hosted on Launchpad.
>>> branch_vocabulary = vocabulary_registry.get(
... a_user, "HostedBranchRestrictedOnOwner")
>>> print_vocab_branches(branch_vocabulary, None)
~a-branching-user/product-two/hosted
+ ~a-team/product-two/another_hosted
Follow ups