Merge lp:~stevenk/launchpad/no-structsub-for-bug-supervisor into lp:launchpad
- no-structsub-for-bug-supervisor
- Merge into devel
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 | ||||||||
| Related bugs: |
|
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| William Grant | code | 2012-08-16 | Approve on 2012-08-16 |
|
Review via email:
|
|||
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.
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 <smack /> as the bug supervisor for ' |
| 232 | - '<boing /> because you are not an administrator of that ' |
| 233 | - 'team.<br />If you believe that <smack /> should be the ' |
| 234 | - 'bug supervisor for <boing />, notify one of the ' |
| 235 | - '<a href="http://launchpad.dev/~smack/+members"><smack /> ' |
| 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 <boing />.') |
| 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 | - '<boing />.<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 |

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: firefox. setBugSuperviso r(foobar, foobar) firefox. bug_supervisor = foobar
611
612 - >>> mozilla_
613 + >>> mozilla_
Is this bit necessary any more? The rest of the test looks like it was just testing notification.
1426 def testPersonCanSe tSelfAsSupervis or(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.