Merge lp:~gary/launchpad/bug723999-2b into lp:launchpad

Proposed by Gary Poster
Status: Merged
Merged at revision: 12548
Proposed branch: lp:~gary/launchpad/bug723999-2b
Merge into: lp:launchpad
Prerequisite: lp:~gary/launchpad/bug723999-2a
Diff against target: 770 lines (+342/-340)
2 files modified
lib/lp/bugs/tests/test_structuralsubscription.py (+341/-1)
lib/lp/bugs/tests/test_structuralsubscriptiontarget.py (+1/-339)
To merge this branch: bzr merge lp:~gary/launchpad/bug723999-2b
Reviewer Review Type Date Requested Status
Benji York (community) code Approve
Review via email: mp+52429@code.launchpad.net

Description of the change

This branch builds on ~gary/launchpad/bug723999-2a to simply move the tests that had changed in that branch to what I believe is now a more appropriate location, in lib/lp/bugs/tests/test_structuralsubscription.py. That's all I did. make lint was happy without any tweaks.

Thank you

Gary

To post a comment you must log in.
Revision history for this message
Benji York (benji) wrote :

Looks good. I did a little processing of the diff so I could prove to myself that all the code that was removed was put back and that no changes were introduced in the process. Everything made the trip unscathed.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/tests/test_structuralsubscription.py'
2--- lib/lp/bugs/tests/test_structuralsubscription.py 2011-02-18 15:49:10 +0000
3+++ lib/lp/bugs/tests/test_structuralsubscription.py 2011-03-07 16:14:59 +0000
4@@ -8,10 +8,20 @@
5 from storm.store import Store
6 from zope.security.interfaces import Unauthorized
7
8-from canonical.testing.layers import DatabaseFunctionalLayer
9+from canonical.testing.layers import (
10+ LaunchpadFunctionalLayer,
11+ DatabaseFunctionalLayer,
12+ )
13+from lp.bugs.enum import BugNotificationLevel
14+from lp.bugs.interfaces.bugtask import (
15+ BugTaskImportance,
16+ BugTaskStatus,
17+ )
18 from lp.bugs.model.bugsubscriptionfilter import BugSubscriptionFilter
19+from lp.bugs.model.structuralsubscription import get_structural_subscribers
20 from lp.testing import (
21 anonymous_logged_in,
22+ login_person,
23 person_logged_in,
24 TestCaseWithFactory,
25 )
26@@ -104,3 +114,333 @@
27 with person_logged_in(self.factory.makePerson()):
28 self.assertRaises(
29 Unauthorized, lambda: self.subscription.newBugFilter)
30+
31+
32+class FilteredStructuralSubscriptionTestBase:
33+ """Tests for filtered structural subscriptions."""
34+
35+ layer = LaunchpadFunctionalLayer
36+
37+ def makeTarget(self):
38+ raise NotImplementedError(self.makeTarget)
39+
40+ def makeBugTask(self):
41+ return self.factory.makeBugTask(target=self.target)
42+
43+ def setUp(self):
44+ super(FilteredStructuralSubscriptionTestBase, self).setUp()
45+ self.ordinary_subscriber = self.factory.makePerson()
46+ login_person(self.ordinary_subscriber)
47+ self.target = self.makeTarget()
48+ self.bugtask = self.makeBugTask()
49+ self.bug = self.bugtask.bug
50+ self.subscription = self.target.addSubscription(
51+ self.ordinary_subscriber, self.ordinary_subscriber)
52+ self.initial_filter = self.subscription.bug_filters[0]
53+
54+ def assertSubscribers(
55+ self, expected_subscribers, level=BugNotificationLevel.NOTHING):
56+ observed_subscribers = list(
57+ get_structural_subscribers(self.bugtask, None, level))
58+ self.assertEqual(expected_subscribers, observed_subscribers)
59+
60+ def test_getStructuralSubscribers(self):
61+ # If no one has a filtered subscription for the given bug, the result
62+ # of get_structural_subscribers() is the same as for
63+ # the set of people from each subscription in getSubscriptions().
64+ subscriptions = self.target.getSubscriptions()
65+ self.assertSubscribers([sub.subscriber for sub in subscriptions])
66+
67+ def test_getStructuralSubscribers_with_filter_on_status(self):
68+ # If a status filter exists for a subscription, the result of
69+ # get_structural_subscribers() may be a subset of getSubscriptions().
70+
71+ # Without any filters the subscription is found.
72+ self.assertSubscribers([self.ordinary_subscriber])
73+
74+ # Filter the subscription to bugs in the CONFIRMED state.
75+ self.initial_filter.statuses = [BugTaskStatus.CONFIRMED]
76+
77+ # With the filter the subscription is not found.
78+ self.assertSubscribers([])
79+
80+ # If the filter is adjusted, the subscription is found again.
81+ self.initial_filter.statuses = [self.bugtask.status]
82+ self.assertSubscribers([self.ordinary_subscriber])
83+
84+ def test_getStructuralSubscribers_with_filter_on_importance(self):
85+ # If an importance filter exists for a subscription, the result of
86+ # get_structural_subscribers() may be a subset of getSubscriptions().
87+
88+ # Without any filters the subscription is found.
89+ self.assertSubscribers([self.ordinary_subscriber])
90+
91+ # Filter the subscription to bugs in the CRITICAL state.
92+ self.initial_filter.importances = [BugTaskImportance.CRITICAL]
93+
94+ # With the filter the subscription is not found.
95+ self.assertSubscribers([])
96+
97+ # If the filter is adjusted, the subscription is found again.
98+ self.initial_filter.importances = [self.bugtask.importance]
99+ self.assertSubscribers([self.ordinary_subscriber])
100+
101+ def test_getStructuralSubscribers_with_filter_on_level(self):
102+ # All structural subscriptions have a level for bug notifications
103+ # which get_structural_subscribers() observes.
104+
105+ # Adjust the subscription level to METADATA.
106+ self.initial_filter.bug_notification_level = (
107+ BugNotificationLevel.METADATA)
108+
109+ # The subscription is found when looking for NOTHING or above.
110+ self.assertSubscribers(
111+ [self.ordinary_subscriber], BugNotificationLevel.NOTHING)
112+ # The subscription is found when looking for METADATA or above.
113+ self.assertSubscribers(
114+ [self.ordinary_subscriber], BugNotificationLevel.METADATA)
115+ # The subscription is not found when looking for COMMENTS or above.
116+ self.assertSubscribers(
117+ [], BugNotificationLevel.COMMENTS)
118+
119+ def test_getStructuralSubscribers_with_filter_include_any_tags(self):
120+ # If a subscription filter has include_any_tags, a bug with one or
121+ # more tags is matched.
122+
123+ self.initial_filter.include_any_tags = True
124+
125+ # Without any tags the subscription is not found.
126+ self.assertSubscribers([])
127+
128+ # With any tag the subscription is found.
129+ self.bug.tags = ["foo"]
130+ self.assertSubscribers([self.ordinary_subscriber])
131+
132+ def test_getStructuralSubscribers_with_filter_exclude_any_tags(self):
133+ # If a subscription filter has exclude_any_tags, only bugs with no
134+ # tags are matched.
135+
136+ self.initial_filter.exclude_any_tags = True
137+
138+ # Without any tags the subscription is found.
139+ self.assertSubscribers([self.ordinary_subscriber])
140+
141+ # With any tag the subscription is not found.
142+ self.bug.tags = ["foo"]
143+ self.assertSubscribers([])
144+
145+ def test_getStructuralSubscribers_with_filter_for_any_tag(self):
146+ # If a subscription filter specifies that any of one or more specific
147+ # tags must be present, bugs with any of those tags are matched.
148+
149+ # Looking for either the "foo" or the "bar" tag.
150+ self.initial_filter.tags = [u"foo", u"bar"]
151+ self.initial_filter.find_all_tags = False
152+
153+ # Without either tag the subscription is not found.
154+ self.assertSubscribers([])
155+
156+ # With either tag the subscription is found.
157+ self.bug.tags = ["bar", "baz"]
158+ self.assertSubscribers([self.ordinary_subscriber])
159+
160+ def test_getStructuralSubscribers_with_filter_for_all_tags(self):
161+ # If a subscription filter specifies that all of one or more specific
162+ # tags must be present, bugs with all of those tags are matched.
163+
164+ # Looking for both the "foo" and the "bar" tag.
165+ self.initial_filter.tags = [u"foo", u"bar"]
166+ self.initial_filter.find_all_tags = True
167+
168+ # Without either tag the subscription is not found.
169+ self.assertSubscribers([])
170+
171+ # Without only one of the required tags the subscription is not found.
172+ self.bug.tags = ["foo"]
173+ self.assertSubscribers([])
174+
175+ # With both required tags the subscription is found.
176+ self.bug.tags = ["foo", "bar"]
177+ self.assertSubscribers([self.ordinary_subscriber])
178+
179+ def test_getStructuralSubscribers_with_filter_for_not_any_tag(self):
180+ # If a subscription filter specifies that any of one or more specific
181+ # tags must not be present, bugs without any of those tags are
182+ # matched.
183+
184+ # Looking to exclude the "foo" or "bar" tags.
185+ self.initial_filter.tags = [u"-foo", u"-bar"]
186+ self.initial_filter.find_all_tags = False
187+
188+ # Without either tag the subscription is found.
189+ self.assertSubscribers([self.ordinary_subscriber])
190+
191+ # With both tags, the subscription is omitted.
192+ self.bug.tags = ["foo", "bar"]
193+ self.assertSubscribers([])
194+
195+ # With only one tag, the subscription is found again.
196+ self.bug.tags = ["foo"]
197+ self.assertSubscribers([self.ordinary_subscriber])
198+
199+ # However, if find_all_tags is True, even a single excluded tag
200+ # causes the subscription to be skipped.
201+ self.initial_filter.find_all_tags = True
202+ self.assertSubscribers([])
203+
204+ # This is also true, of course, if the bug has both tags.
205+ self.bug.tags = ["foo", "bar"]
206+ self.assertSubscribers([])
207+
208+ def test_getStructuralSubscribers_with_filter_for_not_all_tags(self):
209+ # If a subscription filter specifies that all of one or more specific
210+ # tags must not be present, bugs without all of those tags are
211+ # matched.
212+
213+ # Looking to exclude the "foo" and "bar" tags.
214+ self.initial_filter.tags = [u"-foo", u"-bar"]
215+ self.initial_filter.find_all_tags = True
216+
217+ # Without either tag the subscription is found.
218+ self.assertSubscribers([self.ordinary_subscriber])
219+
220+ # With only one of the excluded tags the subscription is not
221+ # found--we are saying that we want to find both an absence of foo
222+ # and an absence of bar, and yet foo exists.
223+ self.bug.tags = ["foo"]
224+ self.assertSubscribers([])
225+
226+ # With both tags the subscription is also not found.
227+ self.bug.tags = ["foo", "bar"]
228+ self.assertSubscribers([])
229+
230+ def test_getStructuralSubscribers_with_multiple_filters(self):
231+ # If multiple filters exist for a subscription, all filters must
232+ # match.
233+
234+ # Add the "foo" tag to the bug.
235+ self.bug.tags = ["foo"]
236+ self.assertSubscribers([self.ordinary_subscriber])
237+
238+ # Filter the subscription to bugs in the CRITICAL state.
239+ self.initial_filter.statuses = [BugTaskStatus.CONFIRMED]
240+ self.initial_filter.importances = [BugTaskImportance.CRITICAL]
241+
242+ # With the filter the subscription is not found.
243+ self.assertSubscribers([])
244+
245+ # If the filter is adjusted to match status but not importance, the
246+ # subscription is still not found.
247+ self.initial_filter.statuses = [self.bugtask.status]
248+ self.assertSubscribers([])
249+
250+ # If the filter is adjusted to also match importance, the subscription
251+ # is found again.
252+ self.initial_filter.importances = [self.bugtask.importance]
253+ self.assertSubscribers([self.ordinary_subscriber])
254+
255+ # If the filter is given some tag criteria, the subscription is not
256+ # found.
257+ self.initial_filter.tags = [u"-foo", u"bar", u"baz"]
258+ self.initial_filter.find_all_tags = False
259+ self.assertSubscribers([])
260+
261+ # After removing the "foo" tag and adding the "bar" tag, the
262+ # subscription is found.
263+ self.bug.tags = ["bar"]
264+ self.assertSubscribers([self.ordinary_subscriber])
265+
266+ # Requiring that all tag criteria are fulfilled causes the
267+ # subscription to no longer be found.
268+ self.initial_filter.find_all_tags = True
269+ self.assertSubscribers([])
270+
271+ # After adding the "baz" tag, the subscription is found again.
272+ self.bug.tags = ["bar", "baz"]
273+ self.assertSubscribers([self.ordinary_subscriber])
274+
275+ def test_getStructuralSubscribers_any_filter_is_a_match(self):
276+ # If a subscription has multiple filters, the subscription is selected
277+ # when any filter is found to match. Put another way, the filters are
278+ # ORed together.
279+ subscription_filter1 = self.initial_filter
280+ subscription_filter1.statuses = [BugTaskStatus.CONFIRMED]
281+ subscription_filter2 = self.subscription.newBugFilter()
282+ subscription_filter2.tags = [u"foo"]
283+
284+ # With the filter the subscription is not found.
285+ self.assertSubscribers([])
286+
287+ # If the bugtask is adjusted to match the criteria of the first filter
288+ # but not those of the second, the subscription is found.
289+ self.bugtask.transitionToStatus(
290+ BugTaskStatus.CONFIRMED, self.ordinary_subscriber)
291+ self.assertSubscribers([self.ordinary_subscriber])
292+
293+ # If the filter is adjusted to also match the criteria of the second
294+ # filter, the subscription is still found.
295+ self.bugtask.bug.tags = [u"foo"]
296+ self.assertSubscribers([self.ordinary_subscriber])
297+
298+ # If the bugtask is adjusted to no longer match the criteria of the
299+ # first filter, the subscription is still found.
300+ self.bugtask.transitionToStatus(
301+ BugTaskStatus.INPROGRESS, self.ordinary_subscriber)
302+ self.assertSubscribers([self.ordinary_subscriber])
303+
304+
305+class TestStructuralSubscriptionFiltersForDistro(
306+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
307+
308+ def makeTarget(self):
309+ return self.factory.makeDistribution()
310+
311+
312+class TestStructuralSubscriptionFiltersForProduct(
313+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
314+
315+ def makeTarget(self):
316+ return self.factory.makeProduct()
317+
318+
319+class TestStructuralSubscriptionFiltersForDistroSourcePackage(
320+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
321+
322+ def makeTarget(self):
323+ return self.factory.makeDistributionSourcePackage()
324+
325+
326+class TestStructuralSubscriptionFiltersForMilestone(
327+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
328+
329+ def makeTarget(self):
330+ return self.factory.makeMilestone()
331+
332+ def makeBugTask(self):
333+ bug = self.factory.makeBug(milestone=self.target)
334+ return bug.bugtasks[0]
335+
336+
337+class TestStructuralSubscriptionFiltersForDistroSeries(
338+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
339+
340+ def makeTarget(self):
341+ return self.factory.makeDistroSeries()
342+
343+
344+class TestStructuralSubscriptionFiltersForProjectGroup(
345+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
346+
347+ def makeTarget(self):
348+ return self.factory.makeProject()
349+
350+ def makeBugTask(self):
351+ return self.factory.makeBugTask(
352+ target=self.factory.makeProduct(project=self.target))
353+
354+
355+class TestStructuralSubscriptionFiltersForProductSeries(
356+ FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
357+
358+ def makeTarget(self):
359+ return self.factory.makeProductSeries()
360
361=== modified file 'lib/lp/bugs/tests/test_structuralsubscriptiontarget.py'
362--- lib/lp/bugs/tests/test_structuralsubscriptiontarget.py 2011-03-07 16:14:58 +0000
363+++ lib/lp/bugs/tests/test_structuralsubscriptiontarget.py 2011-03-07 16:14:59 +0000
364@@ -27,20 +27,12 @@
365 LaunchpadFunctionalLayer,
366 LaunchpadZopelessLayer,
367 )
368-from lp.bugs.enum import BugNotificationLevel
369 from lp.bugs.interfaces.bug import CreateBugParams
370-from lp.bugs.interfaces.bugtask import (
371- BugTaskImportance,
372- BugTaskStatus,
373- )
374 from lp.bugs.interfaces.structuralsubscription import (
375 IStructuralSubscriptionTarget,
376 IStructuralSubscriptionTargetHelper,
377 )
378-from lp.bugs.model.structuralsubscription import (
379- get_structural_subscribers,
380- StructuralSubscription,
381- )
382+from lp.bugs.model.structuralsubscription import StructuralSubscription
383 from lp.bugs.tests.test_bugtarget import bugtarget_filebug
384 from lp.registry.errors import (
385 DeleteSubscriptionError,
386@@ -175,279 +167,6 @@
387 None)
388
389
390-class FilteredStructuralSubscriptionTestBase:
391- """Tests for filtered structural subscriptions."""
392-
393- layer = LaunchpadFunctionalLayer
394-
395- def makeTarget(self):
396- raise NotImplementedError(self.makeTarget)
397-
398- def makeBugTask(self):
399- return self.factory.makeBugTask(target=self.target)
400-
401- def setUp(self):
402- super(FilteredStructuralSubscriptionTestBase, self).setUp()
403- self.ordinary_subscriber = self.factory.makePerson()
404- login_person(self.ordinary_subscriber)
405- self.target = self.makeTarget()
406- self.bugtask = self.makeBugTask()
407- self.bug = self.bugtask.bug
408- self.subscription = self.target.addSubscription(
409- self.ordinary_subscriber, self.ordinary_subscriber)
410- self.initial_filter = self.subscription.bug_filters[0]
411-
412- def assertSubscribers(
413- self, expected_subscribers, level=BugNotificationLevel.NOTHING):
414- observed_subscribers = list(
415- get_structural_subscribers(self.bugtask, None, level))
416- self.assertEqual(expected_subscribers, observed_subscribers)
417-
418- def test_getStructuralSubscribers(self):
419- # If no one has a filtered subscription for the given bug, the result
420- # of get_structural_subscribers() is the same as for
421- # the set of people from each subscription in getSubscriptions().
422- subscriptions = self.target.getSubscriptions()
423- self.assertSubscribers([sub.subscriber for sub in subscriptions])
424-
425- def test_getStructuralSubscribers_with_filter_on_status(self):
426- # If a status filter exists for a subscription, the result of
427- # get_structural_subscribers() may be a subset of getSubscriptions().
428-
429- # Without any filters the subscription is found.
430- self.assertSubscribers([self.ordinary_subscriber])
431-
432- # Filter the subscription to bugs in the CONFIRMED state.
433- self.initial_filter.statuses = [BugTaskStatus.CONFIRMED]
434-
435- # With the filter the subscription is not found.
436- self.assertSubscribers([])
437-
438- # If the filter is adjusted, the subscription is found again.
439- self.initial_filter.statuses = [self.bugtask.status]
440- self.assertSubscribers([self.ordinary_subscriber])
441-
442- def test_getStructuralSubscribers_with_filter_on_importance(self):
443- # If an importance filter exists for a subscription, the result of
444- # get_structural_subscribers() may be a subset of getSubscriptions().
445-
446- # Without any filters the subscription is found.
447- self.assertSubscribers([self.ordinary_subscriber])
448-
449- # Filter the subscription to bugs in the CRITICAL state.
450- self.initial_filter.importances = [BugTaskImportance.CRITICAL]
451-
452- # With the filter the subscription is not found.
453- self.assertSubscribers([])
454-
455- # If the filter is adjusted, the subscription is found again.
456- self.initial_filter.importances = [self.bugtask.importance]
457- self.assertSubscribers([self.ordinary_subscriber])
458-
459- def test_getStructuralSubscribers_with_filter_on_level(self):
460- # All structural subscriptions have a level for bug notifications
461- # which get_structural_subscribers() observes.
462-
463- # Adjust the subscription level to METADATA.
464- self.initial_filter.bug_notification_level = (
465- BugNotificationLevel.METADATA)
466-
467- # The subscription is found when looking for NOTHING or above.
468- self.assertSubscribers(
469- [self.ordinary_subscriber], BugNotificationLevel.NOTHING)
470- # The subscription is found when looking for METADATA or above.
471- self.assertSubscribers(
472- [self.ordinary_subscriber], BugNotificationLevel.METADATA)
473- # The subscription is not found when looking for COMMENTS or above.
474- self.assertSubscribers(
475- [], BugNotificationLevel.COMMENTS)
476-
477- def test_getStructuralSubscribers_with_filter_include_any_tags(self):
478- # If a subscription filter has include_any_tags, a bug with one or
479- # more tags is matched.
480-
481- self.initial_filter.include_any_tags = True
482-
483- # Without any tags the subscription is not found.
484- self.assertSubscribers([])
485-
486- # With any tag the subscription is found.
487- self.bug.tags = ["foo"]
488- self.assertSubscribers([self.ordinary_subscriber])
489-
490- def test_getStructuralSubscribers_with_filter_exclude_any_tags(self):
491- # If a subscription filter has exclude_any_tags, only bugs with no
492- # tags are matched.
493-
494- self.initial_filter.exclude_any_tags = True
495-
496- # Without any tags the subscription is found.
497- self.assertSubscribers([self.ordinary_subscriber])
498-
499- # With any tag the subscription is not found.
500- self.bug.tags = ["foo"]
501- self.assertSubscribers([])
502-
503- def test_getStructuralSubscribers_with_filter_for_any_tag(self):
504- # If a subscription filter specifies that any of one or more specific
505- # tags must be present, bugs with any of those tags are matched.
506-
507- # Looking for either the "foo" or the "bar" tag.
508- self.initial_filter.tags = [u"foo", u"bar"]
509- self.initial_filter.find_all_tags = False
510-
511- # Without either tag the subscription is not found.
512- self.assertSubscribers([])
513-
514- # With either tag the subscription is found.
515- self.bug.tags = ["bar", "baz"]
516- self.assertSubscribers([self.ordinary_subscriber])
517-
518- def test_getStructuralSubscribers_with_filter_for_all_tags(self):
519- # If a subscription filter specifies that all of one or more specific
520- # tags must be present, bugs with all of those tags are matched.
521-
522- # Looking for both the "foo" and the "bar" tag.
523- self.initial_filter.tags = [u"foo", u"bar"]
524- self.initial_filter.find_all_tags = True
525-
526- # Without either tag the subscription is not found.
527- self.assertSubscribers([])
528-
529- # Without only one of the required tags the subscription is not found.
530- self.bug.tags = ["foo"]
531- self.assertSubscribers([])
532-
533- # With both required tags the subscription is found.
534- self.bug.tags = ["foo", "bar"]
535- self.assertSubscribers([self.ordinary_subscriber])
536-
537- def test_getStructuralSubscribers_with_filter_for_not_any_tag(self):
538- # If a subscription filter specifies that any of one or more specific
539- # tags must not be present, bugs without any of those tags are
540- # matched.
541-
542- # Looking to exclude the "foo" or "bar" tags.
543- self.initial_filter.tags = [u"-foo", u"-bar"]
544- self.initial_filter.find_all_tags = False
545-
546- # Without either tag the subscription is found.
547- self.assertSubscribers([self.ordinary_subscriber])
548-
549- # With both tags, the subscription is omitted.
550- self.bug.tags = ["foo", "bar"]
551- self.assertSubscribers([])
552-
553- # With only one tag, the subscription is found again.
554- self.bug.tags = ["foo"]
555- self.assertSubscribers([self.ordinary_subscriber])
556-
557- # However, if find_all_tags is True, even a single excluded tag
558- # causes the subscription to be skipped.
559- self.initial_filter.find_all_tags = True
560- self.assertSubscribers([])
561-
562- # This is also true, of course, if the bug has both tags.
563- self.bug.tags = ["foo", "bar"]
564- self.assertSubscribers([])
565-
566- def test_getStructuralSubscribers_with_filter_for_not_all_tags(self):
567- # If a subscription filter specifies that all of one or more specific
568- # tags must not be present, bugs without all of those tags are
569- # matched.
570-
571- # Looking to exclude the "foo" and "bar" tags.
572- self.initial_filter.tags = [u"-foo", u"-bar"]
573- self.initial_filter.find_all_tags = True
574-
575- # Without either tag the subscription is found.
576- self.assertSubscribers([self.ordinary_subscriber])
577-
578- # With only one of the excluded tags the subscription is not
579- # found--we are saying that we want to find both an absence of foo
580- # and an absence of bar, and yet foo exists.
581- self.bug.tags = ["foo"]
582- self.assertSubscribers([])
583-
584- # With both tags the subscription is also not found.
585- self.bug.tags = ["foo", "bar"]
586- self.assertSubscribers([])
587-
588- def test_getStructuralSubscribers_with_multiple_filters(self):
589- # If multiple filters exist for a subscription, all filters must
590- # match.
591-
592- # Add the "foo" tag to the bug.
593- self.bug.tags = ["foo"]
594- self.assertSubscribers([self.ordinary_subscriber])
595-
596- # Filter the subscription to bugs in the CRITICAL state.
597- self.initial_filter.statuses = [BugTaskStatus.CONFIRMED]
598- self.initial_filter.importances = [BugTaskImportance.CRITICAL]
599-
600- # With the filter the subscription is not found.
601- self.assertSubscribers([])
602-
603- # If the filter is adjusted to match status but not importance, the
604- # subscription is still not found.
605- self.initial_filter.statuses = [self.bugtask.status]
606- self.assertSubscribers([])
607-
608- # If the filter is adjusted to also match importance, the subscription
609- # is found again.
610- self.initial_filter.importances = [self.bugtask.importance]
611- self.assertSubscribers([self.ordinary_subscriber])
612-
613- # If the filter is given some tag criteria, the subscription is not
614- # found.
615- self.initial_filter.tags = [u"-foo", u"bar", u"baz"]
616- self.initial_filter.find_all_tags = False
617- self.assertSubscribers([])
618-
619- # After removing the "foo" tag and adding the "bar" tag, the
620- # subscription is found.
621- self.bug.tags = ["bar"]
622- self.assertSubscribers([self.ordinary_subscriber])
623-
624- # Requiring that all tag criteria are fulfilled causes the
625- # subscription to no longer be found.
626- self.initial_filter.find_all_tags = True
627- self.assertSubscribers([])
628-
629- # After adding the "baz" tag, the subscription is found again.
630- self.bug.tags = ["bar", "baz"]
631- self.assertSubscribers([self.ordinary_subscriber])
632-
633- def test_getStructuralSubscribers_any_filter_is_a_match(self):
634- # If a subscription has multiple filters, the subscription is selected
635- # when any filter is found to match. Put another way, the filters are
636- # ORed together.
637- subscription_filter1 = self.initial_filter
638- subscription_filter1.statuses = [BugTaskStatus.CONFIRMED]
639- subscription_filter2 = self.subscription.newBugFilter()
640- subscription_filter2.tags = [u"foo"]
641-
642- # With the filter the subscription is not found.
643- self.assertSubscribers([])
644-
645- # If the bugtask is adjusted to match the criteria of the first filter
646- # but not those of the second, the subscription is found.
647- self.bugtask.transitionToStatus(
648- BugTaskStatus.CONFIRMED, self.ordinary_subscriber)
649- self.assertSubscribers([self.ordinary_subscriber])
650-
651- # If the filter is adjusted to also match the criteria of the second
652- # filter, the subscription is still found.
653- self.bugtask.bug.tags = [u"foo"]
654- self.assertSubscribers([self.ordinary_subscriber])
655-
656- # If the bugtask is adjusted to no longer match the criteria of the
657- # first filter, the subscription is still found.
658- self.bugtask.transitionToStatus(
659- BugTaskStatus.INPROGRESS, self.ordinary_subscriber)
660- self.assertSubscribers([self.ordinary_subscriber])
661-
662-
663 class TestStructuralSubscriptionForDistro(
664 RestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
665
666@@ -512,13 +231,6 @@
667 StructuralSubscription)
668
669
670-class TestStructuralSubscriptionFiltersForDistro(
671- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
672-
673- def makeTarget(self):
674- return self.factory.makeDistribution()
675-
676-
677 class TestStructuralSubscriptionForProduct(
678 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
679
680@@ -529,13 +241,6 @@
681 self.target = self.factory.makeProduct()
682
683
684-class TestStructuralSubscriptionFiltersForProduct(
685- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
686-
687- def makeTarget(self):
688- return self.factory.makeProduct()
689-
690-
691 class TestStructuralSubscriptionForDistroSourcePackage(
692 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
693
694@@ -547,13 +252,6 @@
695 self.target = ProxyFactory(self.target)
696
697
698-class TestStructuralSubscriptionFiltersForDistroSourcePackage(
699- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
700-
701- def makeTarget(self):
702- return self.factory.makeDistributionSourcePackage()
703-
704-
705 class TestStructuralSubscriptionForMilestone(
706 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
707
708@@ -565,17 +263,6 @@
709 self.target = ProxyFactory(self.target)
710
711
712-class TestStructuralSubscriptionFiltersForMilestone(
713- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
714-
715- def makeTarget(self):
716- return self.factory.makeMilestone()
717-
718- def makeBugTask(self):
719- bug = self.factory.makeBug(milestone=self.target)
720- return bug.bugtasks[0]
721-
722-
723 class TestStructuralSubscriptionForDistroSeries(
724 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
725
726@@ -587,13 +274,6 @@
727 self.target = ProxyFactory(self.target)
728
729
730-class TestStructuralSubscriptionFiltersForDistroSeries(
731- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
732-
733- def makeTarget(self):
734- return self.factory.makeDistroSeries()
735-
736-
737 class TestStructuralSubscriptionForProjectGroup(
738 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
739
740@@ -605,17 +285,6 @@
741 self.target = ProxyFactory(self.target)
742
743
744-class TestStructuralSubscriptionFiltersForProjectGroup(
745- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
746-
747- def makeTarget(self):
748- return self.factory.makeProject()
749-
750- def makeBugTask(self):
751- return self.factory.makeBugTask(
752- target=self.factory.makeProduct(project=self.target))
753-
754-
755 class TestStructuralSubscriptionForProductSeries(
756 UnrestrictedStructuralSubscriptionTestBase, TestCaseWithFactory):
757
758@@ -627,13 +296,6 @@
759 self.target = ProxyFactory(self.target)
760
761
762-class TestStructuralSubscriptionFiltersForProductSeries(
763- FilteredStructuralSubscriptionTestBase, TestCaseWithFactory):
764-
765- def makeTarget(self):
766- return self.factory.makeProductSeries()
767-
768-
769 class TestStructuralSubscriptionTargetHelper(TestCaseWithFactory):
770 """Tests for implementations of `IStructuralSubscriptionTargetHelper`."""
771