Merge lp:~stevenk/launchpad/destroy-old-bugactivity into lp:launchpad
- destroy-old-bugactivity
- Merge into devel
Proposed by
Steve Kowalik
on 2012-10-12
| Status: | Merged |
|---|---|
| Approved by: | Curtis Hovey on 2012-10-12 |
| Approved revision: | no longer in the source branch. |
| Merged at revision: | 16146 |
| Proposed branch: | lp:~stevenk/launchpad/destroy-old-bugactivity |
| Merge into: | lp:launchpad |
| Diff against target: |
838 lines (+79/-374) 12 files modified
database/sampledata/current-dev.sql (+0/-1) database/schema/Makefile (+2/-1) lib/lp/bugs/adapters/bugchange.py (+2/-76) lib/lp/bugs/doc/bug-change.txt (+0/-87) lib/lp/bugs/doc/bugnotification-email.txt (+9/-15) lib/lp/bugs/doc/bugnotification-sending.txt (+21/-20) lib/lp/bugs/doc/bugnotification-threading.txt (+8/-7) lib/lp/bugs/scripts/tests/test_bugnotification.py (+5/-7) lib/lp/bugs/stories/bugs/xx-bug-activity.txt (+13/-56) lib/lp/bugs/subscribers/bug.py (+2/-8) lib/lp/bugs/tests/test_bugchanges.py (+17/-89) lib/lp/services/features/flags.py (+0/-7) |
| To merge this branch: | bzr merge lp:~stevenk/launchpad/destroy-old-bugactivity |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Curtis Hovey (community) | code | 2012-10-12 | Approve on 2012-10-12 |
|
Review via email:
|
|||
Commit Message
Destroy Bug{Security,
Description of the Change
Destroy Bug{Security,
I have changed all of the tests I could find, but I suspect ec2 may find some that I may have missed.
I have corrected a small bug in database/
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 'database/sampledata/current-dev.sql' |
| 2 | --- database/sampledata/current-dev.sql 2012-10-12 05:43:38 +0000 |
| 3 | +++ database/sampledata/current-dev.sql 2012-10-15 03:36:20 +0000 |
| 4 | @@ -4321,7 +4321,6 @@ |
| 5 | |
| 6 | ALTER TABLE featureflag DISABLE TRIGGER ALL; |
| 7 | |
| 8 | -INSERT INTO featureflag (scope, priority, flag, value, date_modified) VALUES ('default', 0, 'disclosure.information_type_notifications.enabled', 'true', '2012-05-18 07:34:39.239649'); |
| 9 | INSERT INTO featureflag (scope, priority, flag, value, date_modified) VALUES ('default', 0, 'js.combo_loader.enabled', 'true', '2012-05-18 07:34:39.239649'); |
| 10 | INSERT INTO featureflag (scope, priority, flag, value, date_modified) VALUES ('default', 1, 'longpoll.merge_proposals.enabled', 'true', '2012-05-18 07:34:39.239649'); |
| 11 | |
| 12 | |
| 13 | === modified file 'database/schema/Makefile' |
| 14 | --- database/schema/Makefile 2012-07-12 09:58:32 +0000 |
| 15 | +++ database/schema/Makefile 2012-10-15 03:36:20 +0000 |
| 16 | @@ -38,7 +38,8 @@ |
| 17 | # The command we use to drop (if exists) and recreate a database. |
| 18 | CREATEDB=${PYTHON} ../../utilities/pgmassacre.py -t |
| 19 | |
| 20 | -HEADER="-- Copyright 2010-2011 Canonical Ltd. This software is licensed \ |
| 21 | +YEAR=$(shell date +'%Y') |
| 22 | +HEADER="-- Copyright 2010-${YEAR} Canonical Ltd. This software is licensed \ |
| 23 | under the\n-- GNU Affero General Public License version 3 (see the file \ |
| 24 | LICENSE)." |
| 25 | |
| 26 | |
| 27 | === modified file 'lib/lp/bugs/adapters/bugchange.py' |
| 28 | --- lib/lp/bugs/adapters/bugchange.py 2012-07-17 03:57:26 +0000 |
| 29 | +++ lib/lp/bugs/adapters/bugchange.py 2012-10-15 03:36:20 +0000 |
| 30 | @@ -24,7 +24,6 @@ |
| 31 | 'BugDescriptionChange', |
| 32 | 'BugDuplicateChange', |
| 33 | 'BugInformationTypeChange', |
| 34 | - 'BugSecurityChange', |
| 35 | 'BugTagsChange', |
| 36 | 'BugTaskAdded', |
| 37 | 'BugTaskAssigneeChange', |
| 38 | @@ -35,7 +34,6 @@ |
| 39 | 'BugTaskStatusChange', |
| 40 | 'BugTaskTargetChange', |
| 41 | 'BugTitleChange', |
| 42 | - 'BugVisibilityChange', |
| 43 | 'BugWatchAdded', |
| 44 | 'BugWatchRemoved', |
| 45 | 'CveLinkedToBug', |
| 46 | @@ -59,7 +57,6 @@ |
| 47 | UNRESOLVED_BUGTASK_STATUSES, |
| 48 | ) |
| 49 | from lp.registry.interfaces.product import IProduct |
| 50 | -from lp.services.features import getFeatureFlag |
| 51 | from lp.services.librarian.browser import ProxiedLibraryFileAlias |
| 52 | from lp.services.webapp.publisher import canonical_url |
| 53 | |
| 54 | @@ -105,13 +102,8 @@ |
| 55 | # The order of the field names in this list is important; this is |
| 56 | # the order in which changes will appear both in the bug activity |
| 57 | # log and in notification emails. |
| 58 | - bug_change_field_names = ['duplicateof', 'title', 'description'] |
| 59 | - if bool(getFeatureFlag( |
| 60 | - 'disclosure.information_type_notifications.enabled')): |
| 61 | - bug_change_field_names.append('information_type') |
| 62 | - else: |
| 63 | - bug_change_field_names.extend(('private', 'security_related')) |
| 64 | - bug_change_field_names.extend(('tags', 'attachment')) |
| 65 | + bug_change_field_names = ['duplicateof', 'title', 'description', |
| 66 | + 'information_type', 'tags', 'attachment'] |
| 67 | for field_name in bug_change_field_names: |
| 68 | field_delta = getattr(bug_delta, field_name) |
| 69 | if field_delta is not None: |
| 70 | @@ -562,70 +554,6 @@ |
| 71 | self.old_value.title, self.new_value.title)} |
| 72 | |
| 73 | |
| 74 | -# XXX: This can be deleted when information_type_notifications is removed. |
| 75 | -class BugVisibilityChange(AttributeChange): |
| 76 | - """Describes a change to a bug's visibility.""" |
| 77 | - |
| 78 | - def _getVisibilityString(self, private): |
| 79 | - """Return a string representation of `private`. |
| 80 | - |
| 81 | - :return: 'Public' if private is False, 'Private' if |
| 82 | - private is True. |
| 83 | - """ |
| 84 | - if private: |
| 85 | - return 'Private' |
| 86 | - else: |
| 87 | - return 'Public' |
| 88 | - |
| 89 | - def getBugActivity(self): |
| 90 | - # Use _getVisibilityString() to set old and new values |
| 91 | - # correctly. We lowercase them for UI consistency in the |
| 92 | - # activity log. |
| 93 | - old_value = self._getVisibilityString(self.old_value) |
| 94 | - new_value = self._getVisibilityString(self.new_value) |
| 95 | - return { |
| 96 | - 'oldvalue': old_value.lower(), |
| 97 | - 'newvalue': new_value.lower(), |
| 98 | - 'whatchanged': 'visibility', |
| 99 | - } |
| 100 | - |
| 101 | - def getBugNotification(self): |
| 102 | - visibility_string = self._getVisibilityString(self.new_value) |
| 103 | - return {'text': "** Visibility changed to: %s" % visibility_string} |
| 104 | - |
| 105 | - |
| 106 | -# XXX: This can be deleted when information_type_notifications is removed. |
| 107 | -class BugSecurityChange(AttributeChange): |
| 108 | - """Describes a change to a bug's security setting.""" |
| 109 | - |
| 110 | - activity_mapping = { |
| 111 | - (False, True): ('no', 'yes'), |
| 112 | - (True, False): ('yes', 'no'), |
| 113 | - } |
| 114 | - |
| 115 | - notification_mapping = { |
| 116 | - (False, True): |
| 117 | - u"** This bug has been flagged as a security vulnerability", |
| 118 | - (True, False): |
| 119 | - u"** This bug is no longer flagged as a security vulnerability", |
| 120 | - } |
| 121 | - |
| 122 | - def getBugActivity(self): |
| 123 | - old_value, new_value = self.activity_mapping[ |
| 124 | - (self.old_value, self.new_value)] |
| 125 | - return { |
| 126 | - 'oldvalue': old_value, |
| 127 | - 'newvalue': new_value, |
| 128 | - 'whatchanged': 'security vulnerability', |
| 129 | - } |
| 130 | - |
| 131 | - def getBugNotification(self): |
| 132 | - return { |
| 133 | - 'text': self.notification_mapping[ |
| 134 | - (self.old_value, self.new_value)], |
| 135 | - } |
| 136 | - |
| 137 | - |
| 138 | class BugTagsChange(AttributeChange): |
| 139 | """Used to represent a change to an `IBug`s tags.""" |
| 140 | |
| 141 | @@ -940,8 +868,6 @@ |
| 142 | |
| 143 | BUG_CHANGE_LOOKUP = { |
| 144 | 'description': BugDescriptionChange, |
| 145 | - 'private': BugVisibilityChange, |
| 146 | - 'security_related': BugSecurityChange, |
| 147 | 'information_type': BugInformationTypeChange, |
| 148 | 'tags': BugTagsChange, |
| 149 | 'title': BugTitleChange, |
| 150 | |
| 151 | === modified file 'lib/lp/bugs/doc/bug-change.txt' |
| 152 | --- lib/lp/bugs/doc/bug-change.txt 2012-08-08 11:48:29 +0000 |
| 153 | +++ lib/lp/bugs/doc/bug-change.txt 2012-10-15 03:36:20 +0000 |
| 154 | @@ -312,50 +312,6 @@ |
| 155 | 'whatchanged': 'marked as duplicate'} |
| 156 | |
| 157 | |
| 158 | -=== BugVisibilityChange === |
| 159 | - |
| 160 | -BugVisibilityChange is used to represent a change in a Bug's `private` |
| 161 | -attribute. |
| 162 | - |
| 163 | - >>> from lp.bugs.adapters.bugchange import ( |
| 164 | - ... BugVisibilityChange) |
| 165 | - |
| 166 | - >>> bug_visibility_change = BugVisibilityChange( |
| 167 | - ... when=nowish, person=example_person, |
| 168 | - ... what_changed='private', old_value=example_bug.private, |
| 169 | - ... new_value=True) |
| 170 | - |
| 171 | -IBug.private is a boolean but to make it more readable we express it in |
| 172 | -activity and notification records as a string, where True = 'Private' |
| 173 | -and False = 'Public'. We also refer to it as "visibility" rather than |
| 174 | -privacy. |
| 175 | - |
| 176 | - >>> print pretty(bug_visibility_change.getBugActivity()) |
| 177 | - {'newvalue': 'private', |
| 178 | - 'oldvalue': 'public', |
| 179 | - 'whatchanged': 'visibility'} |
| 180 | - |
| 181 | -We also use the 'Private', 'Public' and 'Visibility' terms in the |
| 182 | -notification text. |
| 183 | - |
| 184 | - >>> print bug_visibility_change.getBugNotification()['text'] |
| 185 | - ** Visibility changed to: Private |
| 186 | - |
| 187 | -If we reverse the changes we'll see the opposite values in the |
| 188 | -notification and activity entries. |
| 189 | - |
| 190 | - >>> bug_visibility_change = BugVisibilityChange( |
| 191 | - ... when=nowish, person=example_person, |
| 192 | - ... what_changed='private', old_value=True, new_value=False) |
| 193 | - >>> print pretty(bug_visibility_change.getBugActivity()) |
| 194 | - {'newvalue': 'public', |
| 195 | - 'oldvalue': 'private', |
| 196 | - 'whatchanged': 'visibility'} |
| 197 | - |
| 198 | - >>> print bug_visibility_change.getBugNotification()['text'] |
| 199 | - ** Visibility changed to: Public |
| 200 | - |
| 201 | - |
| 202 | == BugTagsChange == |
| 203 | |
| 204 | BugTagsChange is used to represent a change in a Bug's tag list. |
| 205 | @@ -385,49 +341,6 @@ |
| 206 | ** Tags added: zillionth-tag |
| 207 | |
| 208 | |
| 209 | -=== BugSecurityChange === |
| 210 | - |
| 211 | -BugSecurityChange is used to represent a change in a Bug's |
| 212 | -`security_related` attribute. |
| 213 | - |
| 214 | - >>> from lp.bugs.adapters.bugchange import ( |
| 215 | - ... BugSecurityChange) |
| 216 | - |
| 217 | - >>> bug_security_change = BugSecurityChange( |
| 218 | - ... when=nowish, person=example_person, |
| 219 | - ... what_changed='security_related', |
| 220 | - ... old_value=False, new_value=True) |
| 221 | - |
| 222 | -IBug.security_related is a boolean but to make it more readable we |
| 223 | -express it in activity and notification records as a short phrase. |
| 224 | - |
| 225 | -Marking a bug as security related causes one set of terms/phrases to |
| 226 | -be used. |
| 227 | - |
| 228 | - >>> print pretty(bug_security_change.getBugActivity()) |
| 229 | - {'newvalue': 'yes', |
| 230 | - 'oldvalue': 'no', |
| 231 | - 'whatchanged': 'security vulnerability'} |
| 232 | - |
| 233 | - >>> print bug_security_change.getBugNotification()['text'] |
| 234 | - ** This bug has been flagged as a security vulnerability |
| 235 | - |
| 236 | -Going the other way the phrases are similar. |
| 237 | - |
| 238 | - >>> bug_security_change = BugSecurityChange( |
| 239 | - ... when=nowish, person=example_person, |
| 240 | - ... what_changed='security_related', |
| 241 | - ... old_value=True, new_value=False) |
| 242 | - |
| 243 | - >>> print pretty(bug_security_change.getBugActivity()) |
| 244 | - {'newvalue': 'no', |
| 245 | - 'oldvalue': 'yes', |
| 246 | - 'whatchanged': 'security vulnerability'} |
| 247 | - |
| 248 | - >>> print bug_security_change.getBugNotification()['text'] |
| 249 | - ** This bug is no longer flagged as a security vulnerability |
| 250 | - |
| 251 | - |
| 252 | === CveLinkedToBug / CveUnlinkedFromBug === |
| 253 | |
| 254 | These describe the linking or unlinking of a CVE to a bug. |
| 255 | |
| 256 | === modified file 'lib/lp/bugs/doc/bugnotification-email.txt' |
| 257 | --- lib/lp/bugs/doc/bugnotification-email.txt 2012-09-17 16:13:40 +0000 |
| 258 | +++ lib/lp/bugs/doc/bugnotification-email.txt 2012-10-15 03:36:20 +0000 |
| 259 | @@ -233,10 +233,9 @@ |
| 260 | ... bug=edited_bug, |
| 261 | ... bugurl="http://www.example.com/bugs/6", |
| 262 | ... user=sample_person, |
| 263 | - ... private={'old': False, 'new': edited_bug.private}, |
| 264 | - ... security_related={ |
| 265 | - ... 'old': False, |
| 266 | - ... 'new': edited_bug.security_related, |
| 267 | + ... information_type = { |
| 268 | + ... 'old': InformationType.PUBLIC, |
| 269 | + ... 'new': InformationType.PRIVATESECURITY |
| 270 | ... }) |
| 271 | |
| 272 | >>> for change in get_bug_changes(bug_delta): |
| 273 | @@ -244,13 +243,10 @@ |
| 274 | ... text_representation = notification['text'] |
| 275 | ... print text_representation #doctest: -NORMALIZE_WHITESPACE |
| 276 | ... print "-----------------------------" |
| 277 | - ** Visibility changed to: Private |
| 278 | - ----------------------------- |
| 279 | - ** This bug has been flagged as a security vulnerability |
| 280 | + ** Information type changed from Public to Private Security |
| 281 | ----------------------------- |
| 282 | |
| 283 | -Now we set the bug public, and not security-related and check if the |
| 284 | -e-mail sent changed as well. |
| 285 | +Now we set the bug back to public and check if the e-mail sent changed as well. |
| 286 | |
| 287 | >>> changed = edited_bug.transitionToInformationType( |
| 288 | ... InformationType.PUBLIC, getUtility(ILaunchBag).user) |
| 289 | @@ -259,17 +255,15 @@ |
| 290 | ... bugurl="http://www.example.com/bugs/6", |
| 291 | ... user=sample_person, |
| 292 | ... private={'old': True, 'new': edited_bug.private}, |
| 293 | - ... security_related={ |
| 294 | - ... 'old': True, |
| 295 | - ... 'new': edited_bug.security_related, |
| 296 | + ... information_type={ |
| 297 | + ... 'old': InformationType.PRIVATESECURITY, |
| 298 | + ... 'new': InformationType.PUBLIC |
| 299 | ... }) |
| 300 | >>> for change in get_bug_changes(bug_delta): |
| 301 | ... notification = change.getBugNotification() |
| 302 | ... print notification['text'] #doctest: -NORMALIZE_WHITESPACE |
| 303 | ... print "-----------------------------" |
| 304 | - ** Visibility changed to: Public |
| 305 | - ----------------------------- |
| 306 | - ** This bug is no longer flagged as a security vulnerability |
| 307 | + ** Information type changed from Private Security to Public |
| 308 | ----------------------------- |
| 309 | |
| 310 | Let's add some tags to a bug: |
| 311 | |
| 312 | === modified file 'lib/lp/bugs/doc/bugnotification-sending.txt' |
| 313 | --- lib/lp/bugs/doc/bugnotification-sending.txt 2012-09-19 13:21:13 +0000 |
| 314 | +++ lib/lp/bugs/doc/bugnotification-sending.txt 2012-10-15 03:36:20 +0000 |
| 315 | @@ -166,16 +166,17 @@ |
| 316 | Let's add a few changes and see how it looks like: |
| 317 | |
| 318 | >>> from lp.bugs.adapters.bugchange import ( |
| 319 | - ... BugTitleChange, BugVisibilityChange) |
| 320 | + ... BugTitleChange, BugInformationTypeChange) |
| 321 | + >>> from lp.app.enums import InformationType |
| 322 | |
| 323 | >>> bug_one.addChange( |
| 324 | ... BugTitleChange( |
| 325 | ... ten_minutes_ago, sample_person, "title", |
| 326 | ... "Old summary", "New summary")) |
| 327 | >>> bug_one.addChange( |
| 328 | - ... BugVisibilityChange( |
| 329 | - ... ten_minutes_ago, sample_person, "private", |
| 330 | - ... False, True)) |
| 331 | + ... BugInformationTypeChange( |
| 332 | + ... ten_minutes_ago, sample_person, "information_type", |
| 333 | + ... InformationType.PUBLIC, InformationType.USERDATA)) |
| 334 | >>> pending_notifications = getUtility( |
| 335 | ... IBugNotificationSet).getNotificationsToSend() |
| 336 | >>> len(pending_notifications) |
| 337 | @@ -196,7 +197,7 @@ |
| 338 | - Old summary |
| 339 | + New summary |
| 340 | <BLANKLINE> |
| 341 | - ** Visibility changed to: Private |
| 342 | + ** Information type changed from Public to Private |
| 343 | <BLANKLINE> |
| 344 | -- |
| 345 | ... |
| 346 | @@ -216,9 +217,9 @@ |
| 347 | ... ten_minutes_ago, sample_person, "title", |
| 348 | ... "New summary", "Another summary")) |
| 349 | >>> bug_one.addChange( |
| 350 | - ... BugVisibilityChange( |
| 351 | - ... ten_minutes_ago, sample_person, "private", |
| 352 | - ... True, False)) |
| 353 | + ... BugInformationTypeChange( |
| 354 | + ... ten_minutes_ago, sample_person, "information_type", |
| 355 | + ... InformationType.USERDATA, InformationType.PUBLIC)) |
| 356 | >>> pending_notifications = getUtility( |
| 357 | ... IBugNotificationSet).getNotificationsToSend() |
| 358 | >>> len(pending_notifications) |
| 359 | @@ -283,9 +284,10 @@ |
| 360 | >>> now = datetime.now(pytz.timezone('UTC')) |
| 361 | >>> for minutes_ago in reversed(range(10)): |
| 362 | ... bug_one.addChange( |
| 363 | - ... BugVisibilityChange( |
| 364 | + ... BugInformationTypeChange( |
| 365 | ... now - timedelta(minutes=minutes_ago), sample_person, |
| 366 | - ... "private", False, True)) |
| 367 | + ... "information_type", InformationType.PUBLIC, |
| 368 | + ... InformationType.USERDATA)) |
| 369 | >>> pending_notifications = getUtility( |
| 370 | ... IBugNotificationSet).getNotificationsToSend() |
| 371 | >>> len(pending_notifications) |
| 372 | @@ -336,7 +338,6 @@ |
| 373 | We will need a fresh new bug. |
| 374 | |
| 375 | >>> from lp.bugs.interfaces.bug import CreateBugParams |
| 376 | - >>> from lp.app.enums import InformationType |
| 377 | >>> from lp.registry.interfaces.distribution import IDistributionSet |
| 378 | >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
| 379 | >>> description = getUtility(IMessageSet).fromText( |
| 380 | @@ -471,13 +472,13 @@ |
| 381 | ... ten_minutes_ago, sample_person, "title", |
| 382 | ... "Old summary", "New summary")) |
| 383 | >>> bug_two.addChange( |
| 384 | - ... BugVisibilityChange( |
| 385 | - ... ten_minutes_ago, sample_person, "title", |
| 386 | - ... False, True)) |
| 387 | + ... BugInformationTypeChange( |
| 388 | + ... ten_minutes_ago, sample_person, "information_type", |
| 389 | + ... InformationType.PUBLIC, InformationType.USERDATA)) |
| 390 | >>> bug_two.addChange( |
| 391 | - ... BugVisibilityChange( |
| 392 | - ... ten_minutes_ago, sample_person, "title", |
| 393 | - ... True, False)) |
| 394 | + ... BugInformationTypeChange( |
| 395 | + ... ten_minutes_ago, sample_person, "information_type", |
| 396 | + ... InformationType.USERDATA, InformationType.PUBLIC)) |
| 397 | |
| 398 | >>> notifications = getUtility( |
| 399 | ... IBugNotificationSet).getNotificationsToSend() |
| 400 | @@ -559,7 +560,7 @@ |
| 401 | INFO Notifying test@canonical.com about bug 1. |
| 402 | ... |
| 403 | |
| 404 | -Note that the message omitted the undone visibility change. |
| 405 | +Note that the message omitted the undone information type change. |
| 406 | |
| 407 | The cronscript has to be sure to mark all notifications, omitted and |
| 408 | otherwise, as sent. It also marks the omitted notifications with a status, |
| 409 | @@ -591,8 +592,8 @@ |
| 410 | summary Sent |
| 411 | comment Sent |
| 412 | summary Sent |
| 413 | - visibility Omitted |
| 414 | - visibility Omitted |
| 415 | + information type Omitted |
| 416 | + information type Omitted |
| 417 | |
| 418 | |
| 419 | The X-Launchpad-Bug header |
| 420 | |
| 421 | === modified file 'lib/lp/bugs/doc/bugnotification-threading.txt' |
| 422 | --- lib/lp/bugs/doc/bugnotification-threading.txt 2012-07-27 01:15:04 +0000 |
| 423 | +++ lib/lp/bugs/doc/bugnotification-threading.txt 2012-10-15 03:36:20 +0000 |
| 424 | @@ -18,16 +18,17 @@ |
| 425 | >>> from datetime import datetime, timedelta |
| 426 | >>> from lp.services.messages.interfaces.message import IMessageSet |
| 427 | >>> from lp.bugs.interfaces.bug import IBugSet |
| 428 | - >>> from lp.bugs.adapters.bugchange import BugVisibilityChange |
| 429 | + >>> from lp.bugs.adapters.bugchange import BugInformationTypeChange |
| 430 | + >>> from lp.app.enums import InformationType |
| 431 | |
| 432 | >>> ten_minutes_ago = ( |
| 433 | ... datetime.now(pytz.timezone('UTC')) - timedelta(minutes=10)) |
| 434 | >>> sample_person = getUtility(ILaunchBag).user |
| 435 | >>> bug_one = getUtility(IBugSet).get(1) |
| 436 | >>> bug_one.addChange( |
| 437 | - ... BugVisibilityChange( |
| 438 | - ... ten_minutes_ago, sample_person, "private", |
| 439 | - ... False, True)) |
| 440 | + ... BugInformationTypeChange( |
| 441 | + ... ten_minutes_ago, sample_person, "information_type", |
| 442 | + ... InformationType.PUBLIC, InformationType.USERDATA)) |
| 443 | |
| 444 | >>> from lp.bugs.interfaces.bugnotification import IBugNotificationSet |
| 445 | >>> from lp.bugs.scripts.bugnotification import ( |
| 446 | @@ -68,9 +69,9 @@ |
| 447 | >>> bug_one.linkMessage(comment) |
| 448 | <...> |
| 449 | >>> bug_one.addChange( |
| 450 | - ... BugVisibilityChange( |
| 451 | - ... ten_minutes_ago, sample_person, "private", |
| 452 | - ... True, False)) |
| 453 | + ... BugInformationTypeChange( |
| 454 | + ... ten_minutes_ago, sample_person, "information_type", |
| 455 | + ... InformationType.USERDATA, InformationType.PUBLIC)) |
| 456 | >>> notifications = getUtility( |
| 457 | ... IBugNotificationSet).getNotificationsToSend() |
| 458 | >>> messages = [emails for notifications, omitted, emails in |
| 459 | |
| 460 | === modified file 'lib/lp/bugs/scripts/tests/test_bugnotification.py' |
| 461 | --- lib/lp/bugs/scripts/tests/test_bugnotification.py 2012-09-18 18:36:09 +0000 |
| 462 | +++ lib/lp/bugs/scripts/tests/test_bugnotification.py 2012-10-15 03:36:20 +0000 |
| 463 | @@ -1,4 +1,4 @@ |
| 464 | -# Copyright 2009-2010 Canonical Ltd. This software is licensed under the |
| 465 | +# Copyright 2009-2012 Canonical Ltd. This software is licensed under the |
| 466 | # GNU Affero General Public License version 3 (see the file LICENSE). |
| 467 | """Tests for construction bug notification emails for sending.""" |
| 468 | |
| 469 | @@ -29,10 +29,10 @@ |
| 470 | BranchUnlinkedFromBug, |
| 471 | BugAttachmentChange, |
| 472 | BugDuplicateChange, |
| 473 | + BugInformationTypeChange, |
| 474 | BugTagsChange, |
| 475 | BugTaskStatusChange, |
| 476 | BugTitleChange, |
| 477 | - BugVisibilityChange, |
| 478 | BugWatchAdded, |
| 479 | BugWatchRemoved, |
| 480 | CveLinkedToBug, |
| 481 | @@ -96,8 +96,6 @@ |
| 482 | implements(IBug) |
| 483 | |
| 484 | duplicateof = None |
| 485 | - private = False |
| 486 | - security_related = False |
| 487 | information_type = InformationType.PUBLIC |
| 488 | messages = [] |
| 489 | |
| 490 | @@ -691,9 +689,9 @@ |
| 491 | |
| 492 | def change_other(self): |
| 493 | self.bug.addChange( |
| 494 | - BugVisibilityChange( |
| 495 | - self.ten_minutes_ago, self.person, "private", |
| 496 | - False, True)) |
| 497 | + BugInformationTypeChange( |
| 498 | + self.ten_minutes_ago, self.person, "information_type", |
| 499 | + InformationType.PUBLIC, InformationType.USERDATA)) |
| 500 | |
| 501 | def test_change_seen(self): |
| 502 | # A smoketest. |
| 503 | |
| 504 | === modified file 'lib/lp/bugs/stories/bugs/xx-bug-activity.txt' |
| 505 | --- lib/lp/bugs/stories/bugs/xx-bug-activity.txt 2012-08-03 01:42:13 +0000 |
| 506 | +++ lib/lp/bugs/stories/bugs/xx-bug-activity.txt 2012-10-15 03:36:20 +0000 |
| 507 | @@ -98,44 +98,6 @@ |
| 508 | + A new title for this bug |
| 509 | -------- |
| 510 | |
| 511 | -Alterations to a bug's privacy will show up as 'visibility' changes. |
| 512 | - |
| 513 | - >>> admin_browser.open( |
| 514 | - ... 'http://bugs.launchpad.dev/redfish/+bug/15/+secrecy') |
| 515 | - >>> admin_browser.getControl("Private", index=1).selected = True |
| 516 | - >>> admin_browser.getControl("Change").click() |
| 517 | - |
| 518 | - >>> admin_browser.open('http://launchpad.dev/bugs/15') |
| 519 | - >>> print_comments(admin_browser.contents) |
| 520 | - Foo Bar |
| 521 | - ... ago |
| 522 | - summary: |
| 523 | - - Nonsensical bugs are useless |
| 524 | - + A new title for this bug |
| 525 | - visibility: |
| 526 | - public => private |
| 527 | - -------- |
| 528 | - |
| 529 | -Changes to a bug's security_related field will be displayed as |
| 530 | -'security vulnerability' changes, with values of 'yes' or 'no'. Note |
| 531 | -that changes are grouped together if they occur at similar times, but |
| 532 | -are still shown in the order the changes were made. |
| 533 | - |
| 534 | - >>> admin_browser.open( |
| 535 | - ... 'http://bugs.launchpad.dev/redfish/+bug/15/+secrecy') |
| 536 | - >>> admin_browser.getControl("Private Security").selected = True |
| 537 | - >>> admin_browser.getControl("Change").click() |
| 538 | - |
| 539 | - >>> admin_browser.open('http://launchpad.dev/bugs/15') |
| 540 | - >>> print_comments(admin_browser.contents) |
| 541 | - Foo Bar (name16) |
| 542 | - ... ago |
| 543 | - summary: |
| 544 | - ... |
| 545 | - security vulnerability: |
| 546 | - no => yes |
| 547 | - -------- |
| 548 | - |
| 549 | Changes to the bug's description will simply be displayed as 'description: |
| 550 | updated', since such changes can be quite long. |
| 551 | |
| 552 | @@ -310,31 +272,26 @@ |
| 553 | ubuntu |
| 554 | -------- |
| 555 | |
| 556 | -Changes to information_type are shown when the feature flag is set. |
| 557 | +Changes to information_type are shown. |
| 558 | |
| 559 | - >>> from lp.services.features.testing import FeatureFixture |
| 560 | - >>> feature_flag = { |
| 561 | - ... 'disclosure.information_type_notifications.enabled': 'on'} |
| 562 | - >>> with FeatureFixture(feature_flag): |
| 563 | - ... admin_browser.open( |
| 564 | - ... "http://bugs.launchpad.dev/evolution/+bug/7/+secrecy") |
| 565 | - ... admin_browser.getControl("Private", index=1).selected = True |
| 566 | - ... admin_browser.getControl('Change').click() |
| 567 | - ... admin_browser.open("http://bugs.launchpad.dev/evolution/+bug/7") |
| 568 | - ... print_comments(admin_browser.contents) |
| 569 | + >>> admin_browser.open( |
| 570 | + ... "http://bugs.launchpad.dev/evolution/+bug/7/+secrecy") |
| 571 | + >>> admin_browser.getControl("Private", index=1).selected = True |
| 572 | + >>> admin_browser.getControl('Change').click() |
| 573 | + >>> admin_browser.open("http://bugs.launchpad.dev/evolution/+bug/7") |
| 574 | + >>> print_comments(admin_browser.contents) |
| 575 | Foo Bar (name16) |
| 576 | ... ago |
| 577 | information type: |
| 578 | Public => Private |
| 579 | -------- |
| 580 | |
| 581 | - >>> with FeatureFixture(feature_flag): |
| 582 | - ... admin_browser.open( |
| 583 | - ... "http://bugs.launchpad.dev/jokosher/+bug/14/+secrecy") |
| 584 | - ... admin_browser.getControl("Private", index=1).selected = True |
| 585 | - ... admin_browser.getControl('Change').click() |
| 586 | - ... admin_browser.open("http://bugs.launchpad.dev/jokosher/+bug/14") |
| 587 | - ... print_comments(admin_browser.contents) |
| 588 | + >>> admin_browser.open( |
| 589 | + ... "http://bugs.launchpad.dev/jokosher/+bug/14/+secrecy") |
| 590 | + >>> admin_browser.getControl("Private", index=1).selected = True |
| 591 | + >>> admin_browser.getControl('Change').click() |
| 592 | + >>> admin_browser.open("http://bugs.launchpad.dev/jokosher/+bug/14") |
| 593 | + >>> print_comments(admin_browser.contents) |
| 594 | Foo Bar (name16) |
| 595 | ... ago |
| 596 | information type: |
| 597 | |
| 598 | === modified file 'lib/lp/bugs/subscribers/bug.py' |
| 599 | --- lib/lp/bugs/subscribers/bug.py 2012-09-20 04:49:19 +0000 |
| 600 | +++ lib/lp/bugs/subscribers/bug.py 2012-10-15 03:36:20 +0000 |
| 601 | @@ -30,7 +30,6 @@ |
| 602 | from lp.registry.interfaces.person import IPerson |
| 603 | from lp.services.config import config |
| 604 | from lp.services.database.sqlbase import block_implicit_flushes |
| 605 | -from lp.services.features import getFeatureFlag |
| 606 | from lp.services.mail.helpers import get_contact_email_addresses |
| 607 | from lp.services.mail.sendmail import ( |
| 608 | format_address, |
| 609 | @@ -110,13 +109,8 @@ |
| 610 | IBugDelta if there are changes, or None if there were no changes. |
| 611 | """ |
| 612 | changes = {} |
| 613 | - fields = ["title", "description", "name"] |
| 614 | - if bool(getFeatureFlag( |
| 615 | - 'disclosure.information_type_notifications.enabled')): |
| 616 | - fields.append('information_type') |
| 617 | - else: |
| 618 | - fields.extend(('private', 'security_related')) |
| 619 | - fields.extend(("duplicateof", "tags")) |
| 620 | + fields = ["title", "description", "name", "information_type", |
| 621 | + "duplicateof", "tags"] |
| 622 | for field_name in fields: |
| 623 | # fields for which we show old => new when their values change |
| 624 | old_val = getattr(old_bug, field_name) |
| 625 | |
| 626 | === modified file 'lib/lp/bugs/tests/test_bugchanges.py' |
| 627 | --- lib/lp/bugs/tests/test_bugchanges.py 2012-09-18 18:36:09 +0000 |
| 628 | +++ lib/lp/bugs/tests/test_bugchanges.py 2012-10-15 03:36:20 +0000 |
| 629 | @@ -25,7 +25,6 @@ |
| 630 | from lp.bugs.interfaces.cve import ICveSet |
| 631 | from lp.bugs.model.bugnotification import BugNotification |
| 632 | from lp.bugs.scripts.bugnotification import construct_email_notifications |
| 633 | -from lp.services.features.testing import FeatureFixture |
| 634 | from lp.services.librarian.browser import ProxiedLibraryFileAlias |
| 635 | from lp.services.webapp.interfaces import ILaunchBag |
| 636 | from lp.services.webapp.publisher import canonical_url |
| 637 | @@ -47,8 +46,7 @@ |
| 638 | super(TestBugChanges, self).setUp('foo.bar@canonical.com') |
| 639 | self.admin_user = getUtility(ILaunchBag).user |
| 640 | self.user = self.factory.makePerson( |
| 641 | - displayname='Arthur Dent', |
| 642 | - selfgenerated_bugnotifications=True) |
| 643 | + displayname='Arthur Dent', selfgenerated_bugnotifications=True) |
| 644 | self.product = self.factory.makeProduct( |
| 645 | owner=self.user, official_malone=True) |
| 646 | self.bug = self.factory.makeBug(target=self.product, owner=self.user) |
| 647 | @@ -57,11 +55,9 @@ |
| 648 | # Add some structural subscribers to show that notifications |
| 649 | # aren't sent to LIFECYCLE subscribers by default. |
| 650 | self.product_lifecycle_subscriber = self.newSubscriber( |
| 651 | - self.product, "product-lifecycle", |
| 652 | - BugNotificationLevel.LIFECYCLE) |
| 653 | + self.product, "product-lifecycle", BugNotificationLevel.LIFECYCLE) |
| 654 | self.product_metadata_subscriber = self.newSubscriber( |
| 655 | - self.product, "product-metadata", |
| 656 | - BugNotificationLevel.METADATA) |
| 657 | + self.product, "product-metadata", BugNotificationLevel.METADATA) |
| 658 | |
| 659 | self.saveOldChanges() |
| 660 | |
| 661 | @@ -226,8 +222,7 @@ |
| 662 | self.assertEqual(activity.target, None) |
| 663 | |
| 664 | unsubscribe_activity = dict( |
| 665 | - whatchanged='removed subscriber Arthur Dent', |
| 666 | - person=self.user) |
| 667 | + whatchanged='removed subscriber Arthur Dent', person=self.user) |
| 668 | self.assertRecordedChange(expected_activity=unsubscribe_activity) |
| 669 | |
| 670 | def test_unsubscribe_private_bug(self): |
| 671 | @@ -242,8 +237,7 @@ |
| 672 | self.saveOldChanges(bug=bug) |
| 673 | bug.unsubscribe(subscriber, subscriber) |
| 674 | unsubscribe_activity = dict( |
| 675 | - whatchanged=u'removed subscriber Mom', |
| 676 | - person=subscriber) |
| 677 | + whatchanged=u'removed subscriber Mom', person=subscriber) |
| 678 | self.assertRecordedChange( |
| 679 | expected_activity=unsubscribe_activity, bug=bug) |
| 680 | |
| 681 | @@ -562,77 +556,17 @@ |
| 682 | self.bug.unlinkBranch(branch, self.user) |
| 683 | self.assertRecordedChange() |
| 684 | |
| 685 | - def test_make_private(self): |
| 686 | - # Marking a bug as private adds items to the bug's activity log |
| 687 | - # and notifications. |
| 688 | - bug_before_modification = Snapshot( |
| 689 | - self.bug, providing=providedBy(self.bug)) |
| 690 | - self.bug.setPrivate(True, self.user) |
| 691 | - notify(ObjectModifiedEvent( |
| 692 | - self.bug, bug_before_modification, ['private'], user=self.user)) |
| 693 | - |
| 694 | - visibility_change_activity = { |
| 695 | - 'person': self.user, |
| 696 | - 'whatchanged': 'visibility', |
| 697 | - 'oldvalue': 'public', |
| 698 | - 'newvalue': 'private', |
| 699 | - } |
| 700 | - |
| 701 | - visibility_change_notification = { |
| 702 | - 'text': '** Visibility changed to: Private', |
| 703 | - 'person': self.user, |
| 704 | - } |
| 705 | - |
| 706 | - self.assertRecordedChange( |
| 707 | - expected_activity=visibility_change_activity, |
| 708 | - expected_notification=visibility_change_notification) |
| 709 | - |
| 710 | - def test_make_public(self): |
| 711 | - # Marking a bug as public adds items to the bug's activity log |
| 712 | - # and notifications. |
| 713 | - private_bug = self.factory.makeBug( |
| 714 | - information_type=InformationType.USERDATA) |
| 715 | - self.saveOldChanges(private_bug) |
| 716 | - self.assertTrue(private_bug.private) |
| 717 | - bug_before_modification = Snapshot( |
| 718 | - private_bug, providing=providedBy(private_bug)) |
| 719 | - private_bug.transitionToInformationType( |
| 720 | - InformationType.PUBLIC, self.user) |
| 721 | - notify(ObjectModifiedEvent( |
| 722 | - private_bug, bug_before_modification, ['private'], |
| 723 | - user=self.user)) |
| 724 | - |
| 725 | - visibility_change_activity = { |
| 726 | - 'person': self.user, |
| 727 | - 'whatchanged': 'visibility', |
| 728 | - 'oldvalue': 'private', |
| 729 | - 'newvalue': 'public', |
| 730 | - } |
| 731 | - |
| 732 | - visibility_change_notification = { |
| 733 | - 'text': '** Visibility changed to: Public', |
| 734 | - 'person': self.user, |
| 735 | - } |
| 736 | - |
| 737 | - self.assertRecordedChange( |
| 738 | - expected_activity=visibility_change_activity, |
| 739 | - expected_notification=visibility_change_notification, |
| 740 | - bug=private_bug) |
| 741 | - |
| 742 | def test_change_information_type(self): |
| 743 | # Changing the information type of a bug adds items to the activity |
| 744 | # log and notifications. |
| 745 | bug = self.factory.makeBug() |
| 746 | self.saveOldChanges(bug=bug) |
| 747 | - feature_flag = { |
| 748 | - 'disclosure.information_type_notifications.enabled': 'on'} |
| 749 | bug_before_modification = Snapshot(bug, providing=providedBy(bug)) |
| 750 | - with FeatureFixture(feature_flag): |
| 751 | - bug.transitionToInformationType( |
| 752 | - InformationType.PRIVATESECURITY, self.user) |
| 753 | - notify(ObjectModifiedEvent( |
| 754 | - bug, bug_before_modification, ['information_type'], |
| 755 | - user=self.user)) |
| 756 | + bug.transitionToInformationType( |
| 757 | + InformationType.PRIVATESECURITY, self.user) |
| 758 | + notify(ObjectModifiedEvent( |
| 759 | + bug, bug_before_modification, ['information_type'], |
| 760 | + user=self.user)) |
| 761 | |
| 762 | information_type_change_activity = { |
| 763 | 'person': self.user, |
| 764 | @@ -656,13 +590,9 @@ |
| 765 | person = self.factory.makePerson() |
| 766 | bug = self.factory.makeBug(owner=person) |
| 767 | self.saveOldChanges(bug=bug) |
| 768 | - feature_flag = { |
| 769 | - 'disclosure.information_type_notifications.enabled': 'on'} |
| 770 | webservice = launchpadlib_for('test', person) |
| 771 | lp_bug = webservice.load(api_url(bug)) |
| 772 | - with FeatureFixture(feature_flag): |
| 773 | - lp_bug.transitionToInformationType( |
| 774 | - information_type='Private Security') |
| 775 | + lp_bug.transitionToInformationType(information_type='Private Security') |
| 776 | |
| 777 | information_type_change_activity = { |
| 778 | 'person': person, |
| 779 | @@ -800,7 +730,7 @@ |
| 780 | # This checks the activity's attribute and target attributes. |
| 781 | activity = self.bug.activity[-1] |
| 782 | self.assertEqual(activity.attribute, 'attachments') |
| 783 | - self.assertEqual(activity.target, None) |
| 784 | + self.assertIsNone(activity.target) |
| 785 | |
| 786 | attachment_added_activity = { |
| 787 | 'person': self.user, |
| 788 | @@ -1686,8 +1616,7 @@ |
| 789 | |
| 790 | self.assertRecordedChange( |
| 791 | expected_activity=expected_activity, |
| 792 | - expected_notification=expected_notification, |
| 793 | - bug=duplicate_bug) |
| 794 | + expected_notification=expected_notification, bug=duplicate_bug) |
| 795 | |
| 796 | def test_convert_to_question_no_comment(self): |
| 797 | # When a bug task is converted to a question, its status is |
| 798 | @@ -1754,8 +1683,7 @@ |
| 799 | |
| 800 | self.assertRecordedChange( |
| 801 | expected_activity=expected_activity, |
| 802 | - expected_notification=expected_notification, |
| 803 | - bug=new_bug) |
| 804 | + expected_notification=expected_notification, bug=new_bug) |
| 805 | |
| 806 | def test_description_changed_no_self_email(self): |
| 807 | # Users who have selfgenerated_bugnotifications set to False |
| 808 | @@ -1805,9 +1733,9 @@ |
| 809 | # If a person has a structural METADATA subscription, |
| 810 | # and a direct LIFECYCLE subscription, they should |
| 811 | # get no emails for a non-LIFECYCLE change (bug 713382). |
| 812 | - self.bug.subscribe(self.product_metadata_subscriber, |
| 813 | - self.product_metadata_subscriber, |
| 814 | - level=BugNotificationLevel.LIFECYCLE) |
| 815 | + self.bug.subscribe( |
| 816 | + self.product_metadata_subscriber, self.product_metadata_subscriber, |
| 817 | + level=BugNotificationLevel.LIFECYCLE) |
| 818 | self.changeAttribute( |
| 819 | self.bug, 'description', 'New description') |
| 820 | |
| 821 | |
| 822 | === modified file 'lib/lp/services/features/flags.py' |
| 823 | --- lib/lp/services/features/flags.py 2012-10-04 23:15:35 +0000 |
| 824 | +++ lib/lp/services/features/flags.py 2012-10-15 03:36:20 +0000 |
| 825 | @@ -220,13 +220,6 @@ |
| 826 | '', |
| 827 | '', |
| 828 | ''), |
| 829 | - ('disclosure.information_type_notifications.enabled', |
| 830 | - 'boolean', |
| 831 | - ('If true, calculate and store bugchange notifications to reference ' |
| 832 | - 'information_type rather than private/security_related.'), |
| 833 | - '', |
| 834 | - '', |
| 835 | - ''), |
| 836 | ('auditor.enabled', |
| 837 | 'boolean', |
| 838 | 'If true, send audit data to an auditor instance.', |

Thank you.