Merge lp:~wallyworld/launchpad/getSharedArtifacts-data-1049374 into lp:launchpad

Proposed by Ian Booth
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 15956
Proposed branch: lp:~wallyworld/launchpad/getSharedArtifacts-data-1049374
Merge into: lp:launchpad
Diff against target: 266 lines (+113/-51)
3 files modified
lib/lp/registry/interfaces/sharingservice.py (+34/-14)
lib/lp/registry/services/sharingservice.py (+18/-3)
lib/lp/registry/services/tests/test_sharingservice.py (+61/-34)
To merge this branch: bzr merge lp:~wallyworld/launchpad/getSharedArtifacts-data-1049374
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+124099@code.launchpad.net

Commit message

Unexport the sharing service getSharedArtifacts, getVisibleArtifacts methods and export getSharedBugs, getSharedBranches.

Description of the change

== Implementation ==

The lazr restful infrastructure does not support fully deserialising collections containing heterogeneous elements, or non-trivial named operation return types like tuples of lists. In such cases, the return data contains json dicts of the attribute values for each item, but not web service Entry objects constructed from said data.

There are two sharing service methods recently exported:

getSharedArtifacts
getVisibleArtifacts

These were used internally first, and exported later.

Given the issues above, and the desire to return collections of web service Entry objects:

1. getSharedArtifacts and getVisibleArtifacts were unexported
2. getSharedBugs and getSharedBranches were added to the sharing service and exported

getSharedArtifacts is used internally to populate the model for the sharing details view. getSharedBugs and getSharedBranches just call this method and only return the relevant list of items.

AFAIK, getVisibleArtifacts was not used in any scripts - it was only exported because it was there.

Scripts which call getSharedArtifacts will now need to call getSharedBugs and getSharedBranches instead.

== Tests ==

Update the sharing service tests.

== Lint ==

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/interfaces/sharingservice.py
  lib/lp/registry/services/sharingservice.py
  lib/lp/registry/services/tests/test_sharingservice.py

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/registry/interfaces/sharingservice.py'
2--- lib/lp/registry/interfaces/sharingservice.py 2012-09-06 10:59:56 +0000
3+++ lib/lp/registry/interfaces/sharingservice.py 2012-09-13 04:35:24 +0000
4@@ -18,7 +18,7 @@
5 operation_for_version,
6 operation_parameters,
7 REQUEST_USER,
8- )
9+ operation_returns_collection_of)
10 from lazr.restful.fields import Reference
11 from zope.schema import (
12 Choice,
13@@ -62,12 +62,6 @@
14 information type.
15 """
16
17- @export_read_operation()
18- @call_with(user=REQUEST_USER)
19- @operation_parameters(
20- pillar=Reference(IPillar, title=_('Pillar'), required=True),
21- person=Reference(IPerson, title=_('Person'), required=True))
22- @operation_for_version('devel')
23 def getSharedArtifacts(pillar, person, user):
24 """Return the artifacts shared between the pillar and person.
25
26@@ -82,13 +76,39 @@
27 """
28
29 @export_read_operation()
30- @operation_parameters(
31- person=Reference(IPerson, title=_('Person'), required=True),
32- branches=List(
33- Reference(schema=IBranch), title=_('Branches'), required=False),
34- bugs=List(
35- Reference(schema=IBug), title=_('Bugs'), required=False))
36- @operation_for_version('devel')
37+ @call_with(user=REQUEST_USER)
38+ @operation_parameters(
39+ pillar=Reference(IPillar, title=_('Pillar'), required=True),
40+ person=Reference(IPerson, title=_('Person'), required=True))
41+ @operation_returns_collection_of(IBug)
42+ @operation_for_version('devel')
43+ def getSharedBugs(pillar, person, user):
44+ """Return the bugs shared between the pillar and person.
45+
46+ The result includes bugtasks rather than bugs since this is what the
47+ pillar filtering is applied to. The shared bug can be obtained simply
48+ by reading the bugtask.bug attribute.
49+
50+ :param user: the user making the request. Only bugs visible to the
51+ user will be included in the result.
52+ :return: a collection of bug tasks.
53+ """
54+
55+ @export_read_operation()
56+ @call_with(user=REQUEST_USER)
57+ @operation_parameters(
58+ pillar=Reference(IPillar, title=_('Pillar'), required=True),
59+ person=Reference(IPerson, title=_('Person'), required=True))
60+ @operation_returns_collection_of(IBranch)
61+ @operation_for_version('devel')
62+ def getSharedBranches(pillar, person, user):
63+ """Return the branches shared between the pillar and person.
64+
65+ :param user: the user making the request. Only branches visible to the
66+ user will be included in the result.
67+ :return: a collection of branches
68+ """
69+
70 def getVisibleArtifacts(person, branches=None, bugs=None):
71 """Return the artifacts shared with person.
72
73
74=== modified file 'lib/lp/registry/services/sharingservice.py'
75--- lib/lp/registry/services/sharingservice.py 2012-09-06 10:59:56 +0000
76+++ lib/lp/registry/services/sharingservice.py 2012-09-13 04:35:24 +0000
77@@ -113,16 +113,17 @@
78 )
79
80 @available_with_permission('launchpad.Driver', 'pillar')
81- def getSharedArtifacts(self, pillar, person, user):
82+ def getSharedArtifacts(self, pillar, person, user, include_bugs=True,
83+ include_branches=True):
84 """See `ISharingService`."""
85 policies = getUtility(IAccessPolicySource).findByPillar([pillar])
86 flat_source = getUtility(IAccessPolicyGrantFlatSource)
87 bug_ids = set()
88 branch_ids = set()
89 for artifact in flat_source.findArtifactsByGrantee(person, policies):
90- if artifact.bug_id:
91+ if artifact.bug_id and include_bugs:
92 bug_ids.add(artifact.bug_id)
93- elif artifact.branch_id:
94+ elif artifact.branch_id and include_branches:
95 branch_ids.add(artifact.branch_id)
96
97 # Load the bugs.
98@@ -141,6 +142,20 @@
99
100 return bugtasks, branches
101
102+ @available_with_permission('launchpad.Driver', 'pillar')
103+ def getSharedBugs(self, pillar, person, user):
104+ """See `ISharingService`."""
105+ bugtasks, ignore = self.getSharedArtifacts(
106+ pillar, person, user, include_branches=False)
107+ return bugtasks
108+
109+ @available_with_permission('launchpad.Driver', 'pillar')
110+ def getSharedBranches(self, pillar, person, user):
111+ """See `ISharingService`."""
112+ ignore, branches = self.getSharedArtifacts(
113+ pillar, person, user, include_bugs=False)
114+ return branches
115+
116 def getVisibleArtifacts(self, person, branches=None, bugs=None,
117 ignore_permissions=False):
118 """See `ISharingService`."""
119
120=== modified file 'lib/lp/registry/services/tests/test_sharingservice.py'
121--- lib/lp/registry/services/tests/test_sharingservice.py 2012-09-10 10:20:39 +0000
122+++ lib/lp/registry/services/tests/test_sharingservice.py 2012-09-13 04:35:24 +0000
123@@ -1167,46 +1167,52 @@
124 login_person(anyone)
125 self._assert_updatePillarSharingPoliciesUnauthorized(anyone)
126
127- def test_getSharedArtifacts(self):
128- # Test the getSharedArtifacts method.
129- owner = self.factory.makePerson()
130- product = self.factory.makeProduct(owner=owner)
131- login_person(owner)
132-
133+ def create_shared_artifacts(self, product, grantee, user):
134+ # Create some shared bugs and branches.
135 bugs = []
136 bug_tasks = []
137 for x in range(0, 10):
138 bug = self.factory.makeBug(
139- target=product, owner=owner,
140+ target=product, owner=product.owner,
141 information_type=InformationType.USERDATA)
142 bugs.append(bug)
143 bug_tasks.append(bug.default_bugtask)
144 branches = []
145 for x in range(0, 10):
146 branch = self.factory.makeBranch(
147- product=product, owner=owner,
148+ product=product, owner=product.owner,
149 information_type=InformationType.USERDATA)
150 branches.append(branch)
151
152 # Grant access to grantee as well as the person who will be doing the
153 # query. The person who will be doing the query is not granted access
154 # to the last bug/branch so those won't be in the result.
155- grantee = self.factory.makePerson()
156- user = self.factory.makePerson()
157-
158 def grant_access(artifact, grantee_only):
159 access_artifact = self.factory.makeAccessArtifact(
160 concrete=artifact)
161 self.factory.makeAccessArtifactGrant(
162- artifact=access_artifact, grantee=grantee, grantor=owner)
163+ artifact=access_artifact, grantee=grantee,
164+ grantor=product.owner)
165 if not grantee_only:
166 self.factory.makeAccessArtifactGrant(
167- artifact=access_artifact, grantee=user, grantor=owner)
168+ artifact=access_artifact, grantee=user,
169+ grantor=product.owner)
170
171 for i, bug in enumerate(bugs):
172 grant_access(bug, i == 9)
173 for i, branch in enumerate(branches):
174 grant_access(branch, i == 9)
175+ return bug_tasks, branches
176+
177+ def test_getSharedArtifacts(self):
178+ # Test the getSharedArtifacts method.
179+ owner = self.factory.makePerson()
180+ product = self.factory.makeProduct(owner=owner)
181+ login_person(owner)
182+ grantee = self.factory.makePerson()
183+ user = self.factory.makePerson()
184+ bug_tasks, branches = self.create_shared_artifacts(
185+ product, grantee, user)
186
187 # Check the results.
188 shared_bugtasks, shared_branches = self.service.getSharedArtifacts(
189@@ -1214,6 +1220,35 @@
190 self.assertContentEqual(bug_tasks[:9], shared_bugtasks)
191 self.assertContentEqual(branches[:9], shared_branches)
192
193+ def test_getSharedBugs(self):
194+ # Test the getSharedBugs method.
195+ owner = self.factory.makePerson()
196+ product = self.factory.makeProduct(owner=owner)
197+ login_person(owner)
198+ grantee = self.factory.makePerson()
199+ user = self.factory.makePerson()
200+ bug_tasks, ignored = self.create_shared_artifacts(
201+ product, grantee, user)
202+
203+ # Check the results.
204+ shared_bugtasks = self.service.getSharedBugs(product, grantee, user)
205+ self.assertContentEqual(bug_tasks[:9], shared_bugtasks)
206+
207+ def test_getSharedBranches(self):
208+ # Test the getSharedBranches method.
209+ owner = self.factory.makePerson()
210+ product = self.factory.makeProduct(owner=owner)
211+ login_person(owner)
212+ grantee = self.factory.makePerson()
213+ user = self.factory.makePerson()
214+ ignored, branches = self.create_shared_artifacts(
215+ product, grantee, user)
216+
217+ # Check the results.
218+ shared_branches = self.service.getSharedBranches(
219+ product, grantee, user)
220+ self.assertContentEqual(branches[:9], shared_branches)
221+
222 def test_getPeopleWithAccessBugs(self):
223 # Test the getPeopleWithoutAccess method with bugs.
224 owner = self.factory.makePerson()
225@@ -1534,28 +1569,20 @@
226 InformationType.USERDATA.title: SharingPermission.ALL.title}
227 )
228
229- def test_getSharedArtifacts(self):
230+ def test_getSharedBugs(self):
231+ # Test the exported getSharedBugs() method.
232+ ws_pillar = ws_object(self.launchpad, self.pillar)
233+ ws_grantee = ws_object(self.launchpad, self.grantee)
234+ bugtasks = self.service.getSharedBugs(
235+ pillar=ws_pillar, person=ws_grantee)
236+ self.assertEqual(1, len(bugtasks))
237+ self.assertEqual(bugtasks[0].title, self.bug.default_bugtask.title)
238+
239+ def test_getSharedBranches(self):
240 # Test the exported getSharedArtifacts() method.
241 ws_pillar = ws_object(self.launchpad, self.pillar)
242 ws_grantee = ws_object(self.launchpad, self.grantee)
243- (bugtasks, branches) = self.service.getSharedArtifacts(
244+ branches = self.service.getSharedBranches(
245 pillar=ws_pillar, person=ws_grantee)
246- self.assertEqual(1, len(bugtasks))
247- self.assertEqual(1, len(branches))
248- self.assertEqual(bugtasks[0]['title'], self.bug.default_bugtask.title)
249- self.assertEqual(branches[0]['unique_name'], self.branch.unique_name)
250-
251- def test_getVisibleArtifacts(self):
252- # Test the exported getVisibleArtifacts() method.
253- ws_grantee = ws_object(self.launchpad, self.grantee)
254- # Sadly lazr.restful doesn't know how to marshall lists of entities
255- # so we have to use links directly.
256- ws_bug_link = ws_object(self.launchpad, self.bug).self_link
257- ws_branch_link = ws_object(self.launchpad, self.branch).self_link
258- (bugs, branches) = self.service.getVisibleArtifacts(
259- person=ws_grantee,
260- branches=[ws_branch_link], bugs=[ws_bug_link])
261- self.assertEqual(1, len(bugs))
262- self.assertEqual(1, len(branches))
263- self.assertEqual(bugs[0]['title'], self.bug.title)
264- self.assertEqual(branches[0]['unique_name'], self.branch.unique_name)
265+ self.assertEqual(1, len(branches))
266+ self.assertEqual(branches[0].unique_name, self.branch.unique_name)