Merge lp:~danilo/launchpad/ss-storm-rewrite-methods into lp:launchpad
- ss-storm-rewrite-methods
- Merge into devel
Status: | Merged |
---|---|
Approved by: | Graham Binns |
Approved revision: | no longer in the source branch. |
Merged at revision: | 12254 |
Proposed branch: | lp:~danilo/launchpad/ss-storm-rewrite-methods |
Merge into: | lp:launchpad |
Prerequisite: | lp:~danilo/launchpad/ss-storm-rewrite |
Diff against target: |
569 lines (+102/-92) 12 files modified
lib/lp/bugs/doc/bugsubscription.txt (+33/-28) lib/lp/bugs/doc/bugtask-search.txt (+9/-9) lib/lp/bugs/doc/initial-bug-contacts.txt (+7/-7) lib/lp/bugs/stories/patches-view/patches-view.txt (+1/-1) lib/lp/bugs/tests/bugs-emailinterface.txt (+1/-1) lib/lp/registry/browser/tests/milestone-views.txt (+1/-1) lib/lp/registry/doc/milestone.txt (+2/-2) lib/lp/registry/doc/person.txt (+2/-2) lib/lp/registry/model/person.py (+4/-2) lib/lp/registry/model/structuralsubscription.py (+38/-35) lib/lp/registry/templates/person-structural-subscriptions.pt (+2/-2) lib/lp/registry/tests/structural-subscription-target.txt (+2/-2) |
To merge this branch: | bzr merge lp:~danilo/launchpad/ss-storm-rewrite-methods |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Graham Binns (community) | code | Approve | |
Review via email: mp+46843@code.launchpad.net |
Commit message
[r=gmb]
Description of the change
= Convert StructuralSubsc
This branch completes the migration of StructuralSubsc
This branch continues on that and moves all .select() and .selectBy() calls on StructuralSubsc
Followed https:/
== Implementation details ==
There are not enough unit tests for the functionality I am changing, but the full test run over all the layers of implementation (doc tests, unit tests, API tests and browser tests) did catch a few bugs (or incompatible changes that I did). While I'd love to add new tests for all the methods in StructuralSubsc
It also includes slight optimizations in two places where we go over all the subscriptions to find one for a particular subscriber. It now executes a query which returns just one result instead.
To achieve this, subscriber parameter is added to getSubscriptions(), but it's not exposed in the interface because we are only using it from inside the module. That looks dirty even to me, so I'd be happy to change it if a reviewer thinks I should do it.
I am ignoring doctest lint errors since it might make diff harder to read. I'd be happy to update it after the review is done.
== Tests ==
bin/test -cvvt bugsubscription.txt -t bugnotification
== Demo and Q/A ==
no-qa
= Launchpad lint =
Checking for conflicts and issues in changed files.
Linting changed files:
lib/lp/
lib/lp/
lib/lp/
./lib/lp/
1: narrative uses a moin header.
6: narrative uses a moin header.
25: narrative uses a moin header.
438: source has bad indentation.
442: source has bad indentation.
459: source has bad indentation.
474: source has bad indentation.
487: source has bad indentation.
494: want exceeds 78 characters.
528: narrative uses a moin header.
589: narrative uses a moin header.
644: narrative uses a moin header.
852: narrative uses a moin header.
Graham Binns (gmb) : | # |
Robert Collins (lifeless) wrote : | # |
Preview Diff
1 | === modified file 'lib/lp/bugs/doc/bugsubscription.txt' | |||
2 | --- lib/lp/bugs/doc/bugsubscription.txt 2011-01-18 22:16:03 +0000 | |||
3 | +++ lib/lp/bugs/doc/bugsubscription.txt 2011-01-20 17:50:31 +0000 | |||
4 | @@ -1,9 +1,11 @@ | |||
6 | 1 | = BugSubscription = | 1 | BugSubscription |
7 | 2 | =============== | ||
8 | 2 | 3 | ||
9 | 3 | Users can get email notifications of changes to bugs by subscribing to | 4 | Users can get email notifications of changes to bugs by subscribing to |
10 | 4 | them. | 5 | them. |
11 | 5 | 6 | ||
13 | 6 | == Bug Subscriber APIs == | 7 | Bug Subscriber APIs |
14 | 8 | ------------------- | ||
15 | 7 | 9 | ||
16 | 8 | First, let's login: | 10 | First, let's login: |
17 | 9 | 11 | ||
18 | @@ -22,7 +24,8 @@ | |||
19 | 22 | This list returns only *direct* subscribers. Bugs can also have | 24 | This list returns only *direct* subscribers. Bugs can also have |
20 | 23 | indirect subscribers. | 25 | indirect subscribers. |
21 | 24 | 26 | ||
23 | 25 | === Direct vs. Indirect Subscriptions === | 27 | Direct vs. Indirect Subscriptions |
24 | 28 | ................................. | ||
25 | 26 | 29 | ||
26 | 27 | A user is directly subscribed to a bug if they or someone else has | 30 | A user is directly subscribed to a bug if they or someone else has |
27 | 28 | subscribed them to the bug. | 31 | subscribed them to the bug. |
28 | @@ -147,6 +150,7 @@ | |||
29 | 147 | >>> subscription_no_priv = linux_source.addBugSubscription( | 150 | >>> subscription_no_priv = linux_source.addBugSubscription( |
30 | 148 | ... mr_no_privs, mr_no_privs) | 151 | ... mr_no_privs, mr_no_privs) |
31 | 149 | 152 | ||
32 | 153 | >>> transaction.commit() | ||
33 | 150 | >>> print_displayname( | 154 | >>> print_displayname( |
34 | 151 | ... sub.subscriber for sub in linux_source.bug_subscriptions) | 155 | ... sub.subscriber for sub in linux_source.bug_subscriptions) |
35 | 152 | No Privileges Person | 156 | No Privileges Person |
36 | @@ -434,12 +438,12 @@ | |||
37 | 434 | a bug, and why, IBug.getBugNotificationRecipients() assembles an | 438 | a bug, and why, IBug.getBugNotificationRecipients() assembles an |
38 | 435 | INotificationRecipientSet instance for us: | 439 | INotificationRecipientSet instance for us: |
39 | 436 | 440 | ||
41 | 437 | >>> recipients = linux_source_bug.getBugNotificationRecipients() | 441 | >>> recipients = linux_source_bug.getBugNotificationRecipients() |
42 | 438 | 442 | ||
43 | 439 | You can query for the addresses and reasons: | 443 | You can query for the addresses and reasons: |
44 | 440 | 444 | ||
47 | 441 | >>> addresses = recipients.getEmails() | 445 | >>> addresses = recipients.getEmails() |
48 | 442 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] | 446 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
49 | 443 | [('foo.bar@canonical.com', 'Subscriber'), | 447 | [('foo.bar@canonical.com', 'Subscriber'), |
50 | 444 | ('mark@example.com', 'Subscriber'), | 448 | ('mark@example.com', 'Subscriber'), |
51 | 445 | ('no-priv@canonical.com', 'Subscriber'), | 449 | ('no-priv@canonical.com', 'Subscriber'), |
52 | @@ -455,10 +459,10 @@ | |||
53 | 455 | getBugNotificationRecipients() even if the parameter level is larger than | 459 | getBugNotificationRecipients() even if the parameter level is larger than |
54 | 456 | his structural subscription setting. | 460 | his structural subscription setting. |
55 | 457 | 461 | ||
60 | 458 | >>> recipients = linux_source_bug.getBugNotificationRecipients( | 462 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
61 | 459 | ... level=BugNotificationLevel.COMMENTS) | 463 | ... level=BugNotificationLevel.COMMENTS) |
62 | 460 | >>> addresses = recipients.getEmails() | 464 | >>> addresses = recipients.getEmails() |
63 | 461 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] | 465 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
64 | 462 | [('foo.bar@canonical.com', 'Subscriber'), | 466 | [('foo.bar@canonical.com', 'Subscriber'), |
65 | 463 | ('mark@example.com', 'Subscriber'), | 467 | ('mark@example.com', 'Subscriber'), |
66 | 464 | ('no-priv@canonical.com', 'Subscriber'), | 468 | ('no-priv@canonical.com', 'Subscriber'), |
67 | @@ -470,11 +474,11 @@ | |||
68 | 470 | longer included in the result of getBugNotificationRecipients() for | 474 | longer included in the result of getBugNotificationRecipients() for |
69 | 471 | the COMMENTS level... | 475 | the COMMENTS level... |
70 | 472 | 476 | ||
76 | 473 | >>> linux_source_bug.unsubscribe(mr_no_privs, mr_no_privs) | 477 | >>> linux_source_bug.unsubscribe(mr_no_privs, mr_no_privs) |
77 | 474 | >>> recipients = linux_source_bug.getBugNotificationRecipients( | 478 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
78 | 475 | ... level=BugNotificationLevel.COMMENTS) | 479 | ... level=BugNotificationLevel.COMMENTS) |
79 | 476 | >>> addresses = recipients.getEmails() | 480 | >>> addresses = recipients.getEmails() |
80 | 477 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] | 481 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
81 | 478 | [('foo.bar@canonical.com', 'Subscriber'), | 482 | [('foo.bar@canonical.com', 'Subscriber'), |
82 | 479 | ('mark@example.com', 'Subscriber'), | 483 | ('mark@example.com', 'Subscriber'), |
83 | 480 | ('robertc@robertcollins.net', 'Subscriber'), | 484 | ('robertc@robertcollins.net', 'Subscriber'), |
84 | @@ -483,11 +487,11 @@ | |||
85 | 483 | 487 | ||
86 | 484 | ...but remains included for the level LIFECYCLE. | 488 | ...but remains included for the level LIFECYCLE. |
87 | 485 | 489 | ||
93 | 486 | >>> linux_source_bug.unsubscribe(mr_no_privs, mr_no_privs) | 490 | >>> linux_source_bug.unsubscribe(mr_no_privs, mr_no_privs) |
94 | 487 | >>> recipients = linux_source_bug.getBugNotificationRecipients( | 491 | >>> recipients = linux_source_bug.getBugNotificationRecipients( |
95 | 488 | ... level=BugNotificationLevel.LIFECYCLE) | 492 | ... level=BugNotificationLevel.LIFECYCLE) |
96 | 489 | >>> addresses = recipients.getEmails() | 493 | >>> addresses = recipients.getEmails() |
97 | 490 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] | 494 | >>> [(address, recipients.getReason(address)[1]) for address in addresses] |
98 | 491 | [('foo.bar@canonical.com', 'Subscriber'), | 495 | [('foo.bar@canonical.com', 'Subscriber'), |
99 | 492 | ('mark@example.com', 'Subscriber'), | 496 | ('mark@example.com', 'Subscriber'), |
100 | 493 | ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in ubuntu)'), | 497 | ('no-priv@canonical.com', u'Subscriber (linux-source-2.6.15 in ubuntu)'), |
101 | @@ -524,7 +528,8 @@ | |||
102 | 524 | >>> bug_five.isSubscribedToDupes(sample_person) | 528 | >>> bug_five.isSubscribedToDupes(sample_person) |
103 | 525 | True | 529 | True |
104 | 526 | 530 | ||
106 | 527 | == Subscribing and Unsubscribing == | 531 | Subscribing and Unsubscribing |
107 | 532 | ----------------------------- | ||
108 | 528 | 533 | ||
109 | 529 | To subscribe people to and unsubscribe people from a bug, use | 534 | To subscribe people to and unsubscribe people from a bug, use |
110 | 530 | IBug.subscribe and IBug.unsubscribe: | 535 | IBug.subscribe and IBug.unsubscribe: |
111 | @@ -585,7 +590,8 @@ | |||
112 | 585 | False | 590 | False |
113 | 586 | 591 | ||
114 | 587 | 592 | ||
116 | 588 | === Determining whether a user can unsubscribe someone === | 593 | Determining whether a user can unsubscribe someone |
117 | 594 | .................................................. | ||
118 | 589 | 595 | ||
119 | 590 | As user can't unsubscribe just anyone from a bug. To check whether | 596 | As user can't unsubscribe just anyone from a bug. To check whether |
120 | 591 | someone can be unusubscribed, the canBeUnsubscribedByUser() method on | 597 | someone can be unusubscribed, the canBeUnsubscribedByUser() method on |
121 | @@ -640,14 +646,12 @@ | |||
122 | 640 | UserCannotUnsubscribePerson: ... | 646 | UserCannotUnsubscribePerson: ... |
123 | 641 | 647 | ||
124 | 642 | 648 | ||
126 | 643 | == Automatic Subscriptions on Bug Creation == | 649 | Automatic Subscriptions on Bug Creation |
127 | 650 | --------------------------------------- | ||
128 | 644 | 651 | ||
129 | 645 | When a new bug is opened, only the bug reporter is automatically, explicitly | 652 | When a new bug is opened, only the bug reporter is automatically, explicitly |
130 | 646 | subscribed to the bug: | 653 | subscribed to the bug: |
131 | 647 | 654 | ||
132 | 648 | XXX: Brad Bollenbach, 2005-11-25: These bits need real sample data. See | ||
133 | 649 | https://launchpad.net/bugs/5484. | ||
134 | 650 | |||
135 | 651 | Define a function that get subscriber email addresses back conveniently: | 655 | Define a function that get subscriber email addresses back conveniently: |
136 | 652 | 656 | ||
137 | 653 | >>> def getSubscribers(bug): | 657 | >>> def getSubscribers(bug): |
138 | @@ -804,7 +808,7 @@ | |||
139 | 804 | So, if the Ubuntu team is added as a bug contact to evolution: | 808 | So, if the Ubuntu team is added as a bug contact to evolution: |
140 | 805 | 809 | ||
141 | 806 | >>> evolution.addBugSubscription(ubuntu_team, ubuntu_team) | 810 | >>> evolution.addBugSubscription(ubuntu_team, ubuntu_team) |
143 | 807 | <StructuralSubscription at ...> | 811 | <...StructuralSubscription object at ...> |
144 | 808 | 812 | ||
145 | 809 | The team will be implicitly subscribed to the previous bug we | 813 | The team will be implicitly subscribed to the previous bug we |
146 | 810 | created. (Remember that Sample Person is also implicitly subscribed | 814 | created. (Remember that Sample Person is also implicitly subscribed |
147 | @@ -848,7 +852,8 @@ | |||
148 | 848 | ['foo.bar@canonical.com', 'support@ubuntu.com'] | 852 | ['foo.bar@canonical.com', 'support@ubuntu.com'] |
149 | 849 | 853 | ||
150 | 850 | 854 | ||
152 | 851 | == Subscribed by == | 855 | Subscribed by |
153 | 856 | ------------- | ||
154 | 852 | 857 | ||
155 | 853 | Each `BugSubscription` records who created it, and provides a handy | 858 | Each `BugSubscription` records who created it, and provides a handy |
156 | 854 | utility method for formatting this information. The methods | 859 | utility method for formatting this information. The methods |
157 | 855 | 860 | ||
158 | === modified file 'lib/lp/bugs/doc/bugtask-search.txt' | |||
159 | --- lib/lp/bugs/doc/bugtask-search.txt 2010-10-25 15:03:38 +0000 | |||
160 | +++ lib/lp/bugs/doc/bugtask-search.txt 2011-01-20 17:50:31 +0000 | |||
161 | @@ -1230,7 +1230,7 @@ | |||
162 | 1230 | ... name='product-struct-subber') | 1230 | ... name='product-struct-subber') |
163 | 1231 | >>> firefox.addBugSubscription(product_struct_subber, | 1231 | >>> firefox.addBugSubscription(product_struct_subber, |
164 | 1232 | ... product_struct_subber) | 1232 | ... product_struct_subber) |
166 | 1233 | <StructuralSubscription at ...> | 1233 | <...StructuralSubscription object at ...> |
167 | 1234 | >>> product_struct_sub_search = BugTaskSearchParams( | 1234 | >>> product_struct_sub_search = BugTaskSearchParams( |
168 | 1235 | ... user=None, structural_subscriber=product_struct_subber) | 1235 | ... user=None, structural_subscriber=product_struct_subber) |
169 | 1236 | >>> found_bugtasks = bugtask_set.search(product_struct_sub_search) | 1236 | >>> found_bugtasks = bugtask_set.search(product_struct_sub_search) |
170 | @@ -1248,7 +1248,7 @@ | |||
171 | 1248 | ... name='series-struct-subber') | 1248 | ... name='series-struct-subber') |
172 | 1249 | >>> product_series.addBugSubscription(series_struct_subber, | 1249 | >>> product_series.addBugSubscription(series_struct_subber, |
173 | 1250 | ... series_struct_subber) | 1250 | ... series_struct_subber) |
175 | 1251 | <StructuralSubscription at ...> | 1251 | <...StructuralSubscription object at ...> |
176 | 1252 | >>> series_struct_sub_search = BugTaskSearchParams( | 1252 | >>> series_struct_sub_search = BugTaskSearchParams( |
177 | 1253 | ... user=None, structural_subscriber=series_struct_subber) | 1253 | ... user=None, structural_subscriber=series_struct_subber) |
178 | 1254 | >>> found_bugtasks = bugtask_set.search(series_struct_sub_search) | 1254 | >>> found_bugtasks = bugtask_set.search(series_struct_sub_search) |
179 | @@ -1269,7 +1269,7 @@ | |||
180 | 1269 | ... name='project-struct-subber') | 1269 | ... name='project-struct-subber') |
181 | 1270 | >>> project.addBugSubscription(project_struct_subber, | 1270 | >>> project.addBugSubscription(project_struct_subber, |
182 | 1271 | ... project_struct_subber) | 1271 | ... project_struct_subber) |
184 | 1272 | <StructuralSubscription at ...> | 1272 | <...StructuralSubscription object at ...> |
185 | 1273 | >>> project_struct_sub_search = BugTaskSearchParams( | 1273 | >>> project_struct_sub_search = BugTaskSearchParams( |
186 | 1274 | ... user=None, structural_subscriber=project_struct_subber) | 1274 | ... user=None, structural_subscriber=project_struct_subber) |
187 | 1275 | >>> found_bugtasks = bugtask_set.search(project_struct_sub_search) | 1275 | >>> found_bugtasks = bugtask_set.search(project_struct_sub_search) |
188 | @@ -1285,7 +1285,7 @@ | |||
189 | 1285 | >>> product2.project = project | 1285 | >>> product2.project = project |
190 | 1286 | >>> product2.addBugSubscription(project_struct_subber, | 1286 | >>> product2.addBugSubscription(project_struct_subber, |
191 | 1287 | ... project_struct_subber) | 1287 | ... project_struct_subber) |
193 | 1288 | <StructuralSubscription at ...> | 1288 | <...StructuralSubscription object at ...> |
194 | 1289 | >>> project_struct_sub_search = BugTaskSearchParams( | 1289 | >>> project_struct_sub_search = BugTaskSearchParams( |
195 | 1290 | ... user=None, structural_subscriber=project_struct_subber) | 1290 | ... user=None, structural_subscriber=project_struct_subber) |
196 | 1291 | >>> found_bugtasks = bugtask_set.search(project_struct_sub_search) | 1291 | >>> found_bugtasks = bugtask_set.search(project_struct_sub_search) |
197 | @@ -1300,7 +1300,7 @@ | |||
198 | 1300 | ... name='milestone-struct-subber') | 1300 | ... name='milestone-struct-subber') |
199 | 1301 | >>> product_milestone.addBugSubscription(milestone_struct_subber, | 1301 | >>> product_milestone.addBugSubscription(milestone_struct_subber, |
200 | 1302 | ... milestone_struct_subber) | 1302 | ... milestone_struct_subber) |
202 | 1303 | <StructuralSubscription at ...> | 1303 | <...StructuralSubscription object at ...> |
203 | 1304 | >>> milestone_struct_sub_search = BugTaskSearchParams( | 1304 | >>> milestone_struct_sub_search = BugTaskSearchParams( |
204 | 1305 | ... user=None, structural_subscriber=milestone_struct_subber) | 1305 | ... user=None, structural_subscriber=milestone_struct_subber) |
205 | 1306 | >>> found_bugtasks = bugtask_set.search(milestone_struct_sub_search) | 1306 | >>> found_bugtasks = bugtask_set.search(milestone_struct_sub_search) |
206 | @@ -1315,7 +1315,7 @@ | |||
207 | 1315 | ... name='distro-struct-subber') | 1315 | ... name='distro-struct-subber') |
208 | 1316 | >>> ubuntu.addBugSubscription(distro_struct_subber, | 1316 | >>> ubuntu.addBugSubscription(distro_struct_subber, |
209 | 1317 | ... distro_struct_subber) | 1317 | ... distro_struct_subber) |
211 | 1318 | <StructuralSubscription at ...> | 1318 | <...StructuralSubscription object at ...> |
212 | 1319 | >>> distro_struct_sub_search = BugTaskSearchParams( | 1319 | >>> distro_struct_sub_search = BugTaskSearchParams( |
213 | 1320 | ... user=None, structural_subscriber=distro_struct_subber) | 1320 | ... user=None, structural_subscriber=distro_struct_subber) |
214 | 1321 | >>> found_bugtasks = bugtask_set.search(distro_struct_sub_search) | 1321 | >>> found_bugtasks = bugtask_set.search(distro_struct_sub_search) |
215 | @@ -1332,7 +1332,7 @@ | |||
216 | 1332 | ... name='distro-series-struct-subber') | 1332 | ... name='distro-series-struct-subber') |
217 | 1333 | >>> hoary.addBugSubscription(distro_series_struct_subber, | 1333 | >>> hoary.addBugSubscription(distro_series_struct_subber, |
218 | 1334 | ... distro_series_struct_subber) | 1334 | ... distro_series_struct_subber) |
220 | 1335 | <StructuralSubscription at ...> | 1335 | <...StructuralSubscription object at ...> |
221 | 1336 | >>> distro_series_struct_sub_search = BugTaskSearchParams( | 1336 | >>> distro_series_struct_sub_search = BugTaskSearchParams( |
222 | 1337 | ... user=None, structural_subscriber=distro_series_struct_subber) | 1337 | ... user=None, structural_subscriber=distro_series_struct_subber) |
223 | 1338 | >>> found_bugtasks = bugtask_set.search(distro_series_struct_sub_search) | 1338 | >>> found_bugtasks = bugtask_set.search(distro_series_struct_sub_search) |
224 | @@ -1349,7 +1349,7 @@ | |||
225 | 1349 | ... name='package-struct-subber') | 1349 | ... name='package-struct-subber') |
226 | 1350 | >>> ubuntu_firefox.addBugSubscription(package_struct_subber, | 1350 | >>> ubuntu_firefox.addBugSubscription(package_struct_subber, |
227 | 1351 | ... package_struct_subber) | 1351 | ... package_struct_subber) |
229 | 1352 | <StructuralSubscription at ...> | 1352 | <...StructuralSubscription object at ...> |
230 | 1353 | >>> package_struct_sub_search = BugTaskSearchParams( | 1353 | >>> package_struct_sub_search = BugTaskSearchParams( |
231 | 1354 | ... user=None, structural_subscriber=package_struct_subber) | 1354 | ... user=None, structural_subscriber=package_struct_subber) |
232 | 1355 | >>> found_bugtasks = bugtask_set.search(package_struct_sub_search) | 1355 | >>> found_bugtasks = bugtask_set.search(package_struct_sub_search) |
233 | @@ -1363,7 +1363,7 @@ | |||
234 | 1363 | 1363 | ||
235 | 1364 | >>> product_series.addBugSubscription(package_struct_subber, | 1364 | >>> product_series.addBugSubscription(package_struct_subber, |
236 | 1365 | ... package_struct_subber) | 1365 | ... package_struct_subber) |
238 | 1366 | <StructuralSubscription at ...> | 1366 | <...StructuralSubscription object at ...> |
239 | 1367 | >>> package_struct_sub_search = BugTaskSearchParams( | 1367 | >>> package_struct_sub_search = BugTaskSearchParams( |
240 | 1368 | ... user=None, structural_subscriber=package_struct_subber) | 1368 | ... user=None, structural_subscriber=package_struct_subber) |
241 | 1369 | >>> found_bugtasks = bugtask_set.search(package_struct_sub_search) | 1369 | >>> found_bugtasks = bugtask_set.search(package_struct_sub_search) |
242 | 1370 | 1370 | ||
243 | === modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt' | |||
244 | --- lib/lp/bugs/doc/initial-bug-contacts.txt 2010-12-24 11:02:19 +0000 | |||
245 | +++ lib/lp/bugs/doc/initial-bug-contacts.txt 2011-01-20 17:50:31 +0000 | |||
246 | @@ -38,7 +38,7 @@ | |||
247 | 38 | >>> login("foo.bar@canonical.com") | 38 | >>> login("foo.bar@canonical.com") |
248 | 39 | 39 | ||
249 | 40 | >>> debian_firefox.addBugSubscription(sample_person, sample_person) | 40 | >>> debian_firefox.addBugSubscription(sample_person, sample_person) |
251 | 41 | <StructuralSubscription ...> | 41 | <...StructuralSubscription object at ...> |
252 | 42 | >>> [pbc.subscriber.name for pbc in debian_firefox.bug_subscriptions] | 42 | >>> [pbc.subscriber.name for pbc in debian_firefox.bug_subscriptions] |
253 | 43 | [u'name12'] | 43 | [u'name12'] |
254 | 44 | 44 | ||
255 | @@ -46,13 +46,13 @@ | |||
256 | 46 | already subscribe to that package will return the existing subscription. | 46 | already subscribe to that package will return the existing subscription. |
257 | 47 | 47 | ||
258 | 48 | >>> debian_firefox.addBugSubscription(sample_person, sample_person) | 48 | >>> debian_firefox.addBugSubscription(sample_person, sample_person) |
260 | 49 | <StructuralSubscription ...> | 49 | <...StructuralSubscription object at ...> |
261 | 50 | 50 | ||
262 | 51 | Let's add an ITeam as one of the subscribers: | 51 | Let's add an ITeam as one of the subscribers: |
263 | 52 | 52 | ||
264 | 53 | >>> ubuntu_team = personset.getByName("ubuntu-team") | 53 | >>> ubuntu_team = personset.getByName("ubuntu-team") |
265 | 54 | >>> debian_firefox.addBugSubscription(ubuntu_team, ubuntu_team) | 54 | >>> debian_firefox.addBugSubscription(ubuntu_team, ubuntu_team) |
267 | 55 | <StructuralSubscription ...> | 55 | <...StructuralSubscription object at ...> |
268 | 56 | 56 | ||
269 | 57 | >>> sorted([sub.subscriber.name for sub in debian_firefox.bug_subscriptions]) | 57 | >>> sorted([sub.subscriber.name for sub in debian_firefox.bug_subscriptions]) |
270 | 58 | [u'name12', u'ubuntu-team'] | 58 | [u'name12', u'ubuntu-team'] |
271 | @@ -125,9 +125,9 @@ | |||
272 | 125 | 125 | ||
273 | 126 | >>> daf = personset.getByName("daf") | 126 | >>> daf = personset.getByName("daf") |
274 | 127 | >>> ubuntu_pmount.addBugSubscription(daf, daf) | 127 | >>> ubuntu_pmount.addBugSubscription(daf, daf) |
276 | 128 | <StructuralSubscription ...> | 128 | <...StructuralSubscription object at ...> |
277 | 129 | >>> ubuntu_pmount.addBugSubscription(sample_person, sample_person) | 129 | >>> ubuntu_pmount.addBugSubscription(sample_person, sample_person) |
279 | 130 | <StructuralSubscription ...> | 130 | <...StructuralSubscription object at ...> |
280 | 131 | 131 | ||
281 | 132 | >>> old_state = Snapshot( | 132 | >>> old_state = Snapshot( |
282 | 133 | ... bug_one_in_ubuntu_firefox, providing=IDistroBugTask) | 133 | ... bug_one_in_ubuntu_firefox, providing=IDistroBugTask) |
283 | @@ -247,7 +247,7 @@ | |||
284 | 247 | >>> ubuntu_gnome.preferredemail is None | 247 | >>> ubuntu_gnome.preferredemail is None |
285 | 248 | True | 248 | True |
286 | 249 | >>> ubuntu_pmount.addBugSubscription(ubuntu_gnome, ubuntu_gnome) | 249 | >>> ubuntu_pmount.addBugSubscription(ubuntu_gnome, ubuntu_gnome) |
288 | 250 | <StructuralSubscription ...> | 250 | <...StructuralSubscription object at ...> |
289 | 251 | 251 | ||
290 | 252 | >>> old_state = Snapshot( | 252 | >>> old_state = Snapshot( |
291 | 253 | ... bug_one_in_ubuntu_firefox, providing=IDistroBugTask) | 253 | ... bug_one_in_ubuntu_firefox, providing=IDistroBugTask) |
292 | @@ -279,7 +279,7 @@ | |||
293 | 279 | 279 | ||
294 | 280 | >>> pitti = personset.getByName("martin-pitt") | 280 | >>> pitti = personset.getByName("martin-pitt") |
295 | 281 | >>> ubuntu_firefox.addBugSubscription(pitti, pitti) | 281 | >>> ubuntu_firefox.addBugSubscription(pitti, pitti) |
297 | 282 | <StructuralSubscription ...> | 282 | <...StructuralSubscription object at ...> |
298 | 283 | 283 | ||
299 | 284 | and then the bug gets reassigned to mozilla firefox: | 284 | and then the bug gets reassigned to mozilla firefox: |
300 | 285 | 285 | ||
301 | 286 | 286 | ||
302 | === modified file 'lib/lp/bugs/stories/patches-view/patches-view.txt' | |||
303 | --- lib/lp/bugs/stories/patches-view/patches-view.txt 2010-07-17 21:02:11 +0000 | |||
304 | +++ lib/lp/bugs/stories/patches-view/patches-view.txt 2011-01-20 17:50:31 +0000 | |||
305 | @@ -420,7 +420,7 @@ | |||
306 | 420 | ... name="project-subscriber", displayname="Project Subscriber") | 420 | ... name="project-subscriber", displayname="Project Subscriber") |
307 | 421 | >>> add_bug_sub = lambda *args: patchy_product.addBugSubscription(*args) | 421 | >>> add_bug_sub = lambda *args: patchy_product.addBugSubscription(*args) |
308 | 422 | >>> with_anybody(add_bug_sub)(project_subscriber, project_subscriber) | 422 | >>> with_anybody(add_bug_sub)(project_subscriber, project_subscriber) |
310 | 423 | <StructuralSubscription at ...> | 423 | <...StructuralSubscription object at ...> |
311 | 424 | >>> from zope.security.proxy import removeSecurityProxy | 424 | >>> from zope.security.proxy import removeSecurityProxy |
312 | 425 | >>> subscriber_name = removeSecurityProxy(project_subscriber).name | 425 | >>> subscriber_name = removeSecurityProxy(project_subscriber).name |
313 | 426 | >>> anon_browser.open( | 426 | >>> anon_browser.open( |
314 | 427 | 427 | ||
315 | === modified file 'lib/lp/bugs/tests/bugs-emailinterface.txt' | |||
316 | --- lib/lp/bugs/tests/bugs-emailinterface.txt 2010-12-13 13:40:38 +0000 | |||
317 | +++ lib/lp/bugs/tests/bugs-emailinterface.txt 2011-01-20 17:50:31 +0000 | |||
318 | @@ -1679,7 +1679,7 @@ | |||
319 | 1679 | >>> helge = getUtility(IPersonSet).getByName('kreutzm') | 1679 | >>> helge = getUtility(IPersonSet).getByName('kreutzm') |
320 | 1680 | >>> mozilla_package = ubuntu.getSourcePackage(mozilla_name) | 1680 | >>> mozilla_package = ubuntu.getSourcePackage(mozilla_name) |
321 | 1681 | >>> mozilla_package.addBugSubscription(helge, helge) | 1681 | >>> mozilla_package.addBugSubscription(helge, helge) |
323 | 1682 | <StructuralSubscription ...> | 1682 | <...StructuralSubscription ...> |
324 | 1683 | >>> commit() | 1683 | >>> commit() |
325 | 1684 | >>> LaunchpadZopelessLayer.switchDbUser(config.processmail.dbuser) | 1684 | >>> LaunchpadZopelessLayer.switchDbUser(config.processmail.dbuser) |
326 | 1685 | 1685 | ||
327 | 1686 | 1686 | ||
328 | === modified file 'lib/lp/registry/browser/tests/milestone-views.txt' | |||
329 | --- lib/lp/registry/browser/tests/milestone-views.txt 2010-11-02 20:10:56 +0000 | |||
330 | +++ lib/lp/registry/browser/tests/milestone-views.txt 2011-01-20 17:50:31 +0000 | |||
331 | @@ -682,7 +682,7 @@ | |||
332 | 682 | >>> bugtask.milestone = milestone | 682 | >>> bugtask.milestone = milestone |
333 | 683 | >>> subscription = milestone.addSubscription(owner, owner) | 683 | >>> subscription = milestone.addSubscription(owner, owner) |
334 | 684 | >>> [subscription for subscription in owner.structural_subscriptions] | 684 | >>> [subscription for subscription in owner.structural_subscriptions] |
336 | 685 | [<StructuralSubscription ...>] | 685 | [<...StructuralSubscription ...>] |
337 | 686 | 686 | ||
338 | 687 | >>> view = create_initialized_view(milestone, '+delete') | 687 | >>> view = create_initialized_view(milestone, '+delete') |
339 | 688 | >>> [bugtask.milestone.name for bugtask in view.bugtasks] | 688 | >>> [bugtask.milestone.name for bugtask in view.bugtasks] |
340 | 689 | 689 | ||
341 | === modified file 'lib/lp/registry/doc/milestone.txt' | |||
342 | --- lib/lp/registry/doc/milestone.txt 2010-12-22 00:07:36 +0000 | |||
343 | +++ lib/lp/registry/doc/milestone.txt 2011-01-20 17:50:31 +0000 | |||
344 | @@ -348,10 +348,10 @@ | |||
345 | 348 | >>> cprov = getUtility(IPersonSet).getByName('cprov') | 348 | >>> cprov = getUtility(IPersonSet).getByName('cprov') |
346 | 349 | >>> ddaa = getUtility(IPersonSet).getByName('ddaa') | 349 | >>> ddaa = getUtility(IPersonSet).getByName('ddaa') |
347 | 350 | >>> milestone_one.addBugSubscription(cprov, cprov) | 350 | >>> milestone_one.addBugSubscription(cprov, cprov) |
349 | 351 | <StructuralSubscription at ...> | 351 | <...StructuralSubscription object at ...> |
350 | 352 | 352 | ||
351 | 353 | >>> milestone_two.addBugSubscription(ddaa, ddaa) | 353 | >>> milestone_two.addBugSubscription(ddaa, ddaa) |
353 | 354 | <StructuralSubscription at ...> | 354 | <...StructuralSubscription object at ...> |
354 | 355 | 355 | ||
355 | 356 | We change the milestone for the task from 1.0 to 2.0, and fire the | 356 | We change the milestone for the task from 1.0 to 2.0, and fire the |
356 | 357 | change event. | 357 | change event. |
357 | 358 | 358 | ||
358 | === modified file 'lib/lp/registry/doc/person.txt' | |||
359 | --- lib/lp/registry/doc/person.txt 2010-12-07 00:58:46 +0000 | |||
360 | +++ lib/lp/registry/doc/person.txt 2011-01-20 17:50:31 +0000 | |||
361 | @@ -1027,11 +1027,11 @@ | |||
362 | 1027 | >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') | 1027 | >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu') |
363 | 1028 | >>> pmount = ubuntu.getSourcePackage('pmount') | 1028 | >>> pmount = ubuntu.getSourcePackage('pmount') |
364 | 1029 | >>> pmount.addBugSubscription(no_priv, no_priv) | 1029 | >>> pmount.addBugSubscription(no_priv, no_priv) |
366 | 1030 | <StructuralSubscription at ...> | 1030 | <...StructuralSubscription object at ...> |
367 | 1031 | 1031 | ||
368 | 1032 | >>> mozilla_firefox = ubuntu.getSourcePackage('mozilla-firefox') | 1032 | >>> mozilla_firefox = ubuntu.getSourcePackage('mozilla-firefox') |
369 | 1033 | >>> mozilla_firefox.addBugSubscription(no_priv, no_priv) | 1033 | >>> mozilla_firefox.addBugSubscription(no_priv, no_priv) |
371 | 1034 | <StructuralSubscription at ...> | 1034 | <...StructuralSubscription object at ...> |
372 | 1035 | 1035 | ||
373 | 1036 | >>> [package.name for package in no_priv.getBugSubscriberPackages()] | 1036 | >>> [package.name for package in no_priv.getBugSubscriberPackages()] |
374 | 1037 | [u'mozilla-firefox', u'pmount'] | 1037 | [u'mozilla-firefox', u'pmount'] |
375 | 1038 | 1038 | ||
376 | === modified file 'lib/lp/registry/model/person.py' | |||
377 | --- lib/lp/registry/model/person.py 2011-01-18 04:40:41 +0000 | |||
378 | +++ lib/lp/registry/model/person.py 2011-01-20 17:50:31 +0000 | |||
379 | @@ -2713,8 +2713,10 @@ | |||
380 | 2713 | @property | 2713 | @property |
381 | 2714 | def structural_subscriptions(self): | 2714 | def structural_subscriptions(self): |
382 | 2715 | """See `IPerson`.""" | 2715 | """See `IPerson`.""" |
385 | 2716 | return StructuralSubscription.selectBy( | 2716 | return IStore(self).find( |
386 | 2717 | subscriber=self, orderBy=['-date_created']) | 2717 | StructuralSubscription, |
387 | 2718 | StructuralSubscription.subscriberID==self.id).order_by( | ||
388 | 2719 | Desc(StructuralSubscription.date_created)) | ||
389 | 2718 | 2720 | ||
390 | 2719 | def autoSubscribeToMailingList(self, mailinglist, requester=None): | 2721 | def autoSubscribeToMailingList(self, mailinglist, requester=None): |
391 | 2720 | """See `IPerson`.""" | 2722 | """See `IPerson`.""" |
392 | 2721 | 2723 | ||
393 | === modified file 'lib/lp/registry/model/structuralsubscription.py' | |||
394 | --- lib/lp/registry/model/structuralsubscription.py 2011-01-19 18:12:07 +0000 | |||
395 | +++ lib/lp/registry/model/structuralsubscription.py 2011-01-20 17:50:31 +0000 | |||
396 | @@ -15,6 +15,7 @@ | |||
397 | 15 | Reference, | 15 | Reference, |
398 | 16 | ) | 16 | ) |
399 | 17 | 17 | ||
400 | 18 | from storm.base import Storm | ||
401 | 18 | from storm.expr import ( | 19 | from storm.expr import ( |
402 | 19 | Alias, | 20 | Alias, |
403 | 20 | And, | 21 | And, |
404 | @@ -39,10 +40,7 @@ | |||
405 | 39 | 40 | ||
406 | 40 | from canonical.database.constants import UTC_NOW | 41 | from canonical.database.constants import UTC_NOW |
407 | 41 | from canonical.database.enumcol import DBEnum | 42 | from canonical.database.enumcol import DBEnum |
412 | 42 | from canonical.database.sqlbase import ( | 43 | from canonical.database.sqlbase import quote |
409 | 43 | quote, | ||
410 | 44 | SQLBase, | ||
411 | 45 | ) | ||
413 | 46 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities | 44 | from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities |
414 | 47 | from canonical.launchpad.interfaces.lpstorm import IStore | 45 | from canonical.launchpad.interfaces.lpstorm import IStore |
415 | 48 | from lp.bugs.model.bugsubscriptionfilter import BugSubscriptionFilter | 46 | from lp.bugs.model.bugsubscriptionfilter import BugSubscriptionFilter |
416 | @@ -80,13 +78,11 @@ | |||
417 | 80 | from lp.services.propertycache import cachedproperty | 78 | from lp.services.propertycache import cachedproperty |
418 | 81 | 79 | ||
419 | 82 | 80 | ||
421 | 83 | class StructuralSubscription(SQLBase): | 81 | class StructuralSubscription(Storm): |
422 | 84 | """A subscription to a Launchpad structure.""" | 82 | """A subscription to a Launchpad structure.""" |
423 | 85 | 83 | ||
424 | 86 | implements(IStructuralSubscription) | 84 | implements(IStructuralSubscription) |
425 | 87 | 85 | ||
426 | 88 | _table = 'StructuralSubscription' | ||
427 | 89 | |||
428 | 90 | __storm_table__ = 'StructuralSubscription' | 86 | __storm_table__ = 'StructuralSubscription' |
429 | 91 | 87 | ||
430 | 92 | id = Int(primary=True) | 88 | id = Int(primary=True) |
431 | @@ -135,6 +131,12 @@ | |||
432 | 135 | "date_last_updated", allow_none=False, default=UTC_NOW, | 131 | "date_last_updated", allow_none=False, default=UTC_NOW, |
433 | 136 | tzinfo=pytz.UTC) | 132 | tzinfo=pytz.UTC) |
434 | 137 | 133 | ||
435 | 134 | def __init__(self, subscriber, subscribed_by, **kwargs): | ||
436 | 135 | self.subscriber = subscriber | ||
437 | 136 | self.subscribed_by = subscribed_by | ||
438 | 137 | for arg, value in kwargs.iteritems(): | ||
439 | 138 | setattr(self, arg, value) | ||
440 | 139 | |||
441 | 138 | @property | 140 | @property |
442 | 139 | def target(self): | 141 | def target(self): |
443 | 140 | """See `IStructuralSubscription`.""" | 142 | """See `IStructuralSubscription`.""" |
444 | @@ -427,13 +429,9 @@ | |||
445 | 427 | '%s does not have permission to unsubscribe %s.' % ( | 429 | '%s does not have permission to unsubscribe %s.' % ( |
446 | 428 | unsubscribed_by.name, subscriber.name)) | 430 | unsubscribed_by.name, subscriber.name)) |
447 | 429 | 431 | ||
455 | 430 | subscription_to_remove = None | 432 | subscription_to_remove = self.getSubscriptions( |
456 | 431 | for subscription in self.getSubscriptions( | 433 | min_bug_notification_level=BugNotificationLevel.METADATA, |
457 | 432 | min_bug_notification_level=BugNotificationLevel.METADATA): | 434 | subscriber=subscriber).one() |
451 | 433 | # Only search for bug subscriptions | ||
452 | 434 | if subscription.subscriber == subscriber: | ||
453 | 435 | subscription_to_remove = subscription | ||
454 | 436 | break | ||
458 | 437 | 435 | ||
459 | 438 | if subscription_to_remove is None: | 436 | if subscription_to_remove is None: |
460 | 439 | raise DeleteSubscriptionError( | 437 | raise DeleteSubscriptionError( |
461 | @@ -447,39 +445,44 @@ | |||
462 | 447 | subscription_to_remove.bug_notification_level = ( | 445 | subscription_to_remove.bug_notification_level = ( |
463 | 448 | BugNotificationLevel.NOTHING) | 446 | BugNotificationLevel.NOTHING) |
464 | 449 | else: | 447 | else: |
466 | 450 | subscription_to_remove.destroySelf() | 448 | store = Store.of(subscription_to_remove) |
467 | 449 | store.remove(subscription_to_remove) | ||
468 | 451 | 450 | ||
469 | 452 | def getSubscription(self, person): | 451 | def getSubscription(self, person): |
470 | 453 | """See `IStructuralSubscriptionTarget`.""" | 452 | """See `IStructuralSubscriptionTarget`.""" |
476 | 454 | all_subscriptions = self.getSubscriptions() | 453 | # getSubscriptions returns all subscriptions regardless of |
477 | 455 | for subscription in all_subscriptions: | 454 | # the person for person==None, so we special-case that. |
478 | 456 | if subscription.subscriber == person: | 455 | if person is None: |
479 | 457 | return subscription | 456 | return None |
480 | 458 | return None | 457 | all_subscriptions = self.getSubscriptions(subscriber=person) |
481 | 458 | return all_subscriptions.one() | ||
482 | 459 | 459 | ||
483 | 460 | def getSubscriptions(self, | 460 | def getSubscriptions(self, |
484 | 461 | min_bug_notification_level= | 461 | min_bug_notification_level= |
485 | 462 | BugNotificationLevel.NOTHING, | 462 | BugNotificationLevel.NOTHING, |
486 | 463 | min_blueprint_notification_level= | 463 | min_blueprint_notification_level= |
488 | 464 | BlueprintNotificationLevel.NOTHING): | 464 | BlueprintNotificationLevel.NOTHING, |
489 | 465 | subscriber=None): | ||
490 | 465 | """See `IStructuralSubscriptionTarget`.""" | 466 | """See `IStructuralSubscriptionTarget`.""" |
491 | 467 | from lp.registry.model.person import Person | ||
492 | 466 | clauses = [ | 468 | clauses = [ |
498 | 467 | "StructuralSubscription.subscriber = Person.id", | 469 | StructuralSubscription.subscriberID==Person.id, |
499 | 468 | "StructuralSubscription.bug_notification_level " | 470 | (StructuralSubscription.bug_notification_level >= |
500 | 469 | ">= %s" % quote(min_bug_notification_level), | 471 | min_bug_notification_level), |
501 | 470 | "StructuralSubscription.blueprint_notification_level " | 472 | (StructuralSubscription.blueprint_notification_level >= |
502 | 471 | ">= %s" % quote(min_blueprint_notification_level), | 473 | min_blueprint_notification_level), |
503 | 472 | ] | 474 | ] |
504 | 473 | for key, value in self._target_args.iteritems(): | 475 | for key, value in self._target_args.iteritems(): |
514 | 474 | if value is None: | 476 | clauses.append( |
515 | 475 | clauses.append( | 477 | getattr(StructuralSubscription, key)==value) |
516 | 476 | "StructuralSubscription.%s IS NULL" % (key,)) | 478 | |
517 | 477 | else: | 479 | if subscriber is not None: |
518 | 478 | clauses.append( | 480 | clauses.append( |
519 | 479 | "StructuralSubscription.%s = %s" % (key, quote(value))) | 481 | StructuralSubscription.subscriberID==subscriber.id) |
520 | 480 | query = " AND ".join(clauses) | 482 | |
521 | 481 | return StructuralSubscription.select( | 483 | store = Store.of(self.__helper.pillar) |
522 | 482 | query, orderBy='Person.displayname', clauseTables=['Person']) | 484 | return store.find( |
523 | 485 | StructuralSubscription, *clauses).order_by('Person.displayname') | ||
524 | 483 | 486 | ||
525 | 484 | @property | 487 | @property |
526 | 485 | def bug_subscriptions(self): | 488 | def bug_subscriptions(self): |
527 | 486 | 489 | ||
528 | === modified file 'lib/lp/registry/templates/person-structural-subscriptions.pt' | |||
529 | --- lib/lp/registry/templates/person-structural-subscriptions.pt 2011-01-13 16:30:15 +0000 | |||
530 | +++ lib/lp/registry/templates/person-structural-subscriptions.pt 2011-01-20 17:50:31 +0000 | |||
531 | @@ -23,7 +23,7 @@ | |||
532 | 23 | <div class="yui-g"> | 23 | <div class="yui-g"> |
533 | 24 | <div class="portlet" id="structural-subscriptions"> | 24 | <div class="portlet" id="structural-subscriptions"> |
534 | 25 | 25 | ||
536 | 26 | <ul tal:condition="structural_subscriptions"> | 26 | <ul tal:condition="python:not structural_subscriptions.is_empty()"> |
537 | 27 | <li tal:repeat="subscription structural_subscriptions" | 27 | <li tal:repeat="subscription structural_subscriptions" |
538 | 28 | style="margin: 1em 0em; padding: 1em; border: 1px solid #ddd;"> | 28 | style="margin: 1em 0em; padding: 1em; border: 1px solid #ddd;"> |
539 | 29 | <span tal:replace="structure subscription/target/fmt:link" /> | 29 | <span tal:replace="structure subscription/target/fmt:link" /> |
540 | @@ -74,7 +74,7 @@ | |||
541 | 74 | </li> | 74 | </li> |
542 | 75 | </ul> | 75 | </ul> |
543 | 76 | 76 | ||
545 | 77 | <p tal:condition="not: structural_subscriptions"> | 77 | <p tal:condition="python: structural_subscriptions.is_empty()"> |
546 | 78 | <tal:person content="context/fmt:displayname" /> does not | 78 | <tal:person content="context/fmt:displayname" /> does not |
547 | 79 | have any structural subscriptions. | 79 | have any structural subscriptions. |
548 | 80 | </p> | 80 | </p> |
549 | 81 | 81 | ||
550 | === modified file 'lib/lp/registry/tests/structural-subscription-target.txt' | |||
551 | --- lib/lp/registry/tests/structural-subscription-target.txt 2010-10-17 15:44:08 +0000 | |||
552 | +++ lib/lp/registry/tests/structural-subscription-target.txt 2011-01-20 17:50:31 +0000 | |||
553 | @@ -11,7 +11,7 @@ | |||
554 | 11 | >>> from canonical.launchpad.ftests import login | 11 | >>> from canonical.launchpad.ftests import login |
555 | 12 | >>> login("foo.bar@canonical.com") | 12 | >>> login("foo.bar@canonical.com") |
556 | 13 | >>> target.addBugSubscription(ubuntu_team, foobar) | 13 | >>> target.addBugSubscription(ubuntu_team, foobar) |
558 | 14 | <StructuralSubscription ...> | 14 | <...StructuralSubscription ...> |
559 | 15 | 15 | ||
560 | 16 | Trying to remove a bug subscription when notification levels for other | 16 | Trying to remove a bug subscription when notification levels for other |
561 | 17 | applications are set, doesn't remove the subscription. Instead the | 17 | applications are set, doesn't remove the subscription. Instead the |
562 | @@ -41,7 +41,7 @@ | |||
563 | 41 | IStructuralSubscriptionTarget.getSubscription. | 41 | IStructuralSubscriptionTarget.getSubscription. |
564 | 42 | 42 | ||
565 | 43 | >>> target.getSubscription(ubuntu_team) | 43 | >>> target.getSubscription(ubuntu_team) |
567 | 44 | <StructuralSubscription ...> | 44 | <...StructuralSubscription ...> |
568 | 45 | >>> print target.getSubscription(no_priv) | 45 | >>> print target.getSubscription(no_priv) |
569 | 46 | None | 46 | None |
570 | 47 | 47 |
We can't use the Storm base class directly, we need a launchpad
specific one with CachedProperty __invalidate__ hooked in.