Merge lp:~bac/launchpad/bug-753965 into lp:launchpad

Proposed by Brad Crittenden
Status: Merged
Approved by: Brad Crittenden
Approved revision: no longer in the source branch.
Merged at revision: 12812
Proposed branch: lp:~bac/launchpad/bug-753965
Merge into: lp:launchpad
Diff against target: 1027 lines (+486/-155)
10 files modified
lib/lp/bugs/browser/structuralsubscription.py (+27/-13)
lib/lp/bugs/model/structuralsubscription.py (+1/-0)
lib/lp/registry/browser/tests/test_subscription_links.py (+367/-71)
lib/lp/registry/templates/distribution-index.pt (+13/-10)
lib/lp/registry/templates/distributionsourcepackage-index.pt (+13/-10)
lib/lp/registry/templates/distroseries-index.pt (+13/-10)
lib/lp/registry/templates/milestone-index.pt (+13/-10)
lib/lp/registry/templates/product-index.pt (+13/-11)
lib/lp/registry/templates/productseries-index.pt (+13/-10)
lib/lp/registry/templates/project-index.pt (+13/-10)
To merge this branch: bzr merge lp:~bac/launchpad/bug-753965
Reviewer Review Type Date Requested Status
Benji York (community) code Approve
Review via email: mp+57262@code.launchpad.net

Commit message

[r=benji][bug=753965] Do not show structural subscription links if the IStructuralSubscriptionTarget does not use LP for bug tracking.

Description of the change

= Summary =

If the IStructuralSubscriptionTarget does not use LP for bug tracking
then the structural subscription links should not be shown.

== Proposed fix ==

Check the service usage before enabling the link. Also don't call
structural-subscription.setup from the page template unless Launchpad is
used.

== Pre-implementation notes ==

None.

== Implementation details ==

As above.

== Tests ==

bin/test -vvt test_subscription_links

== Demo and Q/A ==

Create a new project in launchpad.dev. Note that the subscription links
are present. Go to 'Configure bug tracker' and mark it as external.
Note the links no longer appear.

= Launchpad lint =

Lint will be fixed.

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/templates/product-index.pt
  lib/lp/registry/templates/milestone-index.pt
  lib/lp/registry/templates/distroseries-index.pt
  lib/lp/registry/templates/distribution-index.pt
  lib/lp/registry/templates/distributionsourcepackage-index.pt
  lib/lp/bugs/browser/structuralsubscription.py
  lib/lp/bugs/model/structuralsubscription.py
  lib/lp/registry/templates/project-index.pt
  lib/lp/registry/templates/productseries-index.pt
  lib/lp/registry/browser/tests/test_subscription_links.py

./lib/lp/bugs/browser/structuralsubscription.py
     443: Line exceeds 78 characters.
./lib/lp/registry/browser/tests/test_subscription_links.py
     641: E302 expected 2 blank lines, found 1
     642: E301 expected 1 blank line, found 0
     649: E301 expected 1 blank line, found 0
     681: E301 expected 1 blank line, found 0
     747: E301 expected 1 blank line, found 0
     801: E301 expected 1 blank line, found 0

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

We discussed the accidentally-included message argument on line 76 of
the diff in IRC.

I would add failure messages to the asserts inside your custom assert
methods: assertOldLinkMissing, assertOldLinkPresent,
assertNewLinksMissing, assertNewLinksPresent.

Skipping DistroView.setUp on line 345 of the diff and calling
BrowserTestCase.setUp instead confused me. If I replace it with a call
to DistroView.setUp the tests still pass.

Also, you didn't start it, but the manual test suite construction in
test_suite is kinda ugly and brittle (a test could easily be dropped
from the list and not noticed). Here's a change that uses the standard
unittest test loader but ignores test cases from the base class that we
want to avoid (also available at http://pastebin.ubuntu.com/593155/).

=== modified file 'lib/lp/registry/browser/tests/test_subscription_links.py'
--- lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-12 14:49:43 +0000
+++ lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-12 14:49:49 +0000
@@ -855,40 +855,19 @@
         self.assertNewLinksMissing()

+class CustomTestLoader(unittest.TestLoader):
+ """A test loader that avoids running tests from a base class."""
+
+ def getTestCaseNames(self, testCaseClass):
+ # If we're asked about which tests to run for _TestStructSubs, reply
+ # with an empty list.
+ if testCaseClass is _TestStructSubs:
+ return []
+ else:
+ return super(CustomTestLoader, self).getTestCaseNames(
+ testCaseClass)
+
+
 def test_suite():
     """Return the `IStructuralSubscriptionTarget` TestSuite."""
-
- # Manually construct the test suite to avoid having tests from the base
- # class _TestStructSubs run.
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ProductView))
- suite.addTest(unittest.makeSuite(ProductBugs))
- suite.addTest(unittest.makeSuite(ProductSeriesView))
- suite.addTest(unittest.makeSuite(ProductSeriesBugs))
- suite.addTest(unittest.makeSuite(ProjectGroupView))
- suite.addTest(unittest.makeSuite(ProjectGroupBugs))
- suite.addTest(unittest.makeSuite(DistributionSourcePackageView))
- suite.addTest(unittest.makeSuite(DistributionSourcePackageBugs))
- suite.addTest(unittest.makeSuite(DistroView))
- suite.addTest(unittest.makeSuite(DistroBugs))
- suite.addTest(unittest.makeSuite(DistroMilestoneView))
- suite.addTest(unittest.makeSuite(ProductMilestoneView))
- suite.addTest(unittest.makeSuite(ProductSeriesMilestoneView))
-
- suite.addTest(unittest.makeSuite(ProductDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProductDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(ProductSeriesDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProductSeriesDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(ProjectGroupDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProjectGroupDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(
- DistributionSourcePackageDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(
- DistributionSourcePackageDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(Dis...

Read more...

review: Approve (code)
Revision history for this message
Benji York (benji) wrote :
Download full text (3.4 KiB)

We discussed the accidentally-included message argument on line 76 of
the diff in IRC.

I would add failure messages to the asserts inside your custom assert
methods: assertOldLinkMissing, assertOldLinkPresent,
assertNewLinksMissing, assertNewLinksPresent.

Skipping DistroView.setUp on line 345 of the diff and calling
BrowserTestCase.setUp instead confused me. If I replace it with a call
to DistroView.setUp the tests still pass.

Also, you didn't start it, but the manual test suite construction in
test_suite is kinda ugly and brittle (a test could easily be dropped
from the list and not noticed). Here's a change that uses the standard
unittest test loader but ignores test cases from the base class that we
want to avoid (also available at http://pastebin.ubuntu.com/593155/).

=== modified file 'lib/lp/registry/browser/tests/test_subscription_links.py'
--- lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-12 14:49:43 +0000
+++ lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-12 14:49:49 +0000
@@ -855,40 +855,19 @@
         self.assertNewLinksMissing()

+class CustomTestLoader(unittest.TestLoader):
+ """A test loader that avoids running tests from a base class."""
+
+ def getTestCaseNames(self, testCaseClass):
+ # If we're asked about which tests to run for _TestStructSubs, reply
+ # with an empty list.
+ if testCaseClass is _TestStructSubs:
+ return []
+ else:
+ return super(CustomTestLoader, self).getTestCaseNames(
+ testCaseClass)
+
+
 def test_suite():
     """Return the `IStructuralSubscriptionTarget` TestSuite."""
-
- # Manually construct the test suite to avoid having tests from the base
- # class _TestStructSubs run.
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(ProductView))
- suite.addTest(unittest.makeSuite(ProductBugs))
- suite.addTest(unittest.makeSuite(ProductSeriesView))
- suite.addTest(unittest.makeSuite(ProductSeriesBugs))
- suite.addTest(unittest.makeSuite(ProjectGroupView))
- suite.addTest(unittest.makeSuite(ProjectGroupBugs))
- suite.addTest(unittest.makeSuite(DistributionSourcePackageView))
- suite.addTest(unittest.makeSuite(DistributionSourcePackageBugs))
- suite.addTest(unittest.makeSuite(DistroView))
- suite.addTest(unittest.makeSuite(DistroBugs))
- suite.addTest(unittest.makeSuite(DistroMilestoneView))
- suite.addTest(unittest.makeSuite(ProductMilestoneView))
- suite.addTest(unittest.makeSuite(ProductSeriesMilestoneView))
-
- suite.addTest(unittest.makeSuite(ProductDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProductDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(ProductSeriesDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProductSeriesDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(ProjectGroupDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(ProjectGroupDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(
- DistributionSourcePackageDoesNotUseLPView))
- suite.addTest(unittest.makeSuite(
- DistributionSourcePackageDoesNotUseLPBugs))
- suite.addTest(unittest.makeSuite(Dis...

Read more...

review: Approve (code)
Revision history for this message
Brad Crittenden (bac) wrote :

Thanks for the review and suggestions Benji.

As mentioned earlier, the test loader is a vast improvement.

The ProductMilestoneView calling BrowserTestCase.setUp directly was a leftover attempt to get failing tests to work. You are correct that it is confusing and has been reverted.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/structuralsubscription.py'
--- lib/lp/bugs/browser/structuralsubscription.py 2011-04-06 15:58:38 +0000
+++ lib/lp/bugs/browser/structuralsubscription.py 2011-04-13 01:26:33 +0000
@@ -49,6 +49,7 @@
49 custom_widget,49 custom_widget,
50 LaunchpadFormView,50 LaunchpadFormView,
51 )51 )
52from lp.app.enums import ServiceUsage
52from lp.app.widgets.itemswidgets import LabeledMultiCheckBoxWidget53from lp.app.widgets.itemswidgets import LabeledMultiCheckBoxWidget
53from lp.bugs.interfaces.bugtask import (54from lp.bugs.interfaces.bugtask import (
54 BugTaskImportance,55 BugTaskImportance,
@@ -354,35 +355,47 @@
354 """355 """
355 sst = self._getSST()356 sst = self._getSST()
356357
357 # ProjectGroup milestones aren't really structural subscription
358 # targets as they're not real milestones, so you can't subscribe to
359 # them.
360 enabled = not IProjectGroupMilestone.providedBy(sst)
361 if sst.userHasBugSubscriptions(self.user):358 if sst.userHasBugSubscriptions(self.user):
362 text = 'Edit bug mail subscription'359 text = 'Edit bug mail subscription'
363 icon = 'edit'360 icon = 'edit'
364 else:361 else:
365 text = 'Subscribe to bug mail'362 text = 'Subscribe to bug mail'
366 icon = 'add'363 icon = 'add'
367 if not enabled or (364 # ProjectGroup milestones aren't really structural subscription
368 not sst.userCanAlterBugSubscription(self.user, self.user)):365 # targets as they're not real milestones, so you can't subscribe to
366 # them.
367 if (not IProjectGroupMilestone.providedBy(sst) and
368 sst.userCanAlterBugSubscription(self.user, self.user)):
369 enabled = True
370 else:
369 enabled = False371 enabled = False
372
370 return Link('+subscribe', text, icon=icon, enabled=enabled)373 return Link('+subscribe', text, icon=icon, enabled=enabled)
371374
375 @property
376 def _enabled(self):
377 """Should the link be enabled?
378
379 True if the target uses Launchpad for bugs and the user can alter the
380 bug subscriptions.
381 """
382 sst = self._getSST()
383 target = sst
384 if sst.parent_subscription_target is not None:
385 target = sst.parent_subscription_target
386 return (target.bug_tracking_usage == ServiceUsage.LAUNCHPAD and
387 sst.userCanAlterBugSubscription(self.user, self.user))
388
372 @enabled_with_permission('launchpad.AnyPerson')389 @enabled_with_permission('launchpad.AnyPerson')
373 def subscribe_to_bug_mail(self):390 def subscribe_to_bug_mail(self):
374 sst = self._getSST()
375 enabled = sst.userCanAlterBugSubscription(self.user, self.user)
376 text = 'Subscribe to bug mail'391 text = 'Subscribe to bug mail'
377 return Link('#', text, icon='add', hidden=True, enabled=enabled)392 return Link('#', text, icon='add', hidden=True, enabled=self._enabled)
378393
379 @enabled_with_permission('launchpad.AnyPerson')394 @enabled_with_permission('launchpad.AnyPerson')
380 def edit_bug_mail(self):395 def edit_bug_mail(self):
381 sst = self._getSST()
382 enabled = sst.userCanAlterBugSubscription(self.user, self.user)
383 text = 'Edit bug mail'396 text = 'Edit bug mail'
384 return Link('+subscriptions', text, icon='edit', site='bugs',397 return Link('+subscriptions', text, icon='edit', site='bugs',
385 enabled=enabled)398 enabled=self._enabled)
386399
387400
388def expose_structural_subscription_data_to_js(context, request,401def expose_structural_subscription_data_to_js(context, request,
@@ -430,7 +443,8 @@
430 IJSONRequestCache(request).objects['administratedTeams'] = info443 IJSONRequestCache(request).objects['administratedTeams'] = info
431444
432445
433def expose_user_subscriptions_to_js(user, subscriptions, request, target=None):446def expose_user_subscriptions_to_js(user, subscriptions, request,
447 target=None):
434 """Make the user's subscriptions available to JavaScript."""448 """Make the user's subscriptions available to JavaScript."""
435 info = {}449 info = {}
436 api_request = IWebServiceClientRequest(request)450 api_request = IWebServiceClientRequest(request)
437451
=== modified file 'lib/lp/bugs/model/structuralsubscription.py'
--- lib/lp/bugs/model/structuralsubscription.py 2011-03-29 05:38:15 +0000
+++ lib/lp/bugs/model/structuralsubscription.py 2011-04-13 01:26:33 +0000
@@ -355,6 +355,7 @@
355355
356 # Nobody else can, unless the context is a IDistributionSourcePackage,356 # Nobody else can, unless the context is a IDistributionSourcePackage,
357 # in which case the drivers or owner can.357 # in which case the drivers or owner can.
358
358 if IDistributionSourcePackage.providedBy(self):359 if IDistributionSourcePackage.providedBy(self):
359 for driver in self.distribution.drivers:360 for driver in self.distribution.drivers:
360 if subscribed_by.inTeam(driver):361 if subscribed_by.inTeam(driver):
361362
=== modified file 'lib/lp/registry/browser/tests/test_subscription_links.py'
--- lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-04 20:15:16 +0000
+++ lib/lp/registry/browser/tests/test_subscription_links.py 2011-04-13 01:26:33 +0000
@@ -52,18 +52,30 @@
52 self.contents, 'menu-link-edit_bug_mail')52 self.contents, 'menu-link-edit_bug_mail')
5353
54 def assertOldLinkMissing(self):54 def assertOldLinkMissing(self):
55 self.assertEqual(None, self.old_link)55 self.assertEqual(
56 None, self.old_link,
57 "Found unexpected link: %s" % self.old_link)
5658
57 def assertOldLinkPresent(self):59 def assertOldLinkPresent(self):
58 self.assertNotEqual(None, self.old_link)60 self.assertNotEqual(
61 None, self.old_link,
62 "Expected +subscribe link missing")
5963
60 def assertNewLinksMissing(self):64 def assertNewLinksMissing(self):
61 self.assertEqual(None, self.new_subscribe_link)65 self.assertEqual(
62 self.assertEqual(None, self.new_edit_link)66 None, self.new_subscribe_link,
67 "Found unexpected link: %s" % self.new_subscribe_link)
68 self.assertEqual(
69 None, self.new_edit_link,
70 "Found unexpected link: %s" % self.new_edit_link)
6371
64 def assertNewLinksPresent(self):72 def assertNewLinksPresent(self):
65 self.assertNotEqual(None, self.new_subscribe_link)73 self.assertNotEqual(
66 self.assertNotEqual(None, self.new_edit_link)74 None, self.new_subscribe_link,
75 "Expected subscribe_to_bug_mail link missing")
76 self.assertNotEqual(
77 None, self.new_edit_link,
78 "Expected edit_bug_mail link missing")
6779
6880
69class _TestStructSubs(TestCaseWithFactory, _TestResultsMixin):81class _TestStructSubs(TestCaseWithFactory, _TestResultsMixin):
@@ -110,7 +122,7 @@
110122
111 def test_subscribe_link_feature_flag_off_user(self):123 def test_subscribe_link_feature_flag_off_user(self):
112 self._create_scenario(self.regular_user, None)124 self._create_scenario(self.regular_user, None)
113 self.assertNotEqual(None, self.old_link)125 self.assertOldLinkPresent()
114 self.assertNewLinksMissing()126 self.assertNewLinksMissing()
115127
116 def test_subscribe_link_feature_flag_on_user(self):128 def test_subscribe_link_feature_flag_on_user(self):
@@ -122,7 +134,7 @@
122 self._create_scenario(ANONYMOUS, None)134 self._create_scenario(ANONYMOUS, None)
123 # The old subscribe link is actually shown to anonymous users but the135 # The old subscribe link is actually shown to anonymous users but the
124 # behavior has changed with the new link.136 # behavior has changed with the new link.
125 self.assertNotEqual(None, self.old_link)137 self.assertOldLinkPresent()
126 self.assertNewLinksMissing()138 self.assertNewLinksMissing()
127139
128 def test_subscribe_link_feature_flag_on_anonymous(self):140 def test_subscribe_link_feature_flag_on_anonymous(self):
@@ -132,75 +144,76 @@
132 self.assertNewLinksMissing()144 self.assertNewLinksMissing()
133145
134146
135class TestProductViewStructSubs(_TestStructSubs):147class ProductView(_TestStructSubs):
136 """Test structural subscriptions on the product view."""148 """Test structural subscriptions on the product view."""
137149
138 rootsite = None150 rootsite = None
139 view = '+index'151 view = '+index'
140152
141 def setUp(self):153 def setUp(self):
142 super(TestProductViewStructSubs, self).setUp()154 super(ProductView, self).setUp()
143 self.target = self.factory.makeProduct(official_malone=True)155 self.target = self.factory.makeProduct(official_malone=True)
144156
145157
146class TestProductBugsStructSubs(TestProductViewStructSubs):158class ProductBugs(ProductView):
147 """Test structural subscriptions on the product bugs view."""159 """Test structural subscriptions on the product bugs view."""
148160
149 rootsite = 'bugs'161 rootsite = 'bugs'
150 view = '+bugs-index'162 view = '+bugs-index'
151163
152164
153class TestProjectGroupViewStructSubs(_TestStructSubs):165class ProjectGroupView(_TestStructSubs):
154 """Test structural subscriptions on the project group view."""166 """Test structural subscriptions on the project group view."""
155167
156 rootsite = None168 rootsite = None
157 view = '+index'169 view = '+index'
158170
159 def setUp(self):171 def setUp(self):
160 super(TestProjectGroupViewStructSubs, self).setUp()172 super(ProjectGroupView, self).setUp()
161 self.target = self.factory.makeProject()173 self.target = self.factory.makeProject()
162 self.factory.makeProduct(174 self.factory.makeProduct(
163 project=self.target, official_malone=True)175 project=self.target, official_malone=True)
164176
165177
166class TestProjectGroupBugsStructSubs(TestProjectGroupViewStructSubs):178class ProjectGroupBugs(ProjectGroupView):
167 """Test structural subscriptions on the project group bugs view."""179 """Test structural subscriptions on the project group bugs view."""
168180
169 rootsite = 'bugs'181 rootsite = 'bugs'
170 view = '+bugs'182 view = '+bugs'
171183
172184
173class TestProductSeriesViewStructSubs(_TestStructSubs):185class ProductSeriesView(_TestStructSubs):
174 """Test structural subscriptions on the product series view."""186 """Test structural subscriptions on the product series view."""
175187
176 rootsite = None188 rootsite = None
177 view = '+index'189 view = '+index'
178190
179 def setUp(self):191 def setUp(self):
180 super(TestProductSeriesViewStructSubs, self).setUp()192 super(ProductSeriesView, self).setUp()
181 self.target = self.factory.makeProductSeries()193 product = self.factory.makeProduct(official_malone=True)
182194 self.target = self.factory.makeProductSeries(product=product)
183195
184class TestProductSeriesBugsStructSubs(TestProductSeriesViewStructSubs):196
197class ProductSeriesBugs(ProductSeriesView):
185 """Test structural subscriptions on the product series bugs view."""198 """Test structural subscriptions on the product series bugs view."""
186199
187 rootsite = 'bugs'200 rootsite = 'bugs'
188 view = '+bugs-index'201 view = '+bugs-index'
189202
190 def setUp(self):203 def setUp(self):
191 super(TestProductSeriesBugsStructSubs, self).setUp()204 super(ProductSeriesBugs, self).setUp()
192 with person_logged_in(self.target.product.owner):205 with person_logged_in(self.target.product.owner):
193 self.target.product.official_malone = True206 self.target.product.official_malone = True
194207
195208
196class TestDistributionSourcePackageViewStructSubs(_TestStructSubs):209class DistributionSourcePackageView(_TestStructSubs):
197 """Test structural subscriptions on the distro src pkg view."""210 """Test structural subscriptions on the distro src pkg view."""
198211
199 rootsite = None212 rootsite = None
200 view = '+index'213 view = '+index'
201214
202 def setUp(self):215 def setUp(self):
203 super(TestDistributionSourcePackageViewStructSubs, self).setUp()216 super(DistributionSourcePackageView, self).setUp()
204 distro = self.factory.makeDistribution()217 distro = self.factory.makeDistribution()
205 with person_logged_in(distro.owner):218 with person_logged_in(distro.owner):
206 distro.official_malone = True219 distro.official_malone = True
@@ -213,15 +226,14 @@
213 test_subscribe_link_feature_flag_on_owner = None226 test_subscribe_link_feature_flag_on_owner = None
214227
215228
216class TestDistributionSourcePackageBugsStructSubs(229class DistributionSourcePackageBugs(DistributionSourcePackageView):
217 TestDistributionSourcePackageViewStructSubs):
218 """Test structural subscriptions on the distro src pkg bugs view."""230 """Test structural subscriptions on the distro src pkg bugs view."""
219231
220 rootsite = 'bugs'232 rootsite = 'bugs'
221 view = '+bugs'233 view = '+bugs'
222234
223235
224class TestDistroViewStructSubs(BrowserTestCase, _TestResultsMixin):236class DistroView(BrowserTestCase, _TestResultsMixin):
225 """Test structural subscriptions on the distribution view.237 """Test structural subscriptions on the distribution view.
226238
227 Distributions are special. They are IStructuralSubscriptionTargets but239 Distributions are special. They are IStructuralSubscriptionTargets but
@@ -238,7 +250,7 @@
238 view = '+index'250 view = '+index'
239251
240 def setUp(self):252 def setUp(self):
241 super(TestDistroViewStructSubs, self).setUp()253 super(DistroView, self).setUp()
242 self.target = self.factory.makeDistribution()254 self.target = self.factory.makeDistribution()
243 with person_logged_in(self.target.owner):255 with person_logged_in(self.target.owner):
244 self.target.official_malone = True256 self.target.official_malone = True
@@ -329,14 +341,13 @@
329 self.assertNewLinksMissing()341 self.assertNewLinksMissing()
330342
331 def test_subscribe_link_feature_flag_on_admin(self):343 def test_subscribe_link_feature_flag_on_admin(self):
332 from lp.testing.sampledata import ADMIN_EMAIL
333 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)344 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
334 self._create_scenario(admin, 'on')345 self._create_scenario(admin, 'on')
335 self.assertOldLinkMissing()346 self.assertOldLinkMissing()
336 self.assertNewLinksPresent()347 self.assertNewLinksPresent()
337348
338349
339class TestDistroBugsStructSubs(TestDistroViewStructSubs):350class DistroBugs(DistroView):
340 """Test structural subscriptions on the distro bugs view."""351 """Test structural subscriptions on the distro bugs view."""
341352
342 rootsite = 'bugs'353 rootsite = 'bugs'
@@ -344,7 +355,7 @@
344355
345 def test_subscribe_link_feature_flag_off_owner(self):356 def test_subscribe_link_feature_flag_off_owner(self):
346 self._create_scenario(self.target.owner, None)357 self._create_scenario(self.target.owner, None)
347 self.assertNotEqual(None, self.old_link)358 self.assertOldLinkPresent()
348 self.assertNewLinksMissing()359 self.assertNewLinksMissing()
349360
350 def test_subscribe_link_feature_flag_on_owner(self):361 def test_subscribe_link_feature_flag_on_owner(self):
@@ -354,7 +365,7 @@
354365
355 def test_subscribe_link_feature_flag_off_user(self):366 def test_subscribe_link_feature_flag_off_user(self):
356 self._create_scenario(self.regular_user, None)367 self._create_scenario(self.regular_user, None)
357 self.assertNotEqual(None, self.old_link)368 self.assertOldLinkPresent()
358 self.assertNewLinksMissing()369 self.assertNewLinksMissing()
359370
360 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):371 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):
@@ -374,7 +385,7 @@
374385
375 def test_subscribe_link_feature_flag_off_anonymous(self):386 def test_subscribe_link_feature_flag_off_anonymous(self):
376 self._create_scenario(ANONYMOUS, None)387 self._create_scenario(ANONYMOUS, None)
377 self.assertNotEqual(None, self.old_link)388 self.assertOldLinkPresent()
378 self.assertNewLinksMissing()389 self.assertNewLinksMissing()
379390
380 def test_subscribe_link_feature_flag_on_anonymous(self):391 def test_subscribe_link_feature_flag_on_anonymous(self):
@@ -388,7 +399,7 @@
388 self.target.setBugSupervisor(399 self.target.setBugSupervisor(
389 self.regular_user, admin)400 self.regular_user, admin)
390 self._create_scenario(self.regular_user, None)401 self._create_scenario(self.regular_user, None)
391 self.assertNotEqual(None, self.old_link)402 self.assertOldLinkPresent()
392 self.assertNewLinksMissing()403 self.assertNewLinksMissing()
393404
394 def test_subscribe_link_feature_flag_on_bug_super(self):405 def test_subscribe_link_feature_flag_on_bug_super(self):
@@ -403,7 +414,7 @@
403 def test_subscribe_link_feature_flag_off_admin(self):414 def test_subscribe_link_feature_flag_off_admin(self):
404 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)415 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
405 self._create_scenario(admin, None)416 self._create_scenario(admin, None)
406 self.assertNotEqual(None, self.old_link)417 self.assertOldLinkPresent()
407 self.assertNewLinksMissing()418 self.assertNewLinksMissing()
408419
409 def test_subscribe_link_feature_flag_on_admin(self):420 def test_subscribe_link_feature_flag_on_admin(self):
@@ -414,17 +425,17 @@
414 self.assertNewLinksPresent()425 self.assertNewLinksPresent()
415426
416427
417class TestDistroMilestoneViewStructSubs(TestDistroViewStructSubs):428class DistroMilestoneView(DistroView):
418 """Test structural subscriptions on the distro milestones."""429 """Test structural subscriptions on the distro milestones."""
419430
420 def setUp(self):431 def setUp(self):
421 super(TestDistroMilestoneViewStructSubs, self).setUp()432 super(DistroMilestoneView, self).setUp()
422 self.distro = self.target433 self.distro = self.target
423 self.target = self.factory.makeMilestone(distribution=self.distro)434 self.target = self.factory.makeMilestone(distribution=self.distro)
424435
425 def test_subscribe_link_feature_flag_off_owner(self):436 def test_subscribe_link_feature_flag_off_owner(self):
426 self._create_scenario(self.distro.owner, None)437 self._create_scenario(self.distro.owner, None)
427 self.assertNotEqual(None, self.old_link)438 self.assertOldLinkPresent()
428 self.assertNewLinksMissing()439 self.assertNewLinksMissing()
429440
430 def test_subscribe_link_feature_flag_on_owner(self):441 def test_subscribe_link_feature_flag_on_owner(self):
@@ -434,7 +445,7 @@
434445
435 def test_subscribe_link_feature_flag_off_user(self):446 def test_subscribe_link_feature_flag_off_user(self):
436 self._create_scenario(self.regular_user, None)447 self._create_scenario(self.regular_user, None)
437 self.assertNotEqual(None, self.old_link)448 self.assertOldLinkPresent()
438 self.assertNewLinksMissing()449 self.assertNewLinksMissing()
439450
440 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):451 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):
@@ -454,7 +465,7 @@
454465
455 def test_subscribe_link_feature_flag_off_anonymous(self):466 def test_subscribe_link_feature_flag_off_anonymous(self):
456 self._create_scenario(ANONYMOUS, None)467 self._create_scenario(ANONYMOUS, None)
457 self.assertNotEqual(None, self.old_link)468 self.assertOldLinkPresent()
458 self.assertNewLinksMissing()469 self.assertNewLinksMissing()
459470
460 def test_subscribe_link_feature_flag_on_anonymous(self):471 def test_subscribe_link_feature_flag_on_anonymous(self):
@@ -468,7 +479,7 @@
468 self.distro.setBugSupervisor(479 self.distro.setBugSupervisor(
469 self.regular_user, admin)480 self.regular_user, admin)
470 self._create_scenario(self.regular_user, None)481 self._create_scenario(self.regular_user, None)
471 self.assertNotEqual(None, self.old_link)482 self.assertOldLinkPresent()
472 self.assertNewLinksMissing()483 self.assertNewLinksMissing()
473484
474 def test_subscribe_link_feature_flag_on_bug_super(self):485 def test_subscribe_link_feature_flag_on_bug_super(self):
@@ -483,7 +494,7 @@
483 def test_subscribe_link_feature_flag_off_admin(self):494 def test_subscribe_link_feature_flag_off_admin(self):
484 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)495 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
485 self._create_scenario(admin, None)496 self._create_scenario(admin, None)
486 self.assertNotEqual(None, self.old_link)497 self.assertOldLinkPresent()
487 self.assertNewLinksMissing()498 self.assertNewLinksMissing()
488499
489 def test_subscribe_link_feature_flag_on_admin(self):500 def test_subscribe_link_feature_flag_on_admin(self):
@@ -494,11 +505,11 @@
494 self.assertNewLinksPresent()505 self.assertNewLinksPresent()
495506
496507
497class TestProductMilestoneViewStructSubs(TestDistroViewStructSubs):508class ProductMilestoneView(DistroView):
498 """Test structural subscriptions on the product milestones."""509 """Test structural subscriptions on the product milestones."""
499510
500 def setUp(self):511 def setUp(self):
501 super(TestProductMilestoneViewStructSubs, self).setUp()512 super(ProductMilestoneView, self).setUp()
502 self.product = self.factory.makeProduct()513 self.product = self.factory.makeProduct()
503 with person_logged_in(self.product.owner):514 with person_logged_in(self.product.owner):
504 self.product.official_malone = True515 self.product.official_malone = True
@@ -507,7 +518,7 @@
507518
508 def test_subscribe_link_feature_flag_off_owner(self):519 def test_subscribe_link_feature_flag_off_owner(self):
509 self._create_scenario(self.product.owner, None)520 self._create_scenario(self.product.owner, None)
510 self.assertNotEqual(None, self.old_link)521 self.assertOldLinkPresent()
511 self.assertNewLinksMissing()522 self.assertNewLinksMissing()
512523
513 def test_subscribe_link_feature_flag_on_owner(self):524 def test_subscribe_link_feature_flag_on_owner(self):
@@ -517,7 +528,7 @@
517528
518 def test_subscribe_link_feature_flag_off_user(self):529 def test_subscribe_link_feature_flag_off_user(self):
519 self._create_scenario(self.regular_user, None)530 self._create_scenario(self.regular_user, None)
520 self.assertNotEqual(None, self.old_link)531 self.assertOldLinkPresent()
521 self.assertNewLinksMissing()532 self.assertNewLinksMissing()
522533
523 # There are no special bug supervisor rules for products.534 # There are no special bug supervisor rules for products.
@@ -528,7 +539,7 @@
528539
529 def test_subscribe_link_feature_flag_off_anonymous(self):540 def test_subscribe_link_feature_flag_off_anonymous(self):
530 self._create_scenario(ANONYMOUS, None)541 self._create_scenario(ANONYMOUS, None)
531 self.assertNotEqual(None, self.old_link)542 self.assertOldLinkPresent()
532 self.assertNewLinksMissing()543 self.assertNewLinksMissing()
533544
534 def test_subscribe_link_feature_flag_on_anonymous(self):545 def test_subscribe_link_feature_flag_on_anonymous(self):
@@ -539,7 +550,7 @@
539 def test_subscribe_link_feature_flag_off_admin(self):550 def test_subscribe_link_feature_flag_off_admin(self):
540 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)551 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
541 self._create_scenario(admin, None)552 self._create_scenario(admin, None)
542 self.assertNotEqual(None, self.old_link)553 self.assertOldLinkPresent()
543 self.assertNewLinksMissing()554 self.assertNewLinksMissing()
544555
545 def test_subscribe_link_feature_flag_on_admin(self):556 def test_subscribe_link_feature_flag_on_admin(self):
@@ -550,12 +561,11 @@
550 self.assertNewLinksPresent()561 self.assertNewLinksPresent()
551562
552563
553class TestProductSeriesMilestoneViewStructSubs(564class ProductSeriesMilestoneView(ProductMilestoneView):
554 TestProductMilestoneViewStructSubs):
555 """Test structural subscriptions on the product series milestones."""565 """Test structural subscriptions on the product series milestones."""
556566
557 def setUp(self):567 def setUp(self):
558 super(TestProductSeriesMilestoneViewStructSubs, self).setUp()568 super(ProductSeriesMilestoneView, self).setUp()
559 self.productseries = self.factory.makeProductSeries()569 self.productseries = self.factory.makeProductSeries()
560 with person_logged_in(self.productseries.product.owner):570 with person_logged_in(self.productseries.product.owner):
561 self.productseries.product.official_malone = True571 self.productseries.product.official_malone = True
@@ -563,27 +573,313 @@
563 self.target = self.factory.makeMilestone(573 self.target = self.factory.makeMilestone(
564 productseries=self.productseries)574 productseries=self.productseries)
565575
576# Tests for when the IStructuralSubscriptionTarget does not use Launchpad for
577# bug tracking. In those cases the links should not be shown.
578
579class ProductDoesNotUseLPView(ProductView):
580 """Test structural subscriptions on the product view."""
581
582 def setUp(self):
583 super(ProductDoesNotUseLPView, self).setUp()
584 self.target = self.factory.makeProduct(official_malone=False)
585
586 def test_subscribe_link_feature_flag_on_owner(self):
587 # Test the new subscription link.
588 self._create_scenario(self.target.owner, 'on')
589 self.assertOldLinkMissing()
590 self.assertNewLinksMissing()
591
592 def test_subscribe_link_feature_flag_on_user(self):
593 self._create_scenario(self.regular_user, 'on')
594 self.assertOldLinkMissing()
595 self.assertNewLinksMissing()
596
597 def test_subscribe_link_feature_flag_on_anonymous(self):
598 self._create_scenario(ANONYMOUS, 'on')
599 # The subscribe link is not shown to anonymous.
600 self.assertOldLinkMissing()
601 self.assertNewLinksMissing()
602
603
604class ProductDoesNotUseLPBugs(ProductDoesNotUseLPView):
605 """Test structural subscriptions on the product bugs view."""
606
607 rootsite = 'bugs'
608 view = '+bugs-index'
609
610 def test_subscribe_link_feature_flag_off_owner(self):
611 self._create_scenario(self.target.owner, None)
612 self.assertOldLinkMissing()
613 self.assertNewLinksMissing()
614
615 def test_subscribe_link_feature_flag_off_user(self):
616 self._create_scenario(self.regular_user, None)
617 self.assertOldLinkMissing()
618 self.assertNewLinksMissing()
619
620 def test_subscribe_link_feature_flag_off_anonymous(self):
621 self._create_scenario(ANONYMOUS, None)
622 # The old subscribe link is actually shown to anonymous users but the
623 # behavior has changed with the new link.
624 self.assertOldLinkMissing()
625 self.assertNewLinksMissing()
626
627
628class ProjectGroupDoesNotUseLPView(ProductDoesNotUseLPView):
629 """Test structural subscriptions on the project group view."""
630
631 rootsite = None
632 view = '+index'
633
634 def setUp(self):
635 super(ProjectGroupDoesNotUseLPView, self).setUp()
636 self.target = self.factory.makeProject()
637 self.factory.makeProduct(
638 project=self.target, official_malone=False)
639
640
641class ProjectGroupDoesNotUseLPBugs(ProductDoesNotUseLPBugs):
642 """Test structural subscriptions on the project group bugs view."""
643
644 rootsite = 'bugs'
645 view = '+bugs'
646
647 def setUp(self):
648 super(ProjectGroupDoesNotUseLPBugs, self).setUp()
649 self.target = self.factory.makeProject()
650 self.factory.makeProduct(
651 project=self.target, official_malone=False)
652
653
654class ProductSeriesDoesNotUseLPView(ProductDoesNotUseLPView):
655
656 def setUp(self):
657 super(ProductSeriesDoesNotUseLPView, self).setUp()
658 product = self.factory.makeProduct(official_malone=False)
659 self.target = self.factory.makeProductSeries(product=product)
660
661
662class ProductSeriesDoesNotUseLPBugs(ProductDoesNotUseLPView):
663
664 def setUp(self):
665 super(ProductSeriesDoesNotUseLPBugs, self).setUp()
666 product = self.factory.makeProduct(official_malone=False)
667 self.target = self.factory.makeProductSeries(product=product)
668
669
670class DistributionSourcePackageDoesNotUseLPView(ProductDoesNotUseLPView):
671 """Test structural subscriptions on the distro src pkg view."""
672
673 def setUp(self):
674 super(DistributionSourcePackageDoesNotUseLPView, self).setUp()
675 distro = self.factory.makeDistribution()
676 self.target = self.factory.makeDistributionSourcePackage(
677 distribution=distro)
678 self.regular_user = self.factory.makePerson()
679
680 # DistributionSourcePackages do not have owners.
681 test_subscribe_link_feature_flag_off_owner = None
682 test_subscribe_link_feature_flag_on_owner = None
683
684
685class DistributionSourcePackageDoesNotUseLPBugs(ProductDoesNotUseLPBugs):
686 """Test structural subscriptions on the distro src pkg bugs view."""
687
688 view = '+bugs'
689
690 # DistributionSourcePackages do not have owners.
691 test_subscribe_link_feature_flag_off_owner = None
692 test_subscribe_link_feature_flag_on_owner = None
693
694
695class DistroDoesNotUseLPView(DistroView):
696
697 def setUp(self):
698 super(DistroDoesNotUseLPView, self).setUp()
699 self.target = self.factory.makeDistribution()
700 self.regular_user = self.factory.makePerson()
701
702 def test_subscribe_link_feature_flag_on_admin(self):
703 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
704 self._create_scenario(admin, 'on')
705 self.assertOldLinkMissing()
706 self.assertNewLinksMissing()
707
708 def test_subscribe_link_feature_flag_on_bug_super(self):
709 with celebrity_logged_in('admin'):
710 admin = getUtility(ILaunchBag).user
711 self.target.setBugSupervisor(
712 self.regular_user, admin)
713 self._create_scenario(self.regular_user, 'on')
714 self.assertOldLinkMissing()
715 self.assertNewLinksMissing()
716
717 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):
718 self._create_scenario(self.regular_user, 'on')
719 self.assertOldLinkMissing()
720 self.assertNewLinksMissing()
721
722 def test_subscribe_link_feature_flag_on_owner(self):
723 # Test the new subscription link.
724 self._create_scenario(self.target.owner, 'on')
725 self.assertOldLinkMissing()
726 self.assertNewLinksMissing()
727
728 def test_subscribe_link_feature_flag_on_user(self):
729 self._create_scenario(self.regular_user, 'on')
730 self.assertOldLinkMissing()
731 self.assertNewLinksMissing()
732
733 def test_subscribe_link_feature_flag_on_anonymous(self):
734 self._create_scenario(ANONYMOUS, 'on')
735 # The subscribe link is not shown to anonymous.
736 self.assertOldLinkMissing()
737 self.assertNewLinksMissing()
738
739
740class DistroDoesNotUseLPBugs(DistroDoesNotUseLPView):
741 rootsite = 'bugs'
742 view = '+bugs-index'
743
744 def test_subscribe_link_feature_flag_off_owner(self):
745 self._create_scenario(self.target.owner, None)
746 self.assertOldLinkMissing()
747 self.assertNewLinksMissing()
748
749 def test_subscribe_link_feature_flag_off_user(self):
750 self._create_scenario(self.regular_user, None)
751 self.assertOldLinkMissing()
752 self.assertNewLinksMissing()
753
754 def test_subscribe_link_feature_flag_off_anonymous(self):
755 self._create_scenario(ANONYMOUS, None)
756 # The old subscribe link is actually shown to anonymous users but the
757 # behavior has changed with the new link.
758 self.assertOldLinkMissing()
759 self.assertNewLinksMissing()
760
761
762class DistroMilestoneDoesNotUseLPView(DistroMilestoneView):
763
764 def setUp(self):
765 super(DistroMilestoneDoesNotUseLPView, self).setUp()
766 with person_logged_in(self.distro.owner):
767 self.distro.official_malone = False
768
769 def test_subscribe_link_feature_flag_on_admin(self):
770 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
771 self._create_scenario(admin, 'on')
772 self.assertOldLinkMissing()
773 self.assertNewLinksMissing()
774
775 def test_subscribe_link_feature_flag_on_bug_super(self):
776 with celebrity_logged_in('admin'):
777 admin = getUtility(ILaunchBag).user
778 self.distro.setBugSupervisor(
779 self.regular_user, admin)
780 self._create_scenario(self.regular_user, 'on')
781 self.assertOldLinkMissing()
782 self.assertNewLinksMissing()
783
784 def test_subscribe_link_feature_flag_on_user_no_bug_super(self):
785 self._create_scenario(self.regular_user, 'on')
786 self.assertOldLinkMissing()
787 self.assertNewLinksMissing()
788
789 def test_subscribe_link_feature_flag_on_owner(self):
790 # Test the new subscription link.
791 self._create_scenario(self.distro.owner, 'on')
792 self.assertOldLinkMissing()
793 self.assertNewLinksMissing()
794
795 def test_subscribe_link_feature_flag_on_user(self):
796 self._create_scenario(self.regular_user, 'on')
797 self.assertOldLinkMissing()
798 self.assertNewLinksMissing()
799
800 def test_subscribe_link_feature_flag_on_anonymous(self):
801 self._create_scenario(ANONYMOUS, 'on')
802 # The subscribe link is not shown to anonymous.
803 self.assertOldLinkMissing()
804 self.assertNewLinksMissing()
805
806 def test_subscribe_link_feature_flag_on_user_with_bug_super(self):
807 with celebrity_logged_in('admin'):
808 admin = getUtility(ILaunchBag).user
809 supervisor = self.factory.makePerson()
810 self.distro.setBugSupervisor(
811 supervisor, admin)
812 self._create_scenario(self.regular_user, 'on')
813 self.assertOldLinkMissing()
814 self.assertNewLinksMissing()
815
816
817class ProductMilestoneDoesNotUseLPView(ProductMilestoneView):
818
819 def setUp(self):
820 BrowserTestCase.setUp(self)
821 self.product = self.factory.makeProduct()
822 with person_logged_in(self.product.owner):
823 self.product.official_malone = False
824 self.target = self.factory.makeMilestone(
825 name='1.0', product=self.product)
826 self.regular_user = self.factory.makePerson()
827
828 def test_subscribe_link_feature_flag_off_owner(self):
829 self._create_scenario(self.product.owner, None)
830 # The presence of the old link is certainly a mistake since the
831 # product does not use Launchpad for bug tracking.
832 self.assertOldLinkPresent()
833 self.assertNewLinksMissing()
834
835 def test_subscribe_link_feature_flag_off_user(self):
836 self._create_scenario(self.regular_user, None)
837 # The presence of the old link is certainly a mistake since the
838 # product does not use Launchpad for bug tracking.
839 self.assertOldLinkPresent()
840 self.assertNewLinksMissing()
841
842 def test_subscribe_link_feature_flag_off_anonymous(self):
843 self._create_scenario(ANONYMOUS, None)
844 # The presence of the old link is certainly a mistake since the
845 # product does not use Launchpad for bug tracking.
846 self.assertOldLinkPresent()
847 self.assertNewLinksMissing()
848
849 def test_subscribe_link_feature_flag_off_admin(self):
850 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
851 self._create_scenario(admin, None)
852 # The presence of the old link is certainly a mistake since the
853 # product does not use Launchpad for bug tracking.
854 self.assertOldLinkPresent()
855 self.assertNewLinksMissing()
856
857 def test_subscribe_link_feature_flag_on_admin(self):
858 from lp.testing.sampledata import ADMIN_EMAIL
859 admin = getUtility(IPersonSet).getByEmail(ADMIN_EMAIL)
860 self._create_scenario(admin, 'on')
861 self.assertOldLinkMissing()
862 self.assertNewLinksMissing()
863
864 def test_subscribe_link_feature_flag_on_owner(self):
865 self._create_scenario(self.product.owner, 'on')
866 self.assertOldLinkMissing()
867 self.assertNewLinksMissing()
868
869
870class CustomTestLoader(unittest.TestLoader):
871 """A test loader that avoids running tests from a base class."""
872
873 def getTestCaseNames(self, testCaseClass):
874 # If we're asked about which tests to run for _TestStructSubs, reply
875 # with an empty list.
876 if testCaseClass is _TestStructSubs:
877 return []
878 else:
879 return super(CustomTestLoader, self).getTestCaseNames(
880 testCaseClass)
881
566882
567def test_suite():883def test_suite():
568 """Return the `IStructuralSubscriptionTarget` TestSuite."""884 """Return the `IStructuralSubscriptionTarget` TestSuite."""
569885 return CustomTestLoader().loadTestsFromName(__name__)
570 # Manually construct the test suite to avoid having tests from the base
571 # class _TestStructSubs run.
572 suite = unittest.TestSuite()
573 suite.addTest(unittest.makeSuite(TestProductViewStructSubs))
574 suite.addTest(unittest.makeSuite(TestProductBugsStructSubs))
575 suite.addTest(unittest.makeSuite(TestProductSeriesViewStructSubs))
576 suite.addTest(unittest.makeSuite(TestProductSeriesBugsStructSubs))
577 suite.addTest(unittest.makeSuite(TestProjectGroupViewStructSubs))
578 suite.addTest(unittest.makeSuite(TestProjectGroupBugsStructSubs))
579 suite.addTest(unittest.makeSuite(
580 TestDistributionSourcePackageViewStructSubs))
581 suite.addTest(unittest.makeSuite(
582 TestDistributionSourcePackageBugsStructSubs))
583 suite.addTest(unittest.makeSuite(TestDistroViewStructSubs))
584 suite.addTest(unittest.makeSuite(TestDistroBugsStructSubs))
585 suite.addTest(unittest.makeSuite(TestDistroMilestoneViewStructSubs))
586 suite.addTest(unittest.makeSuite(TestProductMilestoneViewStructSubs))
587 suite.addTest(unittest.makeSuite(
588 TestProductSeriesMilestoneViewStructSubs))
589 return suite
590886
=== modified file 'lib/lp/registry/templates/distribution-index.pt'
--- lib/lp/registry/templates/distribution-index.pt 2011-04-11 00:34:52 +0000
+++ lib/lp/registry/templates/distribution-index.pt 2011-04-13 01:26:33 +0000
@@ -8,16 +8,19 @@
88
9 <head>9 <head>
10 <tal:head-epilogue metal:fill-slot="head_epilogue">10 <tal:head-epilogue metal:fill-slot="head_epilogue">
11 <script type="text/javascript"11 <tal:uses_launchpad_bugtracker
12 tal:condition="12 condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD">
13 request/features/malone.advanced-structural-subscriptions.enabled">13 <script type="text/javascript"
14 LPS.use('lp.registry.structural_subscription', function(Y) {14 tal:condition="
15 var module = Y.lp.registry.structural_subscription;15 request/features/malone.advanced-structural-subscriptions.enabled">
16 Y.on('domready', function() {16 LPS.use('lp.registry.structural_subscription', function(Y) {
17 module.setup({content_box: "#structural-subscription-content-box"});17 var module = Y.lp.registry.structural_subscription;
18 });18 Y.on('domready', function() {
19 });19 module.setup({content_box: "#structural-subscription-content-box"});
20 </script>20 });
21 });
22 </script>
23 </tal:uses_launchpad_bugtracker>
21 </tal:head-epilogue>24 </tal:head-epilogue>
22 </head>25 </head>
2326
2427
=== modified file 'lib/lp/registry/templates/distributionsourcepackage-index.pt'
--- lib/lp/registry/templates/distributionsourcepackage-index.pt 2011-04-05 16:05:15 +0000
+++ lib/lp/registry/templates/distributionsourcepackage-index.pt 2011-04-13 01:26:33 +0000
@@ -10,16 +10,19 @@
10<body>10<body>
1111
12<metal:block fill-slot="head_epilogue">12<metal:block fill-slot="head_epilogue">
13 <script type="text/javascript"13 <tal:uses_launchpad_bugtracker
14 tal:condition="14 condition="context/distribution/bug_tracking_usage/enumvalue:LAUNCHPAD">
15 request/features/malone.advanced-structural-subscriptions.enabled">15 <script type="text/javascript"
16 LPS.use('lp.registry.structural_subscription', function(Y) {16 tal:condition="
17 var module = Y.lp.registry.structural_subscription;17 request/features/malone.advanced-structural-subscriptions.enabled">
18 Y.on('domready', function() {18 LPS.use('lp.registry.structural_subscription', function(Y) {
19 module.setup({content_box: "#structural-subscription-content-box"});19 var module = Y.lp.registry.structural_subscription;
20 });20 Y.on('domready', function() {
21 });21 module.setup({content_box: "#structural-subscription-content-box"});
22 </script>22 });
23 });
24 </script>
25 </tal:uses_launchpad_bugtracker>
23</metal:block>26</metal:block>
2427
25<tal:side metal:fill-slot="side">28<tal:side metal:fill-slot="side">
2629
=== modified file 'lib/lp/registry/templates/distroseries-index.pt'
--- lib/lp/registry/templates/distroseries-index.pt 2011-03-30 21:38:03 +0000
+++ lib/lp/registry/templates/distroseries-index.pt 2011-04-13 01:26:33 +0000
@@ -13,16 +13,19 @@
13 <script id="milestone-script" type="text/javascript"13 <script id="milestone-script" type="text/javascript"
14 tal:condition="context/menu:overview/create_milestone/enabled"14 tal:condition="context/menu:overview/create_milestone/enabled"
15 tal:content="view/register_milestone_script"></script>15 tal:content="view/register_milestone_script"></script>
16 <script type="text/javascript"16 <tal:uses_launchpad_bugtracker
17 tal:condition="17 condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD">
18 request/features/malone.advanced-structural-subscriptions.enabled">18 <script type="text/javascript"
19 LPS.use('lp.registry.structural_subscription', function(Y) {19 tal:condition="
20 var module = Y.lp.registry.structural_subscription;20 request/features/malone.advanced-structural-subscriptions.enabled">
21 Y.on('domready', function() {21 LPS.use('lp.registry.structural_subscription', function(Y) {
22 module.setup({content_box: "#structural-subscription-content-box"});22 var module = Y.lp.registry.structural_subscription;
23 });23 Y.on('domready', function() {
24 });24 module.setup({content_box: "#structural-subscription-content-box"});
25 </script>25 });
26 });
27 </script>
28 </tal:uses_launchpad_bugtracker>
26 </metal:block>29 </metal:block>
2730
28 <tal:heading metal:fill-slot="heading">31 <tal:heading metal:fill-slot="heading">
2932
=== modified file 'lib/lp/registry/templates/milestone-index.pt'
--- lib/lp/registry/templates/milestone-index.pt 2011-03-29 22:34:04 +0000
+++ lib/lp/registry/templates/milestone-index.pt 2011-04-13 01:26:33 +0000
@@ -13,16 +13,19 @@
13 background: #fff;13 background: #fff;
14 }14 }
15 </style>15 </style>
16 <script type="text/javascript"16 <tal:uses_launchpad_bugtracker
17 tal:condition="17 condition="context/target/bug_tracking_usage/enumvalue:LAUNCHPAD">
18 request/features/malone.advanced-structural-subscriptions.enabled">18 <script type="text/javascript"
19 LPS.use('lp.registry.structural_subscription', function(Y) {19 tal:condition="
20 var module = Y.lp.registry.structural_subscription;20 request/features/malone.advanced-structural-subscriptions.enabled">
21 Y.on('domready', function() {21 LPS.use('lp.registry.structural_subscription', function(Y) {
22 module.setup({content_box: "#structural-subscription-content-box"});22 var module = Y.lp.registry.structural_subscription;
23 });23 Y.on('domready', function() {
24 });24 module.setup({content_box: "#structural-subscription-content-box"});
25 </script>25 });
26 });
27 </script>
28 </tal:uses_launchpad_bugtracker>
26 </tal:head-epilogue>29 </tal:head-epilogue>
2730
28 <body>31 <body>
2932
=== modified file 'lib/lp/registry/templates/product-index.pt'
--- lib/lp/registry/templates/product-index.pt 2011-03-29 22:34:04 +0000
+++ lib/lp/registry/templates/product-index.pt 2011-04-13 01:26:33 +0000
@@ -31,17 +31,19 @@
31 div.collapsible, div.collapsed {display: block;}31 div.collapsible, div.collapsed {display: block;}
32 </style>32 </style>
33 </noscript>33 </noscript>
3434 <tal:uses_launchpad_bugtracker
35 <script type="text/javascript"35 condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD">
36 tal:condition="36 <script type="text/javascript"
37 request/features/malone.advanced-structural-subscriptions.enabled">37 tal:condition="
38 LPS.use('lp.registry.structural_subscription', function(Y) {38 request/features/malone.advanced-structural-subscriptions.enabled">
39 var module = Y.lp.registry.structural_subscription;39 LPS.use('lp.registry.structural_subscription', function(Y) {
40 Y.on('domready', function() {40 var module = Y.lp.registry.structural_subscription;
41 module.setup({content_box: "#structural-subscription-content-box"});41 Y.on('domready', function() {
42 });42 module.setup({content_box: "#structural-subscription-content-box"});
43 });43 });
44 </script>44 });
45 </script>
46 </tal:uses_launchpad_bugtracker>
45 </tal:head-epilogue>47 </tal:head-epilogue>
46</head>48</head>
4749
4850
=== modified file 'lib/lp/registry/templates/productseries-index.pt'
--- lib/lp/registry/templates/productseries-index.pt 2011-04-04 18:51:17 +0000
+++ lib/lp/registry/templates/productseries-index.pt 2011-04-13 01:26:33 +0000
@@ -14,16 +14,19 @@
14 <script id="milestone-script" type="text/javascript"14 <script id="milestone-script" type="text/javascript"
15 tal:condition="context/menu:overview/create_milestone/enabled"15 tal:condition="context/menu:overview/create_milestone/enabled"
16 tal:content="view/register_milestone_script"></script>16 tal:content="view/register_milestone_script"></script>
17 <script type="text/javascript"17 <tal:uses_launchpad_bugtracker
18 tal:condition="18 condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD">
19 request/features/malone.advanced-structural-subscriptions.enabled">19 <script type="text/javascript"
20 LPS.use('lp.registry.structural_subscription', function(Y) {20 tal:condition="
21 var module = Y.lp.registry.structural_subscription;21 request/features/malone.advanced-structural-subscriptions.enabled">
22 Y.on('domready', function() {22 LPS.use('lp.registry.structural_subscription', function(Y) {
23 module.setup({content_box: "#structural-subscription-content-box"});23 var module = Y.lp.registry.structural_subscription;
24 });24 Y.on('domready', function() {
25 });25 module.setup({content_box: "#structural-subscription-content-box"});
26 </script>26 });
27 });
28 </script>
29 </tal:uses_launchpad_bugtracker>
27 </metal:block>30 </metal:block>
2831
29 <tal:heading metal:fill-slot="heading">32 <tal:heading metal:fill-slot="heading">
3033
=== modified file 'lib/lp/registry/templates/project-index.pt'
--- lib/lp/registry/templates/project-index.pt 2011-03-29 22:34:04 +0000
+++ lib/lp/registry/templates/project-index.pt 2011-04-13 01:26:33 +0000
@@ -9,16 +9,19 @@
99
10 <head>10 <head>
11 <tal:head-epilogue metal:fill-slot="head_epilogue">11 <tal:head-epilogue metal:fill-slot="head_epilogue">
12 <script type="text/javascript"12 <tal:uses_launchpad_bugtracker
13 tal:condition="13 condition="context/bug_tracking_usage/enumvalue:LAUNCHPAD">
14 request/features/malone.advanced-structural-subscriptions.enabled">14 <script type="text/javascript"
15 LPS.use('lp.registry.structural_subscription', function(Y) {15 tal:condition="
16 var module = Y.lp.registry.structural_subscription;16 request/features/malone.advanced-structural-subscriptions.enabled">
17 Y.on('domready', function() {17 LPS.use('lp.registry.structural_subscription', function(Y) {
18 module.setup({content_box: "#structural-subscription-content-box"});18 var module = Y.lp.registry.structural_subscription;
19 });19 Y.on('domready', function() {
20 });20 module.setup({content_box: "#structural-subscription-content-box"});
21 </script>21 });
22 });
23 </script>
24 </tal:uses_launchpad_bugtracker>
22 </tal:head-epilogue>25 </tal:head-epilogue>
23 </head>26 </head>
2427