Merge lp:~stevenk/launchpad/no-structsub-for-bug-supervisor into lp:launchpad

Proposed by Steve Kowalik on 2012-08-16
Status: Merged
Approved by: Steve Kowalik on 2012-08-16
Approved revision: no longer in the source branch.
Merged at revision: 15817
Proposed branch: lp:~stevenk/launchpad/no-structsub-for-bug-supervisor
Merge into: lp:launchpad
Diff against target: 1612 lines (+92/-552)
39 files modified
lib/lp/bugs/browser/bugrole.py (+1/-46)
lib/lp/bugs/browser/bugsupervisor.py (+3/-12)
lib/lp/bugs/browser/bugtarget.py (+3/-6)
lib/lp/bugs/browser/tests/bugtarget-filebug-views.txt (+1/-1)
lib/lp/bugs/browser/tests/bugtask-edit-views.txt (+1/-1)
lib/lp/bugs/browser/tests/test_bugnomination.py (+2/-2)
lib/lp/bugs/browser/tests/test_bugsupervisor.py (+4/-80)
lib/lp/bugs/browser/tests/test_bugtarget_configure.py (+2/-13)
lib/lp/bugs/browser/tests/test_bugtask.py (+4/-7)
lib/lp/bugs/browser/tests/test_expose.py (+1/-2)
lib/lp/bugs/doc/bugsubscription.txt (+13/-61)
lib/lp/bugs/doc/bugtask-search.txt (+2/-2)
lib/lp/bugs/doc/initial-bug-contacts.txt (+1/-46)
lib/lp/bugs/interfaces/bugsupervisor.py (+3/-23)
lib/lp/bugs/interfaces/bugtask.py (+2/-4)
lib/lp/bugs/model/tests/test_bug.py (+2/-6)
lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py (+3/-7)
lib/lp/bugs/model/tests/test_bugtask.py (+4/-9)
lib/lp/bugs/model/tests/test_bugtask_status.py (+4/-6)
lib/lp/bugs/model/tests/test_bugtasksearch.py (+3/-4)
lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt (+4/-4)
lib/lp/bugs/stories/bugtask-management/xx-change-assignee.txt (+1/-1)
lib/lp/bugs/stories/bugtask-management/xx-edit-email-address-bugtask.txt (+2/-2)
lib/lp/bugs/stories/bugtask-management/xx-view-editable-bug-task.txt (+1/-1)
lib/lp/bugs/stories/guided-filebug/xx-ubuntu-filebug.txt (+1/-1)
lib/lp/bugs/tests/bugs-emailinterface.txt (+2/-2)
lib/lp/bugs/tests/has-bug-supervisor.txt (+0/-66)
lib/lp/bugs/tests/test_bug.py (+1/-1)
lib/lp/bugs/tests/test_bugcontact.py (+0/-40)
lib/lp/bugs/tests/test_bugvisibility.py (+1/-3)
lib/lp/registry/browser/product.py (+3/-8)
lib/lp/registry/browser/tests/test_edit_permissions.py (+4/-6)
lib/lp/registry/browser/tests/test_subscription_links.py (+9/-31)
lib/lp/registry/configure.zcml (+2/-4)
lib/lp/registry/doc/private-team-roles.txt (+2/-2)
lib/lp/registry/interfaces/product.py (+0/-2)
lib/lp/registry/model/distribution.py (+0/-7)
lib/lp/registry/model/product.py (+0/-7)
lib/lp/registry/tests/test_product.py (+0/-26)
To merge this branch: bzr merge lp:~stevenk/launchpad/no-structsub-for-bug-supervisor
Reviewer Review Type Date Requested Status
William Grant code 2012-08-16 Approve on 2012-08-16
Review via email: mp+119831@code.launchpad.net

Commit Message

No longer give bug supervisors an unconditional structural subscription on the target when they are set.

Description of the Change

No longer give bug supervisors an unconditional structural subscription on the target when they are set. Due to this, bug supervisor no longer has to have such a draconian validation method, since setting it will no longer spam them with tonnes of mail.

I have done a bunch of drive-bys in this branch too. Mostly whitespace related.

To post a comment you must log in.
William Grant (wgrant) wrote :

Thanks for this cleanup. I wonder if you could go even further by porting some bug_supervisor setters to use makeProduct(bug_supervisor=) instead, as a few seem to be ignorant of its existence.

610 Let's make Foo Bar a bug supervisor for upstream firefox:
611
612 - >>> mozilla_firefox.setBugSupervisor(foobar, foobar)
613 + >>> mozilla_firefox.bug_supervisor = foobar

Is this bit necessary any more? The rest of the test looks like it was just testing notification.

1426 def testPersonCanSetSelfAsSupervisor(self):
1427 # A person can set themselves as bug supervisor for a product.
1428 # This is a regression test for bug 438985.

This test can probably die now.

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/bugs/browser/bugrole.py'
2--- lib/lp/bugs/browser/bugrole.py 2012-02-09 04:28:33 +0000
3+++ lib/lp/bugs/browser/bugrole.py 2012-08-16 12:16:23 +0000
4@@ -1,4 +1,4 @@
5-# Copyright 2010 Canonical Ltd. This software is licensed under the
6+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
7 # GNU Affero General Public License version (see the file LICENSE).
8
9 """Common classes to support bug roles."""
10@@ -41,51 +41,6 @@
11 else:
12 return self.OTHER_USER
13
14- def validateBugSupervisor(self, data):
15- """Validates the new bug supervisor.
16-
17- Verify that the value is None, the user, or a team he administers,
18- otherwise, set a field error.
19- """
20- field_state = self._getFieldState(
21- self.context.bug_supervisor, 'bug_supervisor', data)
22- if field_state is self.INVALID_PERSON:
23- error = (
24- 'You must choose a valid person or team to be the '
25- 'bug supervisor for %s.' % self.context.displayname)
26- elif field_state is self.OTHER_TEAM:
27- supervisor = data['bug_supervisor']
28- team_url = canonical_url(
29- supervisor, rootsite='mainsite', view_name='+members')
30- error = structured(
31- 'You cannot set %(team)s as the bug supervisor for '
32- '%(target)s because you are not an administrator of that '
33- 'team.<br />If you believe that %(team)s should be the '
34- 'bug supervisor for %(target)s, notify one of the '
35- '<a href="%(url)s">%(team)s administrators</a>. See '
36- '<a href="https://help.launchpad.net/BugSupervisors">'
37- 'the help wiki</a> for information about setting a bug '
38- 'supervisor.',
39- team=supervisor.displayname,
40- target=self.context.displayname,
41- url=team_url)
42- elif field_state is self.OTHER_USER:
43- error = structured(
44- 'You cannot set another person as the bug supervisor for '
45- '%(target)s.<br />See '
46- '<a href="https://help.launchpad.net/BugSupervisors">'
47- 'the help wiki</a> for information about setting a bug '
48- 'supervisor.',
49- target=self.context.displayname)
50- else:
51- # field_state is self.OK.
52- return
53- self.setFieldError('bug_supervisor', error)
54-
55- def changeBugSupervisor(self, bug_supervisor):
56- if self.context.bug_supervisor != bug_supervisor:
57- self.context.setBugSupervisor(bug_supervisor, self.user)
58-
59 def changeSecurityContact(self, security_contact):
60 if self.context.security_contact != security_contact:
61 self.context.security_contact = security_contact
62
63=== modified file 'lib/lp/bugs/browser/bugsupervisor.py'
64--- lib/lp/bugs/browser/bugsupervisor.py 2012-02-28 04:24:19 +0000
65+++ lib/lp/bugs/browser/bugsupervisor.py 2012-08-16 12:16:23 +0000
66@@ -60,23 +60,14 @@
67
68 cancel_url = next_url
69
70- def validate(self, data):
71- """See `LaunchpadFormView`."""
72- self.validateBugSupervisor(data)
73-
74 @action('Change', name='change')
75 def change_action(self, action, data):
76 """Redirect to the target page with a success message."""
77- bug_supervisor = data['bug_supervisor']
78- self.changeBugSupervisor(bug_supervisor)
79- if bug_supervisor is None:
80+ self.updateContextFromData(data)
81+ if self.context.bug_supervisor is None:
82 message = (
83 "Successfully cleared the bug supervisor. "
84 "You can set the bug supervisor again at any time.")
85 else:
86- message = structured(
87- 'A bug mail subscription was created for the bug supervisor. '
88- 'You can <a href="%s">edit bug mail</a> '
89- 'to change which notifications will be sent.',
90- canonical_url(self.context, view_name='+subscriptions'))
91+ message = structured('Bug supervisor privilege granted.')
92 self.request.response.addNotification(message)
93
94=== modified file 'lib/lp/bugs/browser/bugtarget.py'
95--- lib/lp/bugs/browser/bugtarget.py 2012-08-03 00:30:51 +0000
96+++ lib/lp/bugs/browser/bugtarget.py 2012-08-16 12:16:23 +0000
97@@ -218,7 +218,6 @@
98 """Constrain bug expiration to Launchpad Bugs tracker."""
99 super(ProductConfigureBugTrackerView, self).validate(data)
100 if check_permission("launchpad.Edit", self.context):
101- self.validateBugSupervisor(data)
102 self.validateSecurityContact(data)
103 # enable_bug_expiration is disabled by JavaScript when bugtracker
104 # is not 'In Launchpad'. The constraint is enforced here in case the
105@@ -231,12 +230,10 @@
106
107 @action("Change", name='change')
108 def change_action(self, action, data):
109- # bug_supervisor and security_contactrequires a transition method,
110- # so it must be handled separately and removed for the
111- # updateContextFromData to work as expected.
112+ # security_contact requires a transition method, so it must be
113+ # handled separately and removed for the updateContextFromData call
114+ # to work as expected.
115 if check_permission("launchpad.Edit", self.context):
116- self.changeBugSupervisor(data['bug_supervisor'])
117- del data['bug_supervisor']
118 self.changeSecurityContact(data['security_contact'])
119 del data['security_contact']
120 self.updateContextFromData(data)
121
122=== modified file 'lib/lp/bugs/browser/tests/bugtarget-filebug-views.txt'
123--- lib/lp/bugs/browser/tests/bugtarget-filebug-views.txt 2012-08-06 03:47:42 +0000
124+++ lib/lp/bugs/browser/tests/bugtarget-filebug-views.txt 2012-08-16 12:16:23 +0000
125@@ -685,7 +685,7 @@
126 >>> ignored = login_person(owner)
127 >>> filebug_view = create_initialized_view(product, '+filebug')
128 >>> owner_fields = set(filebug_view.field_names)
129- >>> product.setBugSupervisor(owner, owner)
130+ >>> product.bug_supervisor = owner
131 >>> supervisor_fields = set(filebug_view.field_names)
132
133 Privileged users get most of the same fields as normal users, plus a few
134
135=== modified file 'lib/lp/bugs/browser/tests/bugtask-edit-views.txt'
136--- lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2012-05-22 12:05:51 +0000
137+++ lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2012-08-16 12:16:23 +0000
138@@ -248,7 +248,7 @@
139 >>> login("foo.bar@canonical.com")
140 >>> ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
141 >>> no_priv = getUtility(IPersonSet).getByName("no-priv")
142- >>> ubuntu.setBugSupervisor(no_priv, no_priv)
143+ >>> ubuntu.bug_supervisor = no_priv
144
145 Unlike before, no-priv can now edit the milestone.
146
147
148=== modified file 'lib/lp/bugs/browser/tests/test_bugnomination.py'
149--- lib/lp/bugs/browser/tests/test_bugnomination.py 2012-08-08 11:48:29 +0000
150+++ lib/lp/bugs/browser/tests/test_bugnomination.py 2012-08-16 12:16:23 +0000
151@@ -41,7 +41,7 @@
152 self.bug_worker = self.factory.makePerson()
153 with person_logged_in(owner):
154 bug_team.addMember(self.bug_worker, owner)
155- self.distribution.setBugSupervisor(bug_team, owner)
156+ self.distribution.bug_supervisor = bug_team
157 self.distribution.driver = self.factory.makePerson()
158 self.bug_task = self.factory.makeBugTask(target=self.distribution)
159 launchbag = getUtility(ILaunchBag)
160@@ -54,7 +54,7 @@
161 members.append(person)
162 bug_supervisor = self.factory.makeTeam(members=members, owner=owner)
163 with person_logged_in(owner):
164- target.setBugSupervisor(bug_supervisor, owner)
165+ target.bug_supervisor = bug_supervisor
166
167 def test_submit_action_bug_supervisor(self):
168 # A bug supervisor sees the Nominate action label.
169
170=== modified file 'lib/lp/bugs/browser/tests/test_bugsupervisor.py'
171--- lib/lp/bugs/browser/tests/test_bugsupervisor.py 2012-08-14 23:27:07 +0000
172+++ lib/lp/bugs/browser/tests/test_bugsupervisor.py 2012-08-16 12:16:23 +0000
173@@ -1,11 +1,10 @@
174-# Copyright 2010 Canonical Ltd. This software is licensed under the
175+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
176 # GNU Affero General Public License version (see the file LICENSE).
177
178 """Unit tests for bug supervisor views."""
179
180 __metaclass__ = type
181
182-from zope.app.form.interfaces import ConversionError
183 from zope.component import getUtility
184
185 from lp.bugs.browser.bugsupervisor import BugSupervisorEditSchema
186@@ -14,7 +13,6 @@
187 from lp.services.webapp.publisher import canonical_url
188 from lp.testing import (
189 BrowserTestCase,
190- login,
191 login_person,
192 TestCaseWithFactory,
193 )
194@@ -70,14 +68,11 @@
195 self.assertEqual(self.product.bug_supervisor, self.owner)
196 notifications = view.request.response.notifications
197 self.assertEqual(1, len(notifications))
198- expected = (
199- 'A bug mail subscription was created for the bug supervisor. '
200- 'You can <a href="http://launchpad.dev/boing/+subscriptions">'
201- 'edit bug mail</a> to change which notifications will be sent.')
202+ expected = 'Bug supervisor privilege granted.'
203 self.assertEqual(expected, notifications.pop().message)
204
205 def test_owner_appoint_self_from_another(self):
206- self.product.setBugSupervisor(self.team, self.owner)
207+ self.product.bug_supervisor = self.team
208 form = self._makeForm(self.owner)
209 view = create_initialized_view(
210 self.product, name='+bugsupervisor', form=form)
211@@ -85,7 +80,7 @@
212 self.assertEqual(self.owner, self.product.bug_supervisor)
213
214 def test_owner_appoint_none(self):
215- self.product.setBugSupervisor(self.owner, self.owner)
216+ self.product.bug_supervisor = self.owner
217 form = self._makeForm(None)
218 view = create_initialized_view(
219 self.product, name='+bugsupervisor', form=form)
220@@ -115,77 +110,6 @@
221 self.assertEqual([], view.errors)
222 self.assertEqual(private_team, self.product.bug_supervisor)
223
224- def test_owner_cannot_appoint_another_team(self):
225- team = self.factory.makeTeam(name='smack', displayname='<smack />')
226- form = self._makeForm(team)
227- view = create_initialized_view(
228- self.product, name='+bugsupervisor', form=form)
229- self.assertEqual(1, len(view.errors))
230- expected = (
231- 'You cannot set &lt;smack /&gt; as the bug supervisor for '
232- '&lt;boing /&gt; because you are not an administrator of that '
233- 'team.<br />If you believe that &lt;smack /&gt; should be the '
234- 'bug supervisor for &lt;boing /&gt;, notify one of the '
235- '<a href="http://launchpad.dev/~smack/+members">&lt;smack /&gt; '
236- 'administrators</a>. See '
237- '<a href="https://help.launchpad.net/BugSupervisors">the '
238- 'help wiki</a> for information about setting a bug supervisor.')
239- self.assertEqual(expected, view.errors.pop())
240-
241- def test_owner_cannot_appoint_a_nonvalid_user(self):
242- # The vocabulary only accepts valid users.
243- form = self._makeForm(None)
244- form['field.bug_supervisor'] = 'fnord'
245- view = create_initialized_view(
246- self.product, name='+bugsupervisor', form=form)
247- self.assertEqual(2, len(view.errors))
248- expected = (
249- 'You must choose a valid person or team to be the bug supervisor '
250- 'for &lt;boing /&gt;.')
251- self.assertEqual(expected, view.errors.pop())
252- self.assertTrue(isinstance(view.errors.pop(), ConversionError))
253-
254- def test_owner_cannot_appoint_another_user(self):
255- another_user = self.factory.makePerson()
256- form = self._makeForm(another_user)
257- view = create_initialized_view(
258- self.product, name='+bugsupervisor', form=form)
259- self.assertEqual(1, len(view.errors))
260- expected = (
261- 'You cannot set another person as the bug supervisor for '
262- '&lt;boing /&gt;.<br />See '
263- '<a href="https://help.launchpad.net/BugSupervisors">the help '
264- 'wiki</a> for information about setting a bug supervisor.')
265- self.assertEqual(expected, view.errors.pop())
266-
267- def test_admin_appoint_another_user(self):
268- another_user = self.factory.makePerson()
269- login('admin@canonical.com')
270- form = self._makeForm(another_user)
271- view = create_initialized_view(
272- self.product, name='+bugsupervisor', form=form)
273- self.assertEqual([], view.errors)
274- self.assertEqual(another_user, self.product.bug_supervisor)
275-
276- def test_admin_appoint_another_team(self):
277- another_team = self.factory.makeTeam()
278- login('admin@canonical.com')
279- form = self._makeForm(another_team)
280- view = create_initialized_view(
281- self.product, name='+bugsupervisor', form=form)
282- self.assertEqual([], view.errors)
283- self.assertEqual(another_team, self.product.bug_supervisor)
284-
285- def test_admin_appoint_private_team(self):
286- private_team = self.factory.makeTeam(
287- visibility=PersonVisibility.PRIVATE)
288- login('admin@canonical.com')
289- form = self._makeForm(private_team)
290- view = create_initialized_view(
291- self.product, name='+bugsupervisor', form=form)
292- self.assertEqual([], view.errors)
293- self.assertEqual(private_team, self.product.bug_supervisor)
294-
295
296 class TestBugSupervisorLink(BrowserTestCase):
297
298
299=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_configure.py'
300--- lib/lp/bugs/browser/tests/test_bugtarget_configure.py 2012-08-13 19:34:10 +0000
301+++ lib/lp/bugs/browser/tests/test_bugtarget_configure.py 2012-08-16 12:16:23 +0000
302@@ -1,4 +1,4 @@
303-# Copyright 2010 Canonical Ltd. This software is licensed under the
304+# Copyright 2010-2012 Canonical Ltd. This software is licensed under the
305 # GNU Affero General Public License version (see the file LICENSE).
306
307 """Unit tests for bug configuration views."""
308@@ -92,17 +92,6 @@
309 self.product.bug_reported_acknowledgement)
310 self.assertFalse(self.product.enable_bugfiling_duplicate_search)
311
312- def test_bug_supervisor_invalid(self):
313- # Verify that invalid bug_supervisor states are reported.
314- # This is a sanity check. The bug_supervisor is rigorously tested
315- # in its own test.
316- other_person = self.factory.makePerson()
317- form = self._makeForm()
318- form['field.bug_supervisor'] = other_person.name
319- view = create_initialized_view(
320- self.product, name='+configure-bugtracker', form=form)
321- self.assertEqual(1, len(view.errors))
322-
323 def test_security_contact_invalid(self):
324 # Verify that invalid security_contact states are reported.
325 # This is a sanity check. The security_contact is rigorously tested
326@@ -163,7 +152,7 @@
327 owning_team.addMember(weak_owner, self.owner)
328 bug_team.addMember(weak_owner, self.owner)
329 self.product.owner = owning_team
330- self.product.setBugSupervisor(bug_team, self.owner)
331+ self.product.bug_supervisor = bug_team
332 self.product.security_contact = bug_team
333 login_person(weak_owner)
334 form = self._makeForm()
335
336=== modified file 'lib/lp/bugs/browser/tests/test_bugtask.py'
337--- lib/lp/bugs/browser/tests/test_bugtask.py 2012-08-08 11:48:29 +0000
338+++ lib/lp/bugs/browser/tests/test_bugtask.py 2012-08-16 12:16:23 +0000
339@@ -251,13 +251,10 @@
340 # and will instead receive an error in the UI.
341 person = self.factory.makePerson()
342 product = self.factory.makeProduct(
343- name='product1', owner=person, official_malone=True)
344- with person_logged_in(person):
345- product.setBugSupervisor(person, person)
346+ name='product1', owner=person, official_malone=True,
347+ bug_supervisor=person)
348 product_2 = self.factory.makeProduct(
349 name='product2', official_malone=True)
350- with person_logged_in(product_2.owner):
351- product_2.setBugSupervisor(product_2.owner, product_2.owner)
352 bug = self.factory.makeBug(target=product, owner=person)
353 # We need to commit here, otherwise all the sample data we
354 # created gets destroyed when the transaction is rolled back.
355@@ -1241,7 +1238,7 @@
356 # For regular users, the assignee vocabulary is
357 # AllUserTeamsParticipation if there is a bug supervisor defined.
358 login_person(self.owner)
359- self.product.setBugSupervisor(self.owner, self.owner)
360+ self.product.bug_supervisor = self.owner
361 login(USER_EMAIL)
362 view = BugTaskEditView(self.bugtask, LaunchpadTestRequest())
363 view.initialize()
364@@ -1253,7 +1250,7 @@
365 # For regular users, the assignee vocabulary is
366 # ValidAssignee is there is not a bug supervisor defined.
367 login_person(self.owner)
368- self.product.setBugSupervisor(None, self.owner)
369+ self.product.bug_supervisor = None
370 login(USER_EMAIL)
371 view = BugTaskEditView(self.bugtask, LaunchpadTestRequest())
372 view.initialize()
373
374=== modified file 'lib/lp/bugs/browser/tests/test_expose.py'
375--- lib/lp/bugs/browser/tests/test_expose.py 2012-03-18 01:29:07 +0000
376+++ lib/lp/bugs/browser/tests/test_expose.py 2012-08-16 12:16:23 +0000
377@@ -262,8 +262,7 @@
378 context = self.factory.makeDistribution(
379 owner=self.user, members=self.bug_super_team)
380 with person_logged_in(self.user):
381- context.setBugSupervisor(
382- self.bug_super_team, self.user)
383+ context.bug_supervisor = self.bug_super_team
384
385 expose_user_administered_teams_to_js(self.request, self.user, context,
386 absoluteURL=fake_absoluteURL)
387
388=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
389--- lib/lp/bugs/doc/bugsubscription.txt 2012-08-07 13:50:53 +0000
390+++ lib/lp/bugs/doc/bugsubscription.txt 2012-08-16 12:16:23 +0000
391@@ -172,17 +172,15 @@
392
393 >>> ubuntu_team = personset.getByName("ubuntu-team")
394
395- >>> linux_source.distribution.setBugSupervisor(ubuntu_team, ubuntu_team)
396+ >>> linux_source.distribution.bug_supervisor = ubuntu_team
397
398 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
399 No Privileges Person
400 Sample Person
401- Ubuntu Team
402
403 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
404 No Privileges Person
405 Sample Person
406- Ubuntu Team
407
408 After adding a product bugtask we can see that the upstream bug
409 supervisor is also an indirect subscriber.
410@@ -195,36 +193,28 @@
411 <BugTask ...>
412
413 >>> lifeless = personset.getByName("lifeless")
414- >>> firefox.setBugSupervisor(lifeless, lifeless)
415+ >>> firefox.bug_supervisor = lifeless
416
417 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
418 No Privileges Person
419- Robert Collins
420 Sample Person
421- Ubuntu Team
422
423 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
424 No Privileges Person
425- Robert Collins
426 Sample Person
427- Ubuntu Team
428
429 If there were no upstream product bug subscribers, the product owner
430 would be used instead.
431
432- >>> firefox.setBugSupervisor(None, None)
433+ >>> firefox.bug_supervisor = None
434
435 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
436 No Privileges Person
437- Robert Collins
438 Sample Person
439- Ubuntu Team
440
441 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
442 No Privileges Person
443- Robert Collins
444 Sample Person
445- Ubuntu Team
446
447 >>> previous_owner = firefox.owner
448
449@@ -232,18 +222,14 @@
450
451 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
452 No Privileges Person
453- Robert Collins
454 Sample Person
455- Ubuntu Team
456
457 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
458 No Privileges Person
459- Robert Collins
460 Sample Person
461- Ubuntu Team
462
463 >>> firefox.owner = previous_owner
464- >>> firefox.setBugSupervisor(lifeless, lifeless)
465+ >>> firefox.bug_supervisor = lifeless
466
467 IBug.getAlsoNotifiedSubscribers() and IBug.getIndirectSubscribers() take
468 an optional parameter `level` allowing us to filter the result by
469@@ -267,30 +253,22 @@
470 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
471 ... level=BugNotificationLevel.COMMENTS))
472 No Privileges Person
473- Robert Collins
474 Sample Person
475- Ubuntu Team
476
477 >>> print_displayname(linux_source_bug.getIndirectSubscribers(
478 ... level=BugNotificationLevel.COMMENTS))
479 No Privileges Person
480- Robert Collins
481 Sample Person
482- Ubuntu Team
483
484 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
485 ... level=BugNotificationLevel.LIFECYCLE))
486 No Privileges Person
487- Robert Collins
488 Sample Person
489- Ubuntu Team
490
491 >>> print_displayname(linux_source_bug.getIndirectSubscribers(
492 ... level=BugNotificationLevel.LIFECYCLE))
493 No Privileges Person
494- Robert Collins
495 Sample Person
496- Ubuntu Team
497
498 If No Privileges Person created a single filter with a notification
499 level set to LIFECYCLE, he will not be included, if the parameter
500@@ -305,28 +283,20 @@
501 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
502 ... level=BugNotificationLevel.LIFECYCLE))
503 No Privileges Person
504- Robert Collins
505 Sample Person
506- Ubuntu Team
507
508 >>> print_displayname(linux_source_bug.getIndirectSubscribers(
509 ... level=BugNotificationLevel.LIFECYCLE))
510 No Privileges Person
511- Robert Collins
512 Sample Person
513- Ubuntu Team
514
515 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers(
516 ... level=BugNotificationLevel.METADATA))
517- Robert Collins
518 Sample Person
519- Ubuntu Team
520
521 >>> print_displayname(linux_source_bug.getIndirectSubscribers(
522 ... level=BugNotificationLevel.METADATA))
523- Robert Collins
524 Sample Person
525- Ubuntu Team
526
527 3. Direct subscribers of duplicate bugs.
528
529@@ -351,16 +321,13 @@
530 >>> print_displayname(linux_source_bug_dupe.getIndirectSubscribers())
531 No Privileges Person
532 Stuart Bishop
533- Ubuntu Team
534
535 >>> linux_source_bug_dupe.markAsDuplicate(linux_source_bug)
536
537 >>> print_displayname(linux_source_bug.getIndirectSubscribers())
538 No Privileges Person
539- Robert Collins
540 Sample Person
541 Scott James Remnant
542- Ubuntu Team
543
544 >>> print_displayname(linux_source_bug.getSubscribersFromDuplicates())
545 Scott James Remnant
546@@ -369,8 +336,7 @@
547 he will no longer appear in the list of subscribers of the duplicate
548 bug.
549
550- >>> subscription_keybuk = linux_source.addBugSubscription(
551- ... keybuk, keybuk)
552+ >>> subscription_keybuk = linux_source.addBugSubscription(keybuk, keybuk)
553 >>> linux_source_bug.getSubscribersFromDuplicates()
554 ()
555
556@@ -415,13 +381,11 @@
557 No Privileges Person
558 Sample Person
559 Scott James Remnant
560- Ubuntu Team
561
562 >>> print_displayname(linux_source_bug.getAlsoNotifiedSubscribers())
563 No Privileges Person
564 Sample Person
565 Scott James Remnant
566- Ubuntu Team
567
568 To find out which email addresses should receive a notification email on
569 a bug, and why, IBug.getBugNotificationRecipients() assembles an
570@@ -436,7 +400,6 @@
571 [('foo.bar@canonical.com', 'Subscriber'),
572 ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
573 ('robertc@robertcollins.net', 'Subscriber'),
574- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
575 ('test@canonical.com', 'Assignee')]
576
577 If IBug.getBugNotificationRecipients() is passed a BugNotificationLevel
578@@ -449,7 +412,6 @@
579 >>> [(address, recipients.getReason(address)[1]) for address in addresses]
580 [('foo.bar@canonical.com', 'Subscriber'),
581 ('robertc@robertcollins.net', 'Subscriber'),
582- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
583 ('test@canonical.com', 'Assignee')]
584
585 When Sample Person is unsubscribed from linux_source_bug, he is no
586@@ -463,7 +425,6 @@
587 >>> [(address, recipients.getReason(address)[1]) for address in addresses]
588 [('foo.bar@canonical.com', 'Subscriber'),
589 ('robertc@robertcollins.net', 'Subscriber'),
590- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
591 ('test@canonical.com', 'Assignee')]
592
593 ...but remains included for the level LIFECYCLE.
594@@ -476,7 +437,6 @@
595 [('foo.bar@canonical.com', 'Subscriber'),
596 ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in Ubuntu)'),
597 ('robertc@robertcollins.net', 'Subscriber'),
598- ('support@ubuntu.com', u'Subscriber (Ubuntu) @ubuntu-team'),
599 ('test@canonical.com', 'Assignee')]
600
601 To find out if someone is already directly subscribed to a bug, call
602@@ -646,7 +606,7 @@
603
604 Let's have a look at an example for a distribution bug:
605
606- >>> ubuntu.setBugSupervisor(sample_person, sample_person)
607+ >>> ubuntu.bug_supervisor = sample_person
608
609 >>> params = CreateBugParams(
610 ... title="a test bug", comment="a test description",
611@@ -663,7 +623,7 @@
612 will be implicitly added to the notification recipients.
613
614 >>> getSubscribers(new_bug)
615- ['foo.bar@canonical.com', 'support@ubuntu.com', 'test@canonical.com']
616+ ['foo.bar@canonical.com']
617
618 The distro contact will also be subscribed to private bugs, because
619 there is no security contact:
620@@ -693,7 +653,7 @@
621
622 Another example, this time for an upstream:
623
624- >>> firefox.setBugSupervisor(mark, mark)
625+ >>> firefox.bug_supervisor = mark
626
627 >>> params = CreateBugParams(
628 ... title="a test bug", comment="a test description",
629@@ -710,7 +670,7 @@
630 recipients list.
631
632 >>> getSubscribers(new_bug)
633- ['foo.bar@canonical.com', 'mark@example.com', 'robertc@robertcollins.net']
634+ ['foo.bar@canonical.com']
635
636 If we create a bug task on Ubuntu in the same bug, the Ubuntu bug
637 supervisor will be subscribed:
638@@ -720,10 +680,6 @@
639
640 >>> print '\n'.join(getSubscribers(new_bug))
641 foo.bar@canonical.com
642- mark@example.com
643- robertc@robertcollins.net
644- support@ubuntu.com
645- test@canonical.com
646
647 But still, only Foo Bar is explicitly subscribed.
648
649@@ -735,7 +691,7 @@
650 product.owner is used instead. So, if Firefox's bug supervisor is unset,
651 Sample Person, the Firefox "owner" will get subscribed instead:
652
653- >>> firefox.setBugSupervisor(None, None)
654+ >>> firefox.bug_supervisor = None
655
656 >>> params = CreateBugParams(
657 ... title="a test bug", comment="a test description",
658@@ -753,8 +709,6 @@
659
660 >>> print '\n'.join(getSubscribers(new_bug))
661 foo.bar@canonical.com
662- mark@example.com
663- robertc@robertcollins.net
664
665 The upstream maintainer will be subscribed to security-related private
666 bugs, because upstream has no security contact, in this case.
667@@ -769,8 +723,6 @@
668
669 >>> print '\n'.join(getSubscribers(new_bug))
670 foo.bar@canonical.com
671- mark@example.com
672- robertc@robertcollins.net
673 test@canonical.com
674
675 Now let's create a bug on a specific package, which has no package bug
676@@ -787,7 +739,7 @@
677 >>> new_bug = evolution.createBug(params)
678
679 >>> getSubscribers(new_bug)
680- ['foo.bar@canonical.com', 'support@ubuntu.com', 'test@canonical.com']
681+ ['foo.bar@canonical.com']
682
683 Adding a package bug contact for evolution will mean that that package
684 bug contact gets implicitly subscribed to all bugs ever opened on that
685@@ -807,7 +759,7 @@
686 [u'Foo Bar']
687
688 >>> getSubscribers(new_bug)
689- ['foo.bar@canonical.com', 'support@ubuntu.com', 'test@canonical.com']
690+ ['foo.bar@canonical.com', 'support@ubuntu.com']
691
692 And the Ubuntu team will be implicitly subscribed to future bugs:
693
694@@ -822,7 +774,7 @@
695 [u'Foo Bar']
696
697 >>> getSubscribers(new_bug)
698- ['foo.bar@canonical.com', 'support@ubuntu.com', 'test@canonical.com']
699+ ['foo.bar@canonical.com', 'support@ubuntu.com']
700
701 The distribution maintainer, Ubuntu Team, gets subscribed to the private
702 security bug filed on a package, because Ubuntu has no security contact:
703
704=== modified file 'lib/lp/bugs/doc/bugtask-search.txt'
705--- lib/lp/bugs/doc/bugtask-search.txt 2012-08-08 11:48:29 +0000
706+++ lib/lp/bugs/doc/bugtask-search.txt 2012-08-16 12:16:23 +0000
707@@ -96,7 +96,7 @@
708 bugs return all of Firefox's bugs.
709
710 >>> login('foo.bar@canonical.com')
711- >>> firefox.setBugSupervisor(no_priv, no_priv)
712+ >>> firefox.bug_supervisor = no_priv
713
714 >>> found_bugtasks = bugtask_set.search(no_priv_bug_supervisor)
715 >>> found_bugtasks.count() == firefox_bugs.count()
716@@ -121,7 +121,7 @@
717 >>> ubuntu_bugs.count() > 0
718 True
719
720- >>> ubuntu.setBugSupervisor(no_priv, no_priv)
721+ >>> ubuntu.bug_supervisor = no_priv
722 >>> found_bugtasks = bugtask_set.search(no_priv_bug_supervisor)
723 >>> found_bugtasks.count() == firefox_bugs.count() + ubuntu_bugs.count()
724 True
725
726=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
727--- lib/lp/bugs/doc/initial-bug-contacts.txt 2012-05-22 12:05:51 +0000
728+++ lib/lp/bugs/doc/initial-bug-contacts.txt 2012-08-16 12:16:23 +0000
729@@ -301,12 +301,7 @@
730
731 >>> mozilla_firefox = getUtility(IProductSet).get(4)
732
733-Let's make Foo Bar a bug supervisor for upstream firefox:
734-
735- >>> mozilla_firefox.setBugSupervisor(foobar, foobar)
736-
737-Then we'll reassign bug #2 in Ubuntu to be in Firefox, noting that Foo
738-Bar gets subscribed to the bug in the process:
739+Then we'll reassign bug #2 in Ubuntu to be in Firefox:
740
741 >>> bug_two_in_ubuntu = getUtility(IBugTaskSet).get(3)
742 >>> print bug_two_in_ubuntu.bug.id
743@@ -330,46 +325,6 @@
744 >>> notify(product_changed)
745 >>> transaction.commit()
746
747-With the product changed, we can see that Foo Bar is now subscribed:
748-
749- >>> print '\n'.join(subscriber_names(bug_two_in_ubuntu.bug))
750- Foo Bar
751- Sample Person
752- Steve Alexander
753- Ubuntu Team
754-
755-And Foo Bar gets an email containing complete information about the bug
756-report. It states that he received the email because he is the bug
757-supervisor for Mozilla Firefox.
758-
759- >>> test_emails = list(stub.test_emails)
760- >>> test_emails.sort(by_to_addrs)
761-
762- >>> len(test_emails)
763- 1
764-
765- >>> from_addr, to_addr, raw_message = test_emails.pop()
766- >>> print from_addr
767- bounces@canonical.com
768-
769- >>> print to_addr
770- ['foo.bar@canonical.com']
771-
772- >>> msg = email.message_from_string(raw_message)
773- >>> msg['Subject']
774- '[Bug 2] [NEW] Blackhole Trash folder'
775-
776- >>> print msg.get_payload(decode=True)
777- You have been subscribed to a public bug:
778- ...
779- ** Affects: firefox
780- ...
781- --
782- Blackhole Trash folder
783- http://bugs.launchpad.dev/bugs/2
784- You received this bug notification because you
785- are subscribed to Mozilla Firefox.
786-
787
788 Teams as bug supervisors
789 ------------------------
790
791=== modified file 'lib/lp/bugs/interfaces/bugsupervisor.py'
792--- lib/lp/bugs/interfaces/bugsupervisor.py 2011-12-24 16:54:44 +0000
793+++ lib/lp/bugs/interfaces/bugsupervisor.py 2012-08-16 12:16:23 +0000
794@@ -11,16 +11,7 @@
795 'IHasBugSupervisor',
796 ]
797
798-from lazr.restful.declarations import (
799- call_with,
800- export_write_operation,
801- exported,
802- mutator_for,
803- operation_for_version,
804- operation_parameters,
805- REQUEST_USER,
806- )
807-from lazr.restful.interface import copy_field
808+from lazr.restful.declarations import exported
809 from zope.interface import Interface
810
811 from lp import _
812@@ -33,16 +24,5 @@
813 title=_("Bug Supervisor"),
814 description=_(
815 "The Launchpad id of the person or team (preferred) responsible "
816- "for bug management. Mail about all bug activity will be sent to "
817- "the supervisor by default. The bug supervisor can change the "
818- "bug mail rules to limit the volume of email."),
819- required=False, vocabulary='ValidPersonOrTeam', readonly=True))
820-
821- @mutator_for(bug_supervisor)
822- @call_with(user=REQUEST_USER)
823- @operation_parameters(
824- bug_supervisor=copy_field(bug_supervisor))
825- @export_write_operation()
826- @operation_for_version('beta')
827- def setBugSupervisor(bug_supervisor, user):
828- """Set the bug contact and create a bug subscription."""
829+ "for bug management."),
830+ required=False, vocabulary='ValidPersonOrTeam', readonly=False))
831
832=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
833--- lib/lp/bugs/interfaces/bugtask.py 2012-08-07 03:47:15 +0000
834+++ lib/lp/bugs/interfaces/bugtask.py 2012-08-16 12:16:23 +0000
835@@ -1,8 +1,6 @@
836-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
837+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
838 # GNU Affero General Public License version 3 (see the file LICENSE).
839
840-# pylint: disable-msg=E0211,E0213,E0602
841-
842 """Bug task interfaces."""
843
844 __metaclass__ = type
845@@ -785,7 +783,7 @@
846 """
847
848 def userHasDriverPrivileges(user):
849- """Does the user have driver privledges on the current bugtask?
850+ """Does the user have driver privileges on the current bugtask?
851
852 :return: A boolean.
853 """
854
855=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
856--- lib/lp/bugs/model/tests/test_bug.py 2012-08-08 11:48:29 +0000
857+++ lib/lp/bugs/model/tests/test_bug.py 2012-08-16 12:16:23 +0000
858@@ -9,7 +9,6 @@
859 )
860
861 from pytz import UTC
862-from storm.expr import Join
863 from storm.store import Store
864 from testtools.testcase import ExpectedException
865 from zope.component import getUtility
866@@ -29,7 +28,6 @@
867 BugNotification,
868 BugSubscriptionInfo,
869 )
870-from lp.bugs.model.bugnotification import BugNotificationRecipient
871 from lp.registry.enums import InformationType
872 from lp.registry.interfaces.accesspolicy import (
873 IAccessArtifactSource,
874@@ -940,10 +938,8 @@
875 # This is to protect ubuntu's workflow, which differs from the
876 # Launchpad norm.
877 ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
878- admin = getUtility(ILaunchpadCelebrities).admin
879 ubuntu = removeSecurityProxy(ubuntu)
880- ubuntu.setBugSupervisor(
881- self.factory.makePerson(name='supervisor'), admin)
882+ ubuntu.bug_supervisor = self.factory.makePerson(name='supervisor')
883 bug = self.factory.makeBug(
884 information_type=InformationType.PRIVATESECURITY,
885 target=ubuntu)
886@@ -954,7 +950,7 @@
887 InformationType.USERDATA, who=bug.owner)
888 subscribers = bug.getDirectSubscribers()
889 self.assertContentEqual(initial_subscribers, subscribers)
890- ubuntu.setBugSupervisor(None, ubuntu.owner)
891+ ubuntu.bug_supervisor = None
892
893
894 class TestBugActivityMethods(TestCaseWithFactory):
895
896=== modified file 'lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py'
897--- lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2012-08-08 07:22:51 +0000
898+++ lib/lp/bugs/model/tests/test_bugsubscriptioninfo.py 2012-08-16 12:16:23 +0000
899@@ -371,7 +371,7 @@
900 bugtask.transitionToAssignee(assignee)
901 supervisor = self.factory.makePerson()
902 with person_logged_in(bugtask.target.owner):
903- bugtask.target.setBugSupervisor(supervisor, supervisor)
904+ bugtask.target.bug_supervisor = supervisor
905 structural_subscriber = self.factory.makePerson()
906 with person_logged_in(structural_subscriber):
907 bugtask.target.addSubscription(
908@@ -392,8 +392,7 @@
909 # the assignee, supervisor and structural subscriber do.
910 found_subscribers = self.getInfo().also_notified_subscribers
911 self.assertContentEqual(
912- [assignee, supervisor, structural_subscriber],
913- found_subscribers)
914+ [assignee, structural_subscriber], found_subscribers)
915
916 def test_also_notified_subscribers_muted(self):
917 # If someone is muted, they are not listed in the
918@@ -405,13 +404,10 @@
919 # when they are not muted.
920 found_subscribers = self.getInfo().also_notified_subscribers
921 self.assertContentEqual(
922- [assignee, supervisor, structural_subscriber],
923- found_subscribers)
924+ [assignee, structural_subscriber], found_subscribers)
925 # Now we mute all of the subscribers.
926 with person_logged_in(assignee):
927 self.bug.mute(assignee, assignee)
928- with person_logged_in(supervisor):
929- self.bug.mute(supervisor, supervisor)
930 with person_logged_in(structural_subscriber):
931 self.bug.mute(structural_subscriber, structural_subscriber)
932 # Now we don't see them.
933
934=== modified file 'lib/lp/bugs/model/tests/test_bugtask.py'
935--- lib/lp/bugs/model/tests/test_bugtask.py 2012-08-14 23:27:07 +0000
936+++ lib/lp/bugs/model/tests/test_bugtask.py 2012-08-16 12:16:23 +0000
937@@ -934,13 +934,10 @@
938
939 def _setBugSupervisorData(self):
940 """Helper function used by sub-classes to setup bug supervisors."""
941+ self.supervisor_member = self.factory.makePerson()
942 self.supervisor_team = self.factory.makeTeam(
943- owner=self.target_owner_member)
944- self.supervisor_member = self.factory.makePerson()
945- self.supervisor_team.addMember(
946- self.supervisor_member, self.target_owner_member)
947- self.target.setBugSupervisor(
948- self.supervisor_team, self.target_owner_member)
949+ owner=self.target_owner_member, members=[self.supervisor_member])
950+ self.target.bug_supervisor = self.supervisor_team
951
952 def _setBugSupervisorDataNone(self):
953 """Helper for sub-classes to work around setting a bug supervisor."""
954@@ -3199,10 +3196,8 @@
955
956 def test_pillar_bug_supervisor(self):
957 # The pillar bug supervisor has privileges.
958- pillar = self.factory.makeProduct()
959 bugsupervisor = self.factory.makePerson()
960- removeSecurityProxy(pillar).setBugSupervisor(
961- bugsupervisor, self.celebrities.admin)
962+ pillar = self.factory.makeProduct(bug_supervisor=bugsupervisor)
963 bugtask = self.factory.makeBugTask(target=pillar)
964 self.assertTrue(
965 bugtask.userHasBugSupervisorPrivileges(bugsupervisor))
966
967=== modified file 'lib/lp/bugs/model/tests/test_bugtask_status.py'
968--- lib/lp/bugs/model/tests/test_bugtask_status.py 2012-08-13 19:34:10 +0000
969+++ lib/lp/bugs/model/tests/test_bugtask_status.py 2012-08-16 12:16:23 +0000
970@@ -386,10 +386,9 @@
971 def makePersonAndTask(self):
972 self.owner = self.factory.makePerson()
973 self.person = self.factory.makePerson()
974- self.product = self.factory.makeProduct(owner=self.owner)
975+ self.product = self.factory.makeProduct(
976+ owner=self.owner, bug_supervisor=self.person)
977 self.task = self.factory.makeBugTask(target=self.product)
978- with person_logged_in(self.owner):
979- self.product.setBugSupervisor(self.person, self.person)
980
981
982 class TestBugTaskStatusTransitionBugSupervisorTeamMember(
983@@ -400,10 +399,9 @@
984 self.owner = self.factory.makePerson()
985 self.person = self.factory.makePerson()
986 self.team = self.factory.makeTeam(members=[self.person])
987- self.product = self.factory.makeProduct(owner=self.owner)
988+ self.product = self.factory.makeProduct(
989+ owner=self.owner, bug_supervisor=self.team)
990 self.task = self.factory.makeBugTask(target=self.product)
991- with person_logged_in(self.owner):
992- self.product.setBugSupervisor(self.team, self.team)
993
994
995 class TestBugTaskStatusTransitionBugWatchUpdater(
996
997=== modified file 'lib/lp/bugs/model/tests/test_bugtasksearch.py'
998--- lib/lp/bugs/model/tests/test_bugtasksearch.py 2012-08-08 11:48:29 +0000
999+++ lib/lp/bugs/model/tests/test_bugtasksearch.py 2012-08-16 12:16:23 +0000
1000@@ -936,7 +936,7 @@
1001 def setSupervisor(self, supervisor):
1002 """Set the bug supervisor for the bug task target."""
1003 with person_logged_in(self.owner):
1004- self.searchtarget.setBugSupervisor(supervisor, self.owner)
1005+ self.searchtarget.bug_supervisor = supervisor
1006
1007
1008 class ProductTarget(BugTargetTestBase, ProductAndDistributionTests,
1009@@ -1103,7 +1103,7 @@
1010 with person_logged_in(self.owner):
1011 # We must set the bug supervisor for each bug task target
1012 for bugtask in self.bugtasks:
1013- bugtask.target.setBugSupervisor(supervisor, self.owner)
1014+ bugtask.target.bug_supervisor = supervisor
1015
1016 def findBugtaskForOtherProduct(self, bugtask):
1017 # Return the bugtask for the product that not related to the
1018@@ -1613,8 +1613,7 @@
1019 def setSupervisor(self, supervisor):
1020 """Set the bug supervisor for the bug task target."""
1021 with person_logged_in(self.owner):
1022- self.searchtarget.distribution.setBugSupervisor(
1023- supervisor, self.owner)
1024+ self.searchtarget.distribution.bug_supervisor = supervisor
1025
1026 def targetToGroup(self, target):
1027 return target.sourcepackagename.id
1028
1029=== modified file 'lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt'
1030--- lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt 2012-07-07 21:44:45 +0000
1031+++ lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt 2012-08-16 12:16:23 +0000
1032@@ -54,7 +54,7 @@
1033 For a product bug supervisor.
1034
1035 >>> login("foo.bar@canonical.com")
1036- >>> firefox.setBugSupervisor(no_priv, no_priv)
1037+ >>> firefox.bug_supervisor = no_priv
1038 >>> user_sees_importance_widget(
1039 ... user=no_priv,
1040 ... url="http://bugs.launchpad.dev/firefox/+bug/1/+editstatus")
1041@@ -77,7 +77,7 @@
1042 he can no longer see the widget.
1043
1044 >>> login("foo.bar@canonical.com")
1045- >>> firefox.setBugSupervisor(None, None)
1046+ >>> firefox.bug_supervisor = None
1047 >>> user_sees_importance_widget(
1048 ... user=no_priv,
1049 ... url="http://bugs.launchpad.dev/firefox/+bug/1/+editstatus")
1050@@ -86,7 +86,7 @@
1051 For a distribution bug supervisor.
1052
1053 >>> login("foo.bar@canonical.com")
1054- >>> ubuntu.setBugSupervisor(no_priv, no_priv)
1055+ >>> ubuntu.bug_supervisor = no_priv
1056 >>> user_sees_importance_widget(
1057 ... user=no_priv,
1058 ... url='http://bugs.launchpad.dev/'
1059@@ -108,7 +108,7 @@
1060 For someone else, on Ubuntu.
1061
1062 >>> login("foo.bar@canonical.com")
1063- >>> ubuntu.setBugSupervisor(None, None)
1064+ >>> ubuntu.bug_supervisor = None
1065 >>> user_sees_importance_widget(
1066 ... user=no_priv,
1067 ... url='http://bugs.launchpad.dev/'
1068
1069=== modified file 'lib/lp/bugs/stories/bugtask-management/xx-change-assignee.txt'
1070--- lib/lp/bugs/stories/bugtask-management/xx-change-assignee.txt 2012-01-06 17:13:25 +0000
1071+++ lib/lp/bugs/stories/bugtask-management/xx-change-assignee.txt 2012-08-16 12:16:23 +0000
1072@@ -104,7 +104,7 @@
1073 >>> from lp.registry.interfaces.product import IProductSet
1074 >>> jokosher = getUtility(IProductSet).getByName('jokosher')
1075 >>> foobar = getUtility(IPersonSet).getByName('name16')
1076- >>> jokosher.setBugSupervisor(foobar, foobar)
1077+ >>> jokosher.bug_supervisor = foobar
1078
1079 To avoid any confusion, the option to assign somebody else is only
1080 shown if the user has sufficient privileges to assign anybody or if
1081
1082=== modified file 'lib/lp/bugs/stories/bugtask-management/xx-edit-email-address-bugtask.txt'
1083--- lib/lp/bugs/stories/bugtask-management/xx-edit-email-address-bugtask.txt 2011-12-24 15:18:32 +0000
1084+++ lib/lp/bugs/stories/bugtask-management/xx-edit-email-address-bugtask.txt 2012-08-16 12:16:23 +0000
1085@@ -86,7 +86,7 @@
1086 And the bug supervisor can't see the widgets either.
1087
1088 >>> login("foo.bar@canonical.com")
1089- >>> gnome_terminal.setBugSupervisor(no_priv, no_priv)
1090+ >>> gnome_terminal.bug_supervisor = no_priv
1091 >>> print_widget_visibility(
1092 ... user=no_priv,
1093 ... url=('http://bugs.launchpad.dev/'
1094@@ -149,7 +149,7 @@
1095 A bug supervisor can see both.
1096
1097 >>> login("foo.bar@canonical.com")
1098- >>> alsa_utils.setBugSupervisor(no_priv, no_priv)
1099+ >>> alsa_utils.bug_supervisor = no_priv
1100 >>> print_widget_visibility(
1101 ... user=no_priv,
1102 ... url=('http://bugs.launchpad.dev/'
1103
1104=== modified file 'lib/lp/bugs/stories/bugtask-management/xx-view-editable-bug-task.txt'
1105--- lib/lp/bugs/stories/bugtask-management/xx-view-editable-bug-task.txt 2011-12-30 06:14:56 +0000
1106+++ lib/lp/bugs/stories/bugtask-management/xx-view-editable-bug-task.txt 2012-08-16 12:16:23 +0000
1107@@ -20,7 +20,7 @@
1108 >>> firefox = IMasterObject(getUtility(IProductSet).getByName("firefox"))
1109 >>> sample_person = IMasterObject(
1110 ... getUtility(IPersonSet).getByName("name12"))
1111- >>> firefox.setBugSupervisor(sample_person, sample_person)
1112+ >>> firefox.bug_supervisor = sample_person
1113
1114 >>> flush_database_updates()
1115
1116
1117=== modified file 'lib/lp/bugs/stories/guided-filebug/xx-ubuntu-filebug.txt'
1118--- lib/lp/bugs/stories/guided-filebug/xx-ubuntu-filebug.txt 2012-03-06 11:20:54 +0000
1119+++ lib/lp/bugs/stories/guided-filebug/xx-ubuntu-filebug.txt 2012-08-16 12:16:23 +0000
1120@@ -52,7 +52,7 @@
1121 >>> login('foo.bar@canonical.com')
1122 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
1123 >>> foobar = getUtility(IPersonSet).getByName('name16')
1124- >>> ubuntu.setBugSupervisor(foobar, foobar)
1125+ >>> ubuntu.bug_supervisor = foobar
1126 >>> transaction.commit()
1127 >>> logout()
1128
1129
1130=== modified file 'lib/lp/bugs/tests/bugs-emailinterface.txt'
1131--- lib/lp/bugs/tests/bugs-emailinterface.txt 2012-07-27 01:15:04 +0000
1132+++ lib/lp/bugs/tests/bugs-emailinterface.txt 2012-08-16 12:16:23 +0000
1133@@ -1440,7 +1440,7 @@
1134
1135 >>> with lp_dbuser():
1136 ... login('foo.bar@canonical.com')
1137- ... upstream_task.pillar.setBugSupervisor(email_user, email_user)
1138+ ... upstream_task.pillar.bug_supervisor = email_user
1139
1140 >>> ignored = login_person(email_user)
1141
1142@@ -1459,7 +1459,7 @@
1143
1144 >>> with lp_dbuser():
1145 ... login('foo.bar@canonical.com')
1146- ... upstream_task.pillar.setBugSupervisor(None, None)
1147+ ... upstream_task.pillar.bug_supervisor = None
1148
1149 >>> login('no-priv@canonical.com')
1150
1151
1152=== removed file 'lib/lp/bugs/tests/has-bug-supervisor.txt'
1153--- lib/lp/bugs/tests/has-bug-supervisor.txt 2010-10-14 18:42:19 +0000
1154+++ lib/lp/bugs/tests/has-bug-supervisor.txt 1970-01-01 00:00:00 +0000
1155@@ -1,66 +0,0 @@
1156-= IHasBugSupervisor =
1157-
1158-Bug supervisors are people or teams who are responsible for dealing with
1159-bugs pertaining to a target. All objects with a bug supervisor are also
1160-structural subscription targets. When the bug supervisor for such an object
1161-is set, a new bug subscription is created as well.
1162-
1163- >>> list(target.bug_subscriptions)
1164- []
1165-
1166- >>> print target.bug_supervisor
1167- None
1168-
1169- >>> from lp.registry.interfaces.person import IPersonSet
1170- >>> personset = getUtility(IPersonSet)
1171- >>> no_priv = personset.getByEmail("no-priv@canonical.com")
1172- >>> foo_bar = personset.getByEmail("foo.bar@canonical.com")
1173-
1174- >>> login("foo.bar@canonical.com")
1175-
1176-We set no_priv as the bug supervisor for the target.
1177-
1178- >>> target.setBugSupervisor(no_priv, foo_bar)
1179-
1180-The bug supervisor can be retrieved using the `bug_supervisor` property.
1181-
1182- >>> print target.bug_supervisor.preferredemail.email
1183- no-priv@canonical.com
1184-
1185-But we can't use it to set the bug supervisor.
1186-
1187- >>> target.bug_supervisor = None
1188- Traceback (most recent call last):
1189- ...
1190- ForbiddenAttribute: ('bug_supervisor', <...>)
1191-
1192-After setting no_priv as the bug supervisor, a bug subscription is created
1193-for the target.
1194-
1195- >>> for bug_subscription in target.bug_subscriptions:
1196- ... print bug_subscription.subscriber.preferredemail.email
1197- no-priv@canonical.com
1198-
1199-And now no_priv is an indirect subscriber to any bug filed on
1200-the target.
1201-
1202- >>> bug = filebug(target, 'test bug')
1203- >>> no_priv in bug.getIndirectSubscribers()
1204- True
1205-
1206-If no_priv unsubscribes, he is still set as the bug supervisor.
1207-
1208- >>> target.removeBugSubscription(no_priv, no_priv)
1209- >>> print target.bug_supervisor.preferredemail.email
1210- no-priv@canonical.com
1211- >>> no_priv in bug.getIndirectSubscribers()
1212- False
1213-
1214-But we can remove the bug supervisor by setting it to None.
1215-
1216- >>> target.setBugSupervisor(None, None)
1217- >>> print target.bug_supervisor
1218- None
1219-
1220-Note that removing a person as a bug contact supervisor not remove their
1221-subscription to the target, if it exists.
1222
1223=== modified file 'lib/lp/bugs/tests/test_bug.py'
1224--- lib/lp/bugs/tests/test_bug.py 2012-08-15 02:30:46 +0000
1225+++ lib/lp/bugs/tests/test_bug.py 2012-08-16 12:16:23 +0000
1226@@ -292,7 +292,7 @@
1227 # canTransitionToAssignee() will return False for `person` if
1228 # another Person is passed as `assignee`.
1229 with person_logged_in(target.owner):
1230- target.setBugSupervisor(target.owner, target.owner)
1231+ target.bug_supervisor = target.owner
1232 with person_logged_in(person):
1233 params = CreateBugParams(
1234 owner=person, title="A bug", comment="Nothing important.",
1235
1236=== removed file 'lib/lp/bugs/tests/test_bugcontact.py'
1237--- lib/lp/bugs/tests/test_bugcontact.py 2012-06-06 16:04:34 +0000
1238+++ lib/lp/bugs/tests/test_bugcontact.py 1970-01-01 00:00:00 +0000
1239@@ -1,40 +0,0 @@
1240-# Copyright 2009 Canonical Ltd. This software is licensed under the
1241-# GNU Affero General Public License version 3 (see the file LICENSE).
1242-
1243-"""Test harness for running tests against IHasBugcontact
1244-implementations.
1245-"""
1246-
1247-import unittest
1248-
1249-from lp.bugs.tests.test_structuralsubscriptiontarget import (
1250- distributionSetUp,
1251- productSetUp,
1252- )
1253-from lp.testing.layers import DatabaseFunctionalLayer
1254-from lp.testing.systemdocs import (
1255- LayeredDocFileSuite,
1256- tearDown,
1257- )
1258-
1259-
1260-def test_suite():
1261- """Return the `IHasBugSupervisor` TestSuite."""
1262- suite = unittest.TestSuite()
1263-
1264- setUpMethods = [
1265- productSetUp,
1266- distributionSetUp,
1267- ]
1268-
1269- testname = 'has-bug-supervisor.txt'
1270- for setUpMethod in setUpMethods:
1271- id_ext = "%s-%s" % (testname, setUpMethod.func_name)
1272- test = LayeredDocFileSuite(
1273- testname,
1274- id_extensions=[id_ext],
1275- setUp=setUpMethod, tearDown=tearDown,
1276- layer=DatabaseFunctionalLayer)
1277- suite.addTest(test)
1278-
1279- return suite
1280
1281=== modified file 'lib/lp/bugs/tests/test_bugvisibility.py'
1282--- lib/lp/bugs/tests/test_bugvisibility.py 2012-08-08 11:48:29 +0000
1283+++ lib/lp/bugs/tests/test_bugvisibility.py 2012-08-16 12:16:23 +0000
1284@@ -50,9 +50,7 @@
1285 self.bug_team_member = self.factory.makePerson(name="bugteammember")
1286 with celebrity_logged_in('admin'):
1287 self.bug_team.addMember(self.bug_team_member, self.product.owner)
1288- self.product.setBugSupervisor(
1289- bug_supervisor=self.bug_team,
1290- user=self.product.owner)
1291+ self.product.bug_supervisor = self.bug_team
1292 self.bug = self.factory.makeBug(
1293 owner=self.owner, target=self.product,
1294 information_type=InformationType.USERDATA)
1295
1296=== modified file 'lib/lp/registry/browser/product.py'
1297--- lib/lp/registry/browser/product.py 2012-08-11 02:18:44 +0000
1298+++ lib/lp/registry/browser/product.py 2012-08-16 12:16:23 +0000
1299@@ -1,4 +1,4 @@
1300-# Copyright 2009-2011 Canonical Ltd. This software is licensed under the
1301+# Copyright 2009-2012 Canonical Ltd. This software is licensed under the
1302 # GNU Affero General Public License version 3 (see the file LICENSE).
1303
1304 """Browser views for products."""
1305@@ -114,7 +114,6 @@
1306 from lp.app.widgets.itemswidgets import (
1307 CheckBoxMatrixWidget,
1308 LaunchpadRadioWidget,
1309- LaunchpadRadioWidgetWithDescription,
1310 )
1311 from lp.app.widgets.popup import PersonPickerWidget
1312 from lp.app.widgets.product import (
1313@@ -612,8 +611,7 @@
1314 return Link('+branchvisibility', text, icon='edit')
1315
1316
1317-class ProductBugsMenu(PillarBugsMenu,
1318- ProductEditLinksMixin):
1319+class ProductBugsMenu(PillarBugsMenu, ProductEditLinksMixin):
1320
1321 usedfor = IProduct
1322 facet = 'bugs'
1323@@ -1543,10 +1541,7 @@
1324 else:
1325 return canonical_url(getUtility(IProductSet))
1326
1327- @property
1328- def cancel_url(self):
1329- """See `LaunchpadFormView`."""
1330- return self.next_url
1331+ cancel_url = next_url
1332
1333
1334 class ProductValidationMixin:
1335
1336=== modified file 'lib/lp/registry/browser/tests/test_edit_permissions.py'
1337--- lib/lp/registry/browser/tests/test_edit_permissions.py 2012-01-01 02:58:52 +0000
1338+++ lib/lp/registry/browser/tests/test_edit_permissions.py 2012-08-16 12:16:23 +0000
1339@@ -102,17 +102,15 @@
1340 def setupTarget(self):
1341 self.d_owner = self.factory.makePerson()
1342 login_person(self.d_owner)
1343- self.distro = self.factory.makeDistribution(name='youbuntu',
1344- owner=self.d_owner)
1345+ self.distro = self.factory.makeDistribution(
1346+ name='youbuntu', owner=self.d_owner)
1347 self.target = self.factory.makeDistributionSourcePackage(
1348 distribution=self.distro)
1349- self.supervisor_team = self.factory.makeTeam(
1350- owner=self.d_owner)
1351+ self.supervisor_team = self.factory.makeTeam(owner=self.d_owner)
1352 self.supervisor_member = self.factory.makePerson()
1353 self.supervisor_team.addMember(
1354 self.supervisor_member, self.d_owner)
1355- self.distro.setBugSupervisor(
1356- self.supervisor_team, self.d_owner)
1357+ self.distro.bug_supervisor = self.supervisor_team
1358
1359 def test_bug_supervisor_can_edit(self):
1360 login_person(self.supervisor_member)
1361
1362=== modified file 'lib/lp/registry/browser/tests/test_subscription_links.py'
1363--- lib/lp/registry/browser/tests/test_subscription_links.py 2012-06-04 16:13:51 +0000
1364+++ lib/lp/registry/browser/tests/test_subscription_links.py 2012-08-16 12:16:23 +0000
1365@@ -281,10 +281,7 @@
1366
1367 def test_subscribe_link_user_with_bug_super(self):
1368 with celebrity_logged_in('admin'):
1369- admin = getUtility(ILaunchBag).user
1370- supervisor = self.factory.makePerson()
1371- self.target.setBugSupervisor(
1372- supervisor, admin)
1373+ self.target.bug_supervisor = self.factory.makePerson()
1374 self._create_scenario(self.regular_user)
1375 self.assertLinksMissing()
1376
1377@@ -294,9 +291,7 @@
1378
1379 def test_subscribe_link_bug_super(self):
1380 with celebrity_logged_in('admin'):
1381- admin = getUtility(ILaunchBag).user
1382- self.target.setBugSupervisor(
1383- self.regular_user, admin)
1384+ self.target.bug_supervisor = self.regular_user
1385 self._create_scenario(self.regular_user)
1386 self.assertLinksPresent()
1387
1388@@ -322,10 +317,7 @@
1389
1390 def test_subscribe_link_user_with_bug_super(self):
1391 with celebrity_logged_in('admin'):
1392- admin = getUtility(ILaunchBag).user
1393- supervisor = self.factory.makePerson()
1394- self.target.setBugSupervisor(
1395- supervisor, admin)
1396+ self.target.bug_supervisor = self.factory.makePerson()
1397 self._create_scenario(self.regular_user)
1398 self.assertLinksMissing()
1399
1400@@ -335,9 +327,7 @@
1401
1402 def test_subscribe_link_bug_super(self):
1403 with celebrity_logged_in('admin'):
1404- admin = getUtility(ILaunchBag).user
1405- self.target.setBugSupervisor(
1406- self.regular_user, admin)
1407+ self.target.bug_supervisor = self.regular_user
1408 self._create_scenario(self.regular_user)
1409 self.assertLinksPresent()
1410
1411@@ -366,10 +356,7 @@
1412
1413 def test_subscribe_link_user_with_bug_super(self):
1414 with celebrity_logged_in('admin'):
1415- admin = getUtility(ILaunchBag).user
1416- supervisor = self.factory.makePerson()
1417- self.distro.setBugSupervisor(
1418- supervisor, admin)
1419+ self.distro.bug_supervisor = self.factory.makePerson()
1420 self._create_scenario(self.regular_user)
1421 self.assertLinksPresent()
1422
1423@@ -379,9 +366,7 @@
1424
1425 def test_subscribe_link_bug_super(self):
1426 with celebrity_logged_in('admin'):
1427- admin = getUtility(ILaunchBag).user
1428- self.distro.setBugSupervisor(
1429- self.regular_user, admin)
1430+ self.distro.bug_supervisor = self.regular_user
1431 self._create_scenario(self.regular_user)
1432 self.assertLinksPresent()
1433
1434@@ -561,9 +546,7 @@
1435
1436 def test_subscribe_link_bug_super(self):
1437 with celebrity_logged_in('admin'):
1438- admin = getUtility(ILaunchBag).user
1439- self.target.setBugSupervisor(
1440- self.regular_user, admin)
1441+ self.target.bug_supervisor = self.regular_user
1442 self._create_scenario(self.regular_user)
1443 self.assertLinksMissing()
1444
1445@@ -605,9 +588,7 @@
1446
1447 def test_subscribe_link_bug_super(self):
1448 with celebrity_logged_in('admin'):
1449- admin = getUtility(ILaunchBag).user
1450- self.distro.setBugSupervisor(
1451- self.regular_user, admin)
1452+ self.distro.bug_supervisor = self.regular_user
1453 self._create_scenario(self.regular_user)
1454 self.assertLinksMissing()
1455
1456@@ -631,10 +612,7 @@
1457
1458 def test_subscribe_link_user_with_bug_super(self):
1459 with celebrity_logged_in('admin'):
1460- admin = getUtility(ILaunchBag).user
1461- supervisor = self.factory.makePerson()
1462- self.distro.setBugSupervisor(
1463- supervisor, admin)
1464+ self.distro.bug_supervisor = self.factory.makePerson()
1465 self._create_scenario(self.regular_user)
1466 self.assertLinksMissing()
1467
1468
1469=== modified file 'lib/lp/registry/configure.zcml'
1470--- lib/lp/registry/configure.zcml 2012-08-10 06:40:08 +0000
1471+++ lib/lp/registry/configure.zcml 2012-08-16 12:16:23 +0000
1472@@ -1367,8 +1367,7 @@
1473 bug_supervisor"/>
1474 <require
1475 permission="launchpad.Edit"
1476- attributes="
1477- setBugSupervisor"/>
1478+ set_attributes="bug_supervisor"/>
1479 </class>
1480
1481 <!-- ProductWithLicenses
1482@@ -1642,8 +1641,7 @@
1483 bug_supervisor"/>
1484 <require
1485 permission="launchpad.Edit"
1486- attributes="
1487- setBugSupervisor"/>
1488+ set_attributes="bug_supervisor"/>
1489 </class>
1490 <adapter
1491 for="lp.registry.interfaces.distribution.IDistribution"
1492
1493=== modified file 'lib/lp/registry/doc/private-team-roles.txt'
1494--- lib/lp/registry/doc/private-team-roles.txt 2012-08-13 19:34:10 +0000
1495+++ lib/lp/registry/doc/private-team-roles.txt 2012-08-16 12:16:23 +0000
1496@@ -223,8 +223,8 @@
1497 A public team and a private team can be a project bug supervisor.
1498
1499 >>> product = factory.makeProduct()
1500- >>> product.setBugSupervisor(public_team, admin_user)
1501- >>> product.setBugSupervisor(priv_team, admin_user)
1502+ >>> product.bug_supervisor = public_team
1503+ >>> product.bug_supervisor = priv_team
1504
1505
1506 Product Series Roles
1507
1508=== modified file 'lib/lp/registry/interfaces/product.py'
1509--- lib/lp/registry/interfaces/product.py 2012-08-10 03:30:46 +0000
1510+++ lib/lp/registry/interfaces/product.py 2012-08-16 12:16:23 +0000
1511@@ -1,8 +1,6 @@
1512 # Copyright 2009-2012 Canonical Ltd. This software is licensed under the
1513 # GNU Affero General Public License version 3 (see the file LICENSE).
1514
1515-# pylint: disable-msg=E0211,E0213
1516-
1517 """Interfaces including and related to IProduct."""
1518
1519 __metaclass__ = type
1520
1521=== modified file 'lib/lp/registry/model/distribution.py'
1522--- lib/lp/registry/model/distribution.py 2012-08-08 05:36:44 +0000
1523+++ lib/lp/registry/model/distribution.py 2012-08-16 12:16:23 +0000
1524@@ -81,7 +81,6 @@
1525 DB_UNRESOLVED_BUGTASK_STATUSES,
1526 )
1527 from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask
1528-from lp.bugs.model.bug import BugSet
1529 from lp.bugs.model.bugtarget import (
1530 BugTargetBase,
1531 OfficialBugTagTargetMixin,
1532@@ -1578,12 +1577,6 @@
1533 bugs_with_upstream_patches))
1534 return results
1535
1536- def setBugSupervisor(self, bug_supervisor, user):
1537- """See `IHasBugSupervisor`."""
1538- self.bug_supervisor = bug_supervisor
1539- if bug_supervisor is not None:
1540- self.addBugSubscription(bug_supervisor, user)
1541-
1542 def getAllowedBugInformationTypes(self):
1543 """See `IDistribution.`"""
1544 types = set(InformationType.items)
1545
1546=== modified file 'lib/lp/registry/model/product.py'
1547--- lib/lp/registry/model/product.py 2012-08-10 06:39:58 +0000
1548+++ lib/lp/registry/model/product.py 2012-08-16 12:16:23 +0000
1549@@ -92,7 +92,6 @@
1550 from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
1551 from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
1552 from lp.bugs.interfaces.bugtaskfilter import OrderedBugTask
1553-from lp.bugs.model.bug import BugSet
1554 from lp.bugs.model.bugtarget import (
1555 BugTargetBase,
1556 OfficialBugTagTargetMixin,
1557@@ -1384,12 +1383,6 @@
1558 DistroSeries.distributionID == Distribution.id,
1559 ).config(distinct=True).order_by(Distribution.name)
1560
1561- def setBugSupervisor(self, bug_supervisor, user):
1562- """See `IHasBugSupervisor`."""
1563- self.bug_supervisor = bug_supervisor
1564- if bug_supervisor is not None:
1565- self.addBugSubscription(bug_supervisor, user)
1566-
1567 def composeCustomLanguageCodeMatch(self):
1568 """See `HasCustomLanguageCodesMixin`."""
1569 return CustomLanguageCode.product == self
1570
1571=== modified file 'lib/lp/registry/tests/test_product.py'
1572--- lib/lp/registry/tests/test_product.py 2012-08-14 23:27:07 +0000
1573+++ lib/lp/registry/tests/test_product.py 2012-08-16 12:16:23 +0000
1574@@ -59,7 +59,6 @@
1575 admin_logged_in,
1576 celebrity_logged_in,
1577 login,
1578- login_person,
1579 person_logged_in,
1580 TestCase,
1581 TestCaseWithFactory,
1582@@ -801,31 +800,6 @@
1583 self.assertThat(self.product, DoesNotSnapshot(omitted, IProduct))
1584
1585
1586-class BugSupervisorTestCase(TestCaseWithFactory):
1587- """A TestCase for bug supervisor management."""
1588-
1589- layer = DatabaseFunctionalLayer
1590-
1591- def setUp(self):
1592- super(BugSupervisorTestCase, self).setUp()
1593- self.person = self.factory.makePerson()
1594- self.product = self.factory.makeProduct(owner=self.person)
1595- login_person(self.person)
1596-
1597- def testPersonCanSetSelfAsSupervisor(self):
1598- # A person can set themselves as bug supervisor for a product.
1599- # This is a regression test for bug 438985.
1600- self.product.setBugSupervisor(
1601- bug_supervisor=self.person, user=self.person)
1602-
1603- self.assertEqual(
1604- self.product.bug_supervisor, self.person,
1605- "%s should be bug supervisor for %s. "
1606- "Instead, bug supervisor for firefox is %s" % (
1607- self.person.name, self.product.name,
1608- self.product.bug_supervisor.name))
1609-
1610-
1611 class TestProductTranslations(TestCaseWithFactory):
1612 """A TestCase for accessing product translations-related attributes."""
1613