Merge lp:~edwin-grubbs/launchpad/bug-635302-dsp-filebug-oops into lp:launchpad

Proposed by Edwin Grubbs
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 11688
Proposed branch: lp:~edwin-grubbs/launchpad/bug-635302-dsp-filebug-oops
Merge into: lp:launchpad
Diff against target: 757 lines (+361/-73)
15 files modified
lib/lp/bugs/browser/bugtask.py (+15/-5)
lib/lp/bugs/browser/tests/test_buglisting.py (+122/-0)
lib/lp/bugs/stories/bugtask-searches/xx-advanced-people-filters.txt (+4/-0)
lib/lp/bugs/stories/bugtask-searches/xx-advanced-upstream-pending-bugwatch.txt (+5/-0)
lib/lp/bugs/stories/bugtask-searches/xx-distribution-statistics-portlet.txt (+34/-30)
lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt (+6/-0)
lib/lp/bugs/stories/bugtask-searches/xx-sort-orders.txt (+4/-0)
lib/lp/bugs/templates/buglisting-default.pt (+26/-5)
lib/lp/registry/browser/distributionsourcepackage.py (+18/-3)
lib/lp/registry/browser/pillar.py (+19/-20)
lib/lp/registry/browser/sourcepackage.py (+16/-1)
lib/lp/registry/configure.zcml (+6/-8)
lib/lp/registry/interfaces/projectgroup.py (+2/-1)
lib/lp/registry/model/projectgroup.py (+51/-0)
lib/lp/testing/service_usage_helpers.py (+33/-0)
To merge this branch: bzr merge lp:~edwin-grubbs/launchpad/bug-635302-dsp-filebug-oops
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code + ui Approve
Review via email: mp+37679@code.launchpad.net

Description of the change

Summary
-------

The bugs.lp.net/fedora/+source/$distributionsourcepackage page would display a list of
bugs and the "Report a bug" button despite the fact that the
distribution does not use Launchpad for tracking bugs.

Implementation details
----------------------

Added conditionals for hiding the bug listing and the "Report a bug"
button. It also sets robots=noindex,nofollow and displays a link to
help.lp.net/Bugs like bugtarget-bugs.pt does. However, I did not add a
link to configure the bugtracker, since buglisting-default.pt is used on
so many different objects, and the code would have to determine if the
object is part of a distribution or a project, which actually can have
its bugtracker configured.
    lib/lp/bugs/templates/buglisting-default.pt
    lib/lp/bugs/browser/bugtask.py

Adapt IDistributionSourcePackage/ISourcePackage to IServiceUsage and
reduce the zcml for the IBreadcrumb adapter.
    lib/lp/registry/browser/distributionsourcepackage.py
    lib/lp/registry/browser/sourcepackage.py
    lib/lp/registry/configure.zcml

Since buglisting-default.pt is also used by ProjectGroups, I made it
implement the IServiceUsage interface. This meant that the
browser.pillar.InvolvedMenu code could be simplified.
    lib/lp/registry/browser/pillar.py
    lib/lp/registry/interfaces/projectgroup.py
    lib/lp/registry/model/projectgroup.py

Fix tests by setting bug_tracking_usage to LAUNCHPAD. I also corrected
the indent of the python code in xx-distribution-statistics-portlet.txt.
    lib/lp/bugs/stories/bugtask-searches/xx-advanced-people-filters.txt
    lib/lp/bugs/stories/bugtask-searches/xx-advanced-upstream-pending-bugwatch.txt
    lib/lp/bugs/stories/bugtask-searches/xx-distribution-statistics-portlet.txt
    lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt
    lib/lp/bugs/stories/bugtask-searches/xx-sort-orders.txt

Tests
-----

./bin/test -vv -t 'xx-advanced-people-filters.txt|xx-advanced-upstream-pending-bugwatch.txt|xx-distribution-statistics-portlet.txt|xx-listing-basics.txt|xx-sort-orders.txt'

Demo and Q/A
------------

* These pages should not show a list of bugs or the "Report a bug"
  button, but they should show the "Getting started with bug tracking in
  Launchpad" link.
    * Open http://launchpad.dev/debian/+source/mozilla-firefox
    * Open http://launchpad.dev/debian/sarge/+source/mozilla-firefox
    * Open http://launchpad.dev/apache
* These pages should show the bug listing and the "Report a bug" button.
    * Open http://launchpad.dev/ubuntu/+source/mozilla-firefox
    * Open http://launchpad.dev/ubuntu/warty/+source/mozilla-firefox
    * Open http://launchpad.dev/gnome

To post a comment you must log in.
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :
Download full text (4.7 KiB)

Here is a diff of a couple of files that I forgot to commit before.

=== added file 'lib/lp/bugs/browser/tests/test_buglisting.py'
--- lib/lp/bugs/browser/tests/test_buglisting.py 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/browser/tests/test_buglisting.py 2010-10-06 20:20:08 +0000
@@ -0,0 +1,71 @@
+# Copyright 2010 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+__metaclass__ = type
+
+from canonical.launchpad.testing.pages import (
+ extract_text,
+ find_tag_by_id,
+ find_tags_by_class,
+ )
+from canonical.launchpad.webapp import canonical_url
+from canonical.testing.layers import LaunchpadFunctionalLayer
+from lp.testing import BrowserTestCase
+
+
+class TestBugTaskSearchListingView(BrowserTestCase):
+
+ layer = LaunchpadFunctionalLayer
+
+ def _makeDistributionSourcePackage(self):
+ distro = self.factory.makeDistribution('test-distro')
+ return self.factory.makeDistributionSourcePackage('test-dsp', distro)
+
+ def test_distributionsourcepackage_unknown_bugtracker_message(self):
+ dsp = self._makeDistributionSourcePackage()
+ url = canonical_url(dsp, rootsite='bugs')
+ browser = self.getUserBrowser(url)
+ top_portlet = find_tags_by_class(
+ browser.contents, 'top-portlet')
+ self.assertTrue(len(top_portlet) > 0,
+ "Tag with class=top-portlet not found")
+ self.assertTextMatchesExpressionIgnoreWhitespace("""
+ test-dsp in test-distro does not use Launchpad for bug tracking.
+ Getting started with bug tracking in Launchpad.""",
+ extract_text(top_portlet[0]))
+
+ def test_distributionsourcepackage_unknown_bugtracker_no_button(self):
+ dsp = self._makeDistributionSourcePackage()
+ url = canonical_url(dsp, rootsite='bugs')
+ browser = self.getUserBrowser(url)
+ self.assertIs(None, find_tag_by_id(browser.contents, 'involvement'),
+ "Involvement portlet with Report-a-bug button should "
+ "not be shown")
+
+ def _makeSourcePackage(self):
+ distro = self.factory.makeDistribution('test-distro')
+ series = self.factory.makeDistroRelease(
+ distribution=distro, name='test-series')
+ return self.factory.makeSourcePackage('test-sp', distro.currentseries)
+
+ def test_sourcepackage_unknown_bugtracker_message(self):
+ sp = self._makeSourcePackage()
+ url = canonical_url(sp, rootsite='bugs')
+ browser = self.getUserBrowser(url)
+ top_portlet = find_tags_by_class(
+ browser.contents, 'top-portlet')
+ self.assertTrue(len(top_portlet) > 0,
+ "Tag with class=top-portlet not found")
+ self.assertTextMatchesExpressionIgnoreWhitespace("""
+ test-sp in Test-distro Test-series does not
+ use Launchpad for bug tracking.
+ Getting started with bug tracking in Launchpad.""",
+ extract_text(top_portlet[0]))
+
+ def test_sourcepackage_unknown_bugtracker_no_button(self):
+ sp = self._makeSourcePackage()
+ url...

Read more...

Revision history for this message
Curtis Hovey (sinzui) wrote :

Hi Edwin.

This is a very nice refactoring and improvement to the rules.

There is some scary things in xx-distribution-statistics-portlet.txt, but I will ignore them since you it is unclear what the test is really doing. I think the bugs team should consider deleting it.

I believe you and Brad are solving the same PG issues. You may find you conflict with him. I like you refactoring and hope it is preserved.

I do not have any remarks about your code changes. You comments are clear. I do think something is missing though, and you should investigate why I get oopses when I merge your branch into a local branch:

https://bugs.launchpad.dev/debian/+source/mozilla-firefox
* I see a sidebar with links to do bug searches. I do not think this is correct. The links will show bugs that were reported under the assumption that the project did you LP.

https://launchpad.dev/apache
* OOPS
  Line 74, Column 8
  Expression: <PathExpr standard:u'context/@@+get-involved/answers_usage/enumvalue:LAUNCHPAD'>
  ForbiddenAttribute: ('official_malone', <ProjectGroup at 0xfd1b5ac>)<br />

https://launchpad.dev/gnome
* OOPS (same as above)

review: Needs Fixing (code and ui)
Revision history for this message
Edwin Grubbs (edwin-grubbs) wrote :

On Wed, Oct 6, 2010 at 4:35 PM, Curtis Hovey <email address hidden> wrote:
> Review: Needs Fixing code and ui
> Hi Edwin.
>
> This is a very nice refactoring and improvement to the rules.
>
> There is some scary things in xx-distribution-statistics-portlet.txt, but I will ignore them since you it is unclear what the test is really doing. I think the bugs team should consider deleting it.
>
> I believe you and Brad are solving the same PG issues. You may find you conflict with him. I like you refactoring and hope it is preserved.
>
> I do not have any remarks about your code changes. You comments are clear. I do think something is missing though, and you should investigate why I get oopses when I merge your branch into a local branch:
>
> https://bugs.launchpad.dev/debian/+source/mozilla-firefox
> * I see a sidebar with links to do bug searches. I do not think this is correct. The links will show bugs that were reported under the assumption that the project did you LP.

The portlet with bugfilter links is now hidden, and the bugtags
portlet is now also hidden.

> https://launchpad.dev/apache
> * OOPS
>  Line 74, Column 8
>  Expression: <PathExpr standard:u'context/@@+get-involved/answers_usage/enumvalue:LAUNCHPAD'>
>  ForbiddenAttribute: ('official_malone', <ProjectGroup at 0xfd1b5ac>)<br />
>
>
> https://launchpad.dev/gnome
> * OOPS (same as above)

Both of these are now fixed.

Revision history for this message
Curtis Hovey (sinzui) wrote :

Thanks for addressing my concerns. I think this branch is ready to land.

review: Approve (code + ui)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/bugs/browser/bugtask.py'
--- lib/lp/bugs/browser/bugtask.py 2010-10-04 14:20:00 +0000
+++ lib/lp/bugs/browser/bugtask.py 2010-10-07 13:33:43 +0000
@@ -164,11 +164,6 @@
164from canonical.launchpad.webapp.interfaces import ILaunchBag164from canonical.launchpad.webapp.interfaces import ILaunchBag
165from canonical.launchpad.webapp.launchpadform import ReturnToReferrerMixin165from canonical.launchpad.webapp.launchpadform import ReturnToReferrerMixin
166from canonical.launchpad.webapp.menu import structured166from canonical.launchpad.webapp.menu import structured
167from lp.app.browser.tales import (
168 FormattersAPI,
169 ObjectImageDisplayAPI,
170 PersonFormatterAPI,
171 )
172from canonical.lazr.interfaces import IObjectPrivacy167from canonical.lazr.interfaces import IObjectPrivacy
173from canonical.lazr.utils import smartquote168from canonical.lazr.utils import smartquote
174from canonical.widgets.bug import BugTagsWidget169from canonical.widgets.bug import BugTagsWidget
@@ -189,11 +184,17 @@
189 )184 )
190from canonical.widgets.project import ProjectScopeWidget185from canonical.widgets.project import ProjectScopeWidget
191from lp.answers.interfaces.questiontarget import IQuestionTarget186from lp.answers.interfaces.questiontarget import IQuestionTarget
187from lp.app.browser.tales import (
188 FormattersAPI,
189 ObjectImageDisplayAPI,
190 PersonFormatterAPI,
191 )
192from lp.app.enums import ServiceUsage192from lp.app.enums import ServiceUsage
193from lp.app.errors import (193from lp.app.errors import (
194 NotFoundError,194 NotFoundError,
195 UnexpectedFormData,195 UnexpectedFormData,
196 )196 )
197from lp.app.interfaces.launchpad import IServiceUsage
197from lp.bugs.browser.bug import (198from lp.bugs.browser.bug import (
198 BugContextMenu,199 BugContextMenu,
199 BugTextView,200 BugTextView,
@@ -2484,6 +2485,15 @@
2484 custom_widget('tags_combinator', RadioWidget)2485 custom_widget('tags_combinator', RadioWidget)
2485 custom_widget('component', LabeledMultiCheckBoxWidget)2486 custom_widget('component', LabeledMultiCheckBoxWidget)
24862487
2488 @cachedproperty
2489 def bug_tracking_usage(self):
2490 """Whether the context tracks bugs in launchpad.
2491
2492 :returns: ServiceUsage enum value
2493 """
2494 service_usage = IServiceUsage(self.context)
2495 return service_usage.bug_tracking_usage
2496
2487 @property2497 @property
2488 def schema(self):2498 def schema(self):
2489 """Return the schema that defines the form."""2499 """Return the schema that defines the form."""
24902500
=== added file 'lib/lp/bugs/browser/tests/test_buglisting.py'
--- lib/lp/bugs/browser/tests/test_buglisting.py 1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/browser/tests/test_buglisting.py 2010-10-07 13:33:43 +0000
@@ -0,0 +1,122 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4__metaclass__ = type
5
6from canonical.launchpad.testing.pages import (
7 extract_text,
8 find_tag_by_id,
9 find_tags_by_class,
10 )
11from canonical.launchpad.webapp import canonical_url
12from canonical.testing.layers import LaunchpadFunctionalLayer
13from lp.testing import BrowserTestCase
14
15
16class TestBugTaskSearchListingView(BrowserTestCase):
17
18 layer = LaunchpadFunctionalLayer
19
20 def _makeDistributionSourcePackage(self):
21 distro = self.factory.makeDistribution('test-distro')
22 return self.factory.makeDistributionSourcePackage('test-dsp', distro)
23
24 def test_distributionsourcepackage_unknown_bugtracker_message(self):
25 # A DistributionSourcePackage whose Distro does not use
26 # Launchpad for bug tracking should explain that.
27 dsp = self._makeDistributionSourcePackage()
28 url = canonical_url(dsp, rootsite='bugs')
29 browser = self.getUserBrowser(url)
30 top_portlet = find_tags_by_class(
31 browser.contents, 'top-portlet')
32 self.assertTrue(len(top_portlet) > 0,
33 "Tag with class=top-portlet not found")
34 self.assertTextMatchesExpressionIgnoreWhitespace("""
35 test-dsp in test-distro does not use Launchpad for bug tracking.
36 Getting started with bug tracking in Launchpad.""",
37 extract_text(top_portlet[0]))
38
39 def test_distributionsourcepackage_unknown_bugtracker_no_button(self):
40 # A DistributionSourcePackage whose Distro does not use
41 # Launchpad for bug tracking should not show the "Report a bug"
42 # button.
43 dsp = self._makeDistributionSourcePackage()
44 url = canonical_url(dsp, rootsite='bugs')
45 browser = self.getUserBrowser(url)
46 self.assertIs(None, find_tag_by_id(browser.contents, 'involvement'),
47 "Involvement portlet with Report-a-bug button should "
48 "not be shown")
49
50 def test_distributionsourcepackage_unknown_bugtracker_no_filters(self):
51 # A DistributionSourcePackage whose Distro does not use
52 # Launchpad for bug tracking should not show links to "New
53 # bugs", "Open bugs", etc.
54 dsp = self._makeDistributionSourcePackage()
55 url = canonical_url(dsp, rootsite='bugs')
56 browser = self.getUserBrowser(url)
57 self.assertIs(None,
58 find_tag_by_id(browser.contents, 'portlet-bugfilters'),
59 "portlet-bugfilters should not be shown.")
60
61 def test_distributionsourcepackage_unknown_bugtracker_no_tags(self):
62 # A DistributionSourcePackage whose Distro does not use
63 # Launchpad for bug tracking should not show links to search by
64 # bug tags.
65 dsp = self._makeDistributionSourcePackage()
66 url = canonical_url(dsp, rootsite='bugs')
67 browser = self.getUserBrowser(url)
68 self.assertIs(None, find_tag_by_id(browser.contents, 'portlet-tags'),
69 "portlet-tags should not be shown.")
70
71 def _makeSourcePackage(self):
72 distro = self.factory.makeDistribution('test-distro')
73 series = self.factory.makeDistroRelease(
74 distribution=distro, name='test-series')
75 return self.factory.makeSourcePackage('test-sp', distro.currentseries)
76
77 def test_sourcepackage_unknown_bugtracker_message(self):
78 # A SourcePackage whose Distro does not use
79 # Launchpad for bug tracking should explain that.
80 sp = self._makeSourcePackage()
81 url = canonical_url(sp, rootsite='bugs')
82 browser = self.getUserBrowser(url)
83 top_portlet = find_tags_by_class(
84 browser.contents, 'top-portlet')
85 self.assertTrue(len(top_portlet) > 0,
86 "Tag with class=top-portlet not found")
87 self.assertTextMatchesExpressionIgnoreWhitespace("""
88 test-sp in Test-distro Test-series does not
89 use Launchpad for bug tracking.
90 Getting started with bug tracking in Launchpad.""",
91 extract_text(top_portlet[0]))
92
93 def test_sourcepackage_unknown_bugtracker_no_button(self):
94 # A SourcePackage whose Distro does not use Launchpad for bug
95 # tracking should not show the "Report a bug" button.
96 sp = self._makeSourcePackage()
97 url = canonical_url(sp, rootsite='bugs')
98 browser = self.getUserBrowser(url)
99 self.assertIs(None, find_tag_by_id(browser.contents, 'involvement'),
100 "Involvement portlet with Report-a-bug button should "
101 "not be shown")
102
103 def test_sourcepackage_unknown_bugtracker_no_filters(self):
104 # A SourcePackage whose Distro does not use Launchpad for bug
105 # tracking should not show links to "New bugs", "Open bugs",
106 # etc.
107 sp = self._makeSourcePackage()
108 url = canonical_url(sp, rootsite='bugs')
109 browser = self.getUserBrowser(url)
110 self.assertIs(None,
111 find_tag_by_id(browser.contents, 'portlet-bugfilters'),
112 "portlet-bugfilters should not be shown.")
113
114 def test_sourcepackage_unknown_bugtracker_no_tags(self):
115 # A SourcePackage whose Distro does not use Launchpad for bug
116 # tracking should not show links to search by bug tags.
117 sp = self._makeSourcePackage()
118 url = canonical_url(sp, rootsite='bugs')
119 browser = self.getUserBrowser(url)
120 self.assertIs(None,
121 find_tag_by_id(browser.contents, 'portlet-tags'),
122 "portlet-tags should not be shown.")
0123
=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-advanced-people-filters.txt'
--- lib/lp/bugs/stories/bugtask-searches/xx-advanced-people-filters.txt 2010-06-12 05:14:55 +0000
+++ lib/lp/bugs/stories/bugtask-searches/xx-advanced-people-filters.txt 2010-10-07 13:33:43 +0000
@@ -28,6 +28,10 @@
28Let's test the advanced form for a distribution. We get the search28Let's test the advanced form for a distribution. We get the search
29results when we use a valid assignee.29results when we use a valid assignee.
3030
31 >>> # Debian must enable the Launchpad bug tracker to access bugs.
32 >>> from lp.testing.service_usage_helpers import set_service_usage
33 >>> set_service_usage('debian', bug_tracking_usage='LAUNCHPAD')
34
31 >>> anon_browser.open('http://bugs.launchpad.dev/debian/+bugs?advanced=1')35 >>> anon_browser.open('http://bugs.launchpad.dev/debian/+bugs?advanced=1')
32 >>> anon_browser.getControl(name='field.assignee').value = 'name12'36 >>> anon_browser.getControl(name='field.assignee').value = 'name12'
33 >>> anon_browser.getControl('Search', index=0).click()37 >>> anon_browser.getControl('Search', index=0).click()
3438
=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-advanced-upstream-pending-bugwatch.txt'
--- lib/lp/bugs/stories/bugtask-searches/xx-advanced-upstream-pending-bugwatch.txt 2010-06-12 14:30:43 +0000
+++ lib/lp/bugs/stories/bugtask-searches/xx-advanced-upstream-pending-bugwatch.txt 2010-10-07 13:33:43 +0000
@@ -37,6 +37,11 @@
37chooses to search for all bugs that need to be forwarded upstream.37chooses to search for all bugs that need to be forwarded upstream.
38He sees one match.38He sees one match.
3939
40 >>> # alsa-utils must use an external bugtracker to view bugs
41 >>> # forwarded to an upstream.
42 >>> from lp.testing.service_usage_helpers import set_service_usage
43 >>> set_service_usage('alsa-utils', bug_tracking_usage='EXTERNAL')
44
40 >>> browser.open('http://bugs.launchpad.dev/alsa-utils/+bugs?advanced=1')45 >>> browser.open('http://bugs.launchpad.dev/alsa-utils/+bugs?advanced=1')
41 >>> pending_bugwatch_label = (46 >>> pending_bugwatch_label = (
42 ... 'Show bugs that need to be forwarded to an upstream '47 ... 'Show bugs that need to be forwarded to an upstream '
4348
=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-distribution-statistics-portlet.txt'
--- lib/lp/bugs/stories/bugtask-searches/xx-distribution-statistics-portlet.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/stories/bugtask-searches/xx-distribution-statistics-portlet.txt 2010-10-07 13:33:43 +0000
@@ -7,45 +7,49 @@
77
8Viewing critical bugs as Sample Person:8Viewing critical bugs as Sample Person:
99
10 >>> print http(r"""10 >>> # Debian must enable the Launchpad bug tracker to access bugs.
11 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.importance%3Alist=Critical&search=Search HTTP/1.111 >>> from lp.testing.service_usage_helpers import set_service_usage
12 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=12 >>> set_service_usage('debian', bug_tracking_usage='LAUNCHPAD')
13 ... """)13
14 HTTP/1.1 200 Ok14 >>> print http(r"""
15 ...No results for search...15 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.importance%3Alist=Critical&search=Search HTTP/1.1
16 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
17 ... """)
18 HTTP/1.1 200 Ok
19 ...No results for search...
1620
17Viewing bugs "assigned to me", as Sample Person:21Viewing bugs "assigned to me", as Sample Person:
1822
19 >>> print http(r"""23 >>> print http(r"""
20 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.assignee=name12&search=Search HTTP/1.124 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.assignee=name12&search=Search HTTP/1.1
21 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=25 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
22 ... """)26 ... """)
23 HTTP/1.1 200 Ok27 HTTP/1.1 200 Ok
24 ...1 result...28 ...1 result...
2529
26Viewing untriaged bugs as Sample Person:30Viewing untriaged bugs as Sample Person:
2731
28 >>> print http(r"""32 >>> print http(r"""
29 ... GET /debian/+bugs?field.status%3Alist=New&search=Search HTTP/1.133 ... GET /debian/+bugs?field.status%3Alist=New&search=Search HTTP/1.1
30 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=34 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
31 ... """)35 ... """)
32 HTTP/1.1 200 Ok36 HTTP/1.1 200 Ok
33 ...1 result...37 ...1 result...
3438
35Viewing unassigned bugs as Sample Person:39Viewing unassigned bugs as Sample Person:
3640
37 >>> print http(r"""41 >>> print http(r"""
38 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.status-empty-marker=1&field.importance-empty-marker=1&field.assignee=&assignee_option=none&search=Search HTTP/1.142 ... GET /debian/+bugs?field.status%3Alist=New&field.status%3Alist=Confirmed&field.status-empty-marker=1&field.importance-empty-marker=1&field.assignee=&assignee_option=none&search=Search HTTP/1.1
39 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=43 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
40 ... """)44 ... """)
41 HTTP/1.1 200 Ok45 HTTP/1.1 200 Ok
42 ...2 results...46 ...2 results...
4347
44Viewing open reported bugs as Sample Person:48Viewing open reported bugs as Sample Person:
4549
46 >>> print http(r"""50 >>> print http(r"""
47 ... GET /debian/+bugs?search=Search HTTP/1.151 ... GET /debian/+bugs?search=Search HTTP/1.1
48 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=52 ... Authorization: Basic dGVzdEBjYW5vbmljYWwuY29tOnRlc3Q=
49 ... """)53 ... """)
50 HTTP/1.1 200 Ok54 HTTP/1.1 200 Ok
51 ...3 results...55 ...3 results...
5256
=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt'
--- lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-10-03 15:30:06 +0000
+++ lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-10-07 13:33:43 +0000
@@ -14,6 +14,10 @@
1414
15Bug listings default to open bugtasks:15Bug listings default to open bugtasks:
1616
17 >>> # Debian must enable the Launchpad bug tracker to access bugs.
18 >>> from lp.testing.service_usage_helpers import set_service_usage
19 >>> set_service_usage('debian', bug_tracking_usage='LAUNCHPAD')
20
17 >>> user_browser.open('http://launchpad.dev/debian/+bugs')21 >>> user_browser.open('http://launchpad.dev/debian/+bugs')
18 >>> print_bugtasks(user_browser.contents)22 >>> print_bugtasks(user_browser.contents)
19 3 Bug Title Test mozilla-firefox Unknown New23 3 Bug Title Test mozilla-firefox Unknown New
@@ -31,6 +35,7 @@
3135
32An anonymous user views the bug tasks in upstream Ubuntu.36An anonymous user views the bug tasks in upstream Ubuntu.
3337
38 >>> set_service_usage('tomcat', bug_tracking_usage='LAUNCHPAD')
34 >>> anon_browser.open("http://launchpad.dev/tomcat/+bugs")39 >>> anon_browser.open("http://launchpad.dev/tomcat/+bugs")
35 >>> print_bugtasks(anon_browser.contents)40 >>> print_bugtasks(anon_browser.contents)
36 2 Blackhole Trash folder Low New41 2 Blackhole Trash folder Low New
@@ -179,6 +184,7 @@
179Similarly, if we don't do a search and there are no open bugs on that product,184Similarly, if we don't do a search and there are no open bugs on that product,
180it'll say so.185it'll say so.
181186
187 >>> set_service_usage('iso-codes', bug_tracking_usage='LAUNCHPAD')
182 >>> user_browser.open("http://launchpad.dev/iso-codes/+bugs")188 >>> user_browser.open("http://launchpad.dev/iso-codes/+bugs")
183 >>> print user_browser.contents189 >>> print user_browser.contents
184 <...190 <...
185191
=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-sort-orders.txt'
--- lib/lp/bugs/stories/bugtask-searches/xx-sort-orders.txt 2009-06-12 16:36:02 +0000
+++ lib/lp/bugs/stories/bugtask-searches/xx-sort-orders.txt 2010-10-07 13:33:43 +0000
@@ -33,6 +33,10 @@
3333
34Default view:34Default view:
3535
36 >>> # Debian must enable the Launchpad bug tracker to access bugs.
37 >>> from lp.testing.service_usage_helpers import set_service_usage
38 >>> set_service_usage('debian', bug_tracking_usage='LAUNCHPAD')
39
36 >>> anon_browser.open("http://launchpad.dev/debian/+bugs")40 >>> anon_browser.open("http://launchpad.dev/debian/+bugs")
37 >>> print_bugtasks(anon_browser.contents)41 >>> print_bugtasks(anon_browser.contents)
38 3 Bug Title Test42 3 Bug Title Test
3943
=== modified file 'lib/lp/bugs/templates/buglisting-default.pt'
--- lib/lp/bugs/templates/buglisting-default.pt 2009-09-16 17:05:13 +0000
+++ lib/lp/bugs/templates/buglisting-default.pt 2010-10-07 13:33:43 +0000
@@ -8,8 +8,14 @@
8>8>
9 <body>9 <body>
1010
11 <metal:block fill-slot="head_epilogue">
12 <meta tal:condition="not: view/bug_tracking_usage/enumvalue:LAUNCHPAD"
13 name="robots" content="noindex,nofollow" />
14 </metal:block>
15
11 <div metal:fill-slot="main">16 <div metal:fill-slot="main">
12 <div class="top-portlet">17 <div tal:condition="not: view/bug_tracking_usage/enumvalue:UNKNOWN"
18 class="top-portlet">
13 <tal:block condition="view/_projectContext">19 <tal:block condition="view/_projectContext">
14 <tal:block condition="view/required:launchpad.Edit">20 <tal:block condition="view/required:launchpad.Edit">
15 <p tal:condition="not: context/products" class="warning message">21 <p tal:condition="not: context/products" class="warning message">
@@ -31,7 +37,7 @@
31 condition="not: view/shouldShowAdvancedForm">37 condition="not: view/shouldShowAdvancedForm">
32 <div tal:define="batch_navigator view/search">38 <div tal:define="batch_navigator view/search">
3339
34 <div metal:use-macro="context/@@+bugtarget-macros-search/simple-search-form" />40 <div metal:use-macro="context/@@+bugtarget-macros-search/simple-search-form"></div>
35 <tal:buglisting content="structure batch_navigator/@@+table-view" />41 <tal:buglisting content="structure batch_navigator/@@+table-view" />
36 </div>42 </div>
37 </tal:do_not_show_advanced_form>43 </tal:do_not_show_advanced_form>
@@ -41,9 +47,22 @@
41 use-macro="context/@@+bugtask-macros-tableview/advanced_search_form" />47 use-macro="context/@@+bugtask-macros-tableview/advanced_search_form" />
42 </tal:show_advanced_form>48 </tal:show_advanced_form>
43 </div>49 </div>
50 <div tal:condition="view/bug_tracking_usage/enumvalue:UNKNOWN"
51 class="top-portlet">
52 <p>
53 <tal:displayname replace="context/displayname" />
54 does not use Launchpad for bug tracking.
55 </p>
56 <p>
57 <a class="sprite maybe"
58 href="https://help.launchpad.net/Bugs">Getting started
59 with bug tracking in Launchpad</a>.
60 </p>
61 </div>
44 </div>62 </div>
45 <tal:side metal:fill-slot="side">63 <tal:side metal:fill-slot="side">
46 <div id="involvement" class="portlet involvement">64 <div id="involvement" class="portlet involvement"
65 tal:condition="view/bug_tracking_usage/enumvalue:LAUNCHPAD">
47 <ul>66 <ul>
48 <li style="border: 0">67 <li style="border: 0">
49 <a href="+filebug" class="menu-link-filebug sprite bugs">68 <a href="+filebug" class="menu-link-filebug sprite bugs">
@@ -55,10 +74,12 @@
55 <tal:menu replace="structure view/@@+related-pages" />74 <tal:menu replace="structure view/@@+related-pages" />
56 <tal:do_not_show_portlets_advanced_form75 <tal:do_not_show_portlets_advanced_form
57 condition="not: view/shouldShowAdvancedForm">76 condition="not: view/shouldShowAdvancedForm">
58 <tal:block content="structure context/@@+portlet-bugfilters" />77 <tal:block content="structure context/@@+portlet-bugfilters"
78 tal:condition="view/bug_tracking_usage/enumvalue:LAUNCHPAD"/>
59 <tal:block79 <tal:block
60 content="structure context/@@+portlet-publishing-details | nothing"/>80 content="structure context/@@+portlet-publishing-details | nothing"/>
61 <tal:block content="structure context/@@+portlet-bugtags" />81 <tal:block content="structure context/@@+portlet-bugtags"
82 tal:condition="view/bug_tracking_usage/enumvalue:LAUNCHPAD"/>
62 <tal:releasecriticalbugs83 <tal:releasecriticalbugs
63 tal:condition="view/shouldShowReleaseCriticalPortlet"84 tal:condition="view/shouldShowReleaseCriticalPortlet"
64 tal:content="structure context/@@+portlet-bugtasklist-seriesbugs" />85 tal:content="structure context/@@+portlet-bugtasklist-seriesbugs" />
6586
=== modified file 'lib/lp/registry/browser/distributionsourcepackage.py'
--- lib/lp/registry/browser/distributionsourcepackage.py 2010-09-27 16:49:22 +0000
+++ lib/lp/registry/browser/distributionsourcepackage.py 2010-10-07 13:33:43 +0000
@@ -4,14 +4,15 @@
4__metaclass__ = type4__metaclass__ = type
55
6__all__ = [6__all__ = [
7 'distribution_from_distributionsourcepackage',
7 'DistributionSourcePackageBreadcrumb',8 'DistributionSourcePackageBreadcrumb',
9 'DistributionSourcePackageChangelogView',
8 'DistributionSourcePackageEditView',10 'DistributionSourcePackageEditView',
9 'DistributionSourcePackageFacets',11 'DistributionSourcePackageFacets',
10 'DistributionSourcePackageNavigation',12 'DistributionSourcePackageNavigation',
11 'DistributionSourcePackageOverviewMenu',13 'DistributionSourcePackageOverviewMenu',
14 'DistributionSourcePackagePublishingHistoryView',
12 'DistributionSourcePackageView',15 'DistributionSourcePackageView',
13 'DistributionSourcePackageChangelogView',
14 'DistributionSourcePackagePublishingHistoryView',
15 ]16 ]
1617
17from datetime import datetime18from datetime import datetime
@@ -20,12 +21,17 @@
2021
21from lazr.delegates import delegates22from lazr.delegates import delegates
22import pytz23import pytz
23from zope.component import getUtility24from zope.component import (
25 adapter,
26 getUtility,
27 )
24from zope.interface import (28from zope.interface import (
29 implementer,
25 implements,30 implements,
26 Interface,31 Interface,
27 )32 )
2833
34from canonical.launchpad.webapp.interfaces import IBreadcrumb
29from canonical.launchpad.helpers import shortlist35from canonical.launchpad.helpers import shortlist
30from canonical.launchpad.webapp import (36from canonical.launchpad.webapp import (
31 action,37 action,
@@ -44,6 +50,7 @@
44 NavigationMenu,50 NavigationMenu,
45 )51 )
46from canonical.launchpad.webapp.sorting import sorted_dotted_numbers52from canonical.launchpad.webapp.sorting import sorted_dotted_numbers
53from lp.app.interfaces.launchpad import IServiceUsage
47from lp.app.browser.tales import CustomizableFormatter54from lp.app.browser.tales import CustomizableFormatter
48from canonical.lazr.utils import smartquote55from canonical.lazr.utils import smartquote
49from lp.answers.browser.questiontarget import (56from lp.answers.browser.questiontarget import (
@@ -88,8 +95,10 @@
88 return {'displayname': displayname}95 return {'displayname': displayname}
8996
9097
98@adapter(IDistributionSourcePackage)
91class DistributionSourcePackageBreadcrumb(Breadcrumb):99class DistributionSourcePackageBreadcrumb(Breadcrumb):
92 """Builds a breadcrumb for an `IDistributionSourcePackage`."""100 """Builds a breadcrumb for an `IDistributionSourcePackage`."""
101 implements(IBreadcrumb)
93102
94 @property103 @property
95 def text(self):104 def text(self):
@@ -97,6 +106,12 @@
97 self.context.sourcepackagename.name)106 self.context.sourcepackagename.name)
98107
99108
109@adapter(IDistributionSourcePackage)
110@implementer(IServiceUsage)
111def distribution_from_distributionsourcepackage(dsp):
112 return dsp.distribution
113
114
100class DistributionSourcePackageFacets(QuestionTargetFacetMixin,115class DistributionSourcePackageFacets(QuestionTargetFacetMixin,
101 StandardLaunchpadFacets):116 StandardLaunchpadFacets):
102117
103118
=== modified file 'lib/lp/registry/browser/pillar.py'
--- lib/lp/registry/browser/pillar.py 2010-10-06 19:44:28 +0000
+++ lib/lp/registry/browser/pillar.py 2010-10-07 13:33:43 +0000
@@ -31,8 +31,8 @@
31 )31 )
32from lp.app.browser.tales import MenuAPI32from lp.app.browser.tales import MenuAPI
33from lp.app.enums import (33from lp.app.enums import (
34 service_uses_launchpad,
34 ServiceUsage,35 ServiceUsage,
35 service_uses_launchpad,
36 )36 )
37from lp.app.interfaces.launchpad import IServiceUsage37from lp.app.interfaces.launchpad import IServiceUsage
38from lp.registry.browser.structuralsubscription import (38from lp.registry.browser.structuralsubscription import (
@@ -113,34 +113,33 @@
113 self.translations_usage = ServiceUsage.UNKNOWN113 self.translations_usage = ServiceUsage.UNKNOWN
114 self.codehosting_usage = ServiceUsage.UNKNOWN114 self.codehosting_usage = ServiceUsage.UNKNOWN
115 pillar = nearest(self.context, IPillar)115 pillar = nearest(self.context, IPillar)
116 if IProjectGroup.providedBy(pillar):116
117 for product in pillar.products:117 self._set_official_launchpad(pillar)
118 self._set_official_launchpad(product)118 if IDistroSeries.providedBy(self.context):
119 distribution = self.context.distribution
120 self.codehosting_usage = distribution.codehosting_usage
121 self.answers_usage = ServiceUsage.NOT_APPLICABLE
122 elif IDistributionSourcePackage.providedBy(self.context):
123 self.blueprints_usage = ServiceUsage.UNKNOWN
124 self.translations_usage = ServiceUsage.UNKNOWN
125 elif IProjectGroup.providedBy(pillar):
126 # XXX: 2010-10-07 EdwinGrubbs bug=656292
127 # Fix _set_official_launchpad().
128
119 # Project groups do not support submit code, override the129 # Project groups do not support submit code, override the
120 # default.130 # default.
121 self.codehosting_usage = ServiceUsage.NOT_APPLICABLE131 self.codehosting_usage = ServiceUsage.NOT_APPLICABLE
122 # Product groups must have translatable products for
123 # translations_usage to be ServiceUsage.LAUNCHPAD
124 if not pillar.has_translatable():
125 self.translations_usage = ServiceUsage.UNKNOWN
126 else:132 else:
127 self._set_official_launchpad(pillar)133 # The context is used by all apps.
128 if IDistroSeries.providedBy(self.context):134 pass
129 distribution = self.context.distribution
130 self.codehosting_usage = distribution.codehosting_usage
131 self.answers_usage = ServiceUsage.NOT_APPLICABLE
132 elif IDistributionSourcePackage.providedBy(self.context):
133 self.blueprints_usage = ServiceUsage.UNKNOWN
134 self.translations_usage = ServiceUsage.UNKNOWN
135 else:
136 # The context is used by all apps.
137 pass
138135
139 def _set_official_launchpad(self, pillar):136 def _set_official_launchpad(self, pillar):
140 """Does the pillar officially use launchpad."""137 """Does the pillar officially use launchpad."""
138 # XXX: 2010-10-07 EdwinGrubbs bug=656292
139 # Fix _set_official_launchpad().
141 # This if structure is required because it may be called many140 # This if structure is required because it may be called many
142 # times to build the complete set of official applications.141 # times to build the complete set of official applications.
143 if pillar.official_malone:142 if service_uses_launchpad(IServiceUsage(pillar).bug_tracking_usage):
144 self.official_malone = True143 self.official_malone = True
145 if service_uses_launchpad(IServiceUsage(pillar).answers_usage):144 if service_uses_launchpad(IServiceUsage(pillar).answers_usage):
146 self.answers_usage = ServiceUsage.LAUNCHPAD145 self.answers_usage = ServiceUsage.LAUNCHPAD
147146
=== modified file 'lib/lp/registry/browser/sourcepackage.py'
--- lib/lp/registry/browser/sourcepackage.py 2010-09-29 00:17:32 +0000
+++ lib/lp/registry/browser/sourcepackage.py 2010-10-07 13:33:43 +0000
@@ -27,11 +27,16 @@
27from zope.app.form.browser import DropdownWidget27from zope.app.form.browser import DropdownWidget
28from zope.app.form.interfaces import IInputWidget28from zope.app.form.interfaces import IInputWidget
29from zope.component import (29from zope.component import (
30 adapter,
30 getMultiAdapter,31 getMultiAdapter,
31 getUtility,32 getUtility,
32 )33 )
33from zope.formlib.form import Fields34from zope.formlib.form import Fields
34from zope.interface import Interface35from zope.interface import (
36 implementer,
37 implements,
38 Interface,
39 )
35from zope.schema import (40from zope.schema import (
36 Choice,41 Choice,
37 TextLine,42 TextLine,
@@ -42,10 +47,12 @@
42 SimpleVocabulary,47 SimpleVocabulary,
43 )48 )
4449
50from canonical.launchpad.webapp.interfaces import IBreadcrumb
45from canonical.launchpad import (51from canonical.launchpad import (
46 _,52 _,
47 helpers,53 helpers,
48 )54 )
55from lp.app.interfaces.launchpad import IServiceUsage
49from lp.app.browser.tales import CustomizableFormatter56from lp.app.browser.tales import CustomizableFormatter
50from canonical.launchpad.browser.multistep import (57from canonical.launchpad.browser.multistep import (
51 MultiStepView,58 MultiStepView,
@@ -170,8 +177,16 @@
170 return redirection(redirection_url)177 return redirection(redirection_url)
171178
172179
180@adapter(ISourcePackage)
181@implementer(IServiceUsage)
182def distribution_from_sourcepackage(package):
183 return package.distribution
184
185
186@adapter(ISourcePackage)
173class SourcePackageBreadcrumb(Breadcrumb):187class SourcePackageBreadcrumb(Breadcrumb):
174 """Builds a breadcrumb for an `ISourcePackage`."""188 """Builds a breadcrumb for an `ISourcePackage`."""
189 implements(IBreadcrumb)
175190
176 @property191 @property
177 def text(self):192 def text(self):
178193
=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml 2010-10-04 20:46:55 +0000
+++ lib/lp/registry/configure.zcml 2010-10-07 13:33:43 +0000
@@ -498,10 +498,9 @@
498 provides="canonical.launchpad.webapp.interfaces.ILaunchpadContainer"498 provides="canonical.launchpad.webapp.interfaces.ILaunchpadContainer"
499 factory="canonical.launchpad.components.launchpadcontainer.LaunchpadDistributionSourcePackageContainer"/>499 factory="canonical.launchpad.components.launchpadcontainer.LaunchpadDistributionSourcePackageContainer"/>
500 <adapter500 <adapter
501 provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"501 factory="lp.registry.browser.distributionsourcepackage.distribution_from_distributionsourcepackage"/>
502 for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"502 <adapter
503 factory="lp.registry.browser.distributionsourcepackage.DistributionSourcePackageBreadcrumb"503 factory="lp.registry.browser.distributionsourcepackage.DistributionSourcePackageBreadcrumb"/>
504 permission="zope.Public"/>
505504
506 <!-- CommercialSubscription -->505 <!-- CommercialSubscription -->
507506
@@ -1615,10 +1614,9 @@
1615 interface="lp.registry.interfaces.sourcepackage.ISourcePackageFactory"/>1614 interface="lp.registry.interfaces.sourcepackage.ISourcePackageFactory"/>
1616 </securedutility>1615 </securedutility>
1617 <adapter1616 <adapter
1618 provides="canonical.launchpad.webapp.interfaces.IBreadcrumb"1617 factory="lp.registry.browser.sourcepackage.SourcePackageBreadcrumb"/>
1619 for="lp.registry.interfaces.sourcepackage.ISourcePackage"1618 <adapter
1620 factory="lp.registry.browser.sourcepackage.SourcePackageBreadcrumb"1619 factory="lp.registry.browser.sourcepackage.distribution_from_sourcepackage"/>
1621 permission="zope.Public"/>
16221620
1623 <!-- This is class ProductReleaseSet -->1621 <!-- This is class ProductReleaseSet -->
16241622
16251623
=== modified file 'lib/lp/registry/interfaces/projectgroup.py'
--- lib/lp/registry/interfaces/projectgroup.py 2010-10-06 19:44:28 +0000
+++ lib/lp/registry/interfaces/projectgroup.py 2010-10-07 13:33:43 +0000
@@ -51,6 +51,7 @@
51 )51 )
52from canonical.launchpad.validators.name import name_validator52from canonical.launchpad.validators.name import name_validator
53from lp.app.interfaces.headings import IRootContext53from lp.app.interfaces.headings import IRootContext
54from lp.app.interfaces.launchpad import IServiceUsage
54from lp.blueprints.interfaces.specificationtarget import IHasSpecifications55from lp.blueprints.interfaces.specificationtarget import IHasSpecifications
55from lp.blueprints.interfaces.sprint import IHasSprints56from lp.blueprints.interfaces.sprint import IHasSprints
56from lp.bugs.interfaces.bugtarget import (57from lp.bugs.interfaces.bugtarget import (
@@ -111,7 +112,7 @@
111 IHasDrivers, IHasBranchVisibilityPolicy, IHasIcon, IHasLogo,112 IHasDrivers, IHasBranchVisibilityPolicy, IHasIcon, IHasLogo,
112 IHasMentoringOffers, IHasMergeProposals, IHasMilestones, IHasMugshot,113 IHasMentoringOffers, IHasMergeProposals, IHasMilestones, IHasMugshot,
113 IHasOwner, IHasSpecifications, IHasSprints, IMakesAnnouncements,114 IHasOwner, IHasSpecifications, IHasSprints, IMakesAnnouncements,
114 IKarmaContext, IRootContext, IHasOfficialBugTags):115 IKarmaContext, IRootContext, IHasOfficialBugTags, IServiceUsage):
115 """Public IProjectGroup properties."""116 """Public IProjectGroup properties."""
116117
117 id = Int(title=_('ID'), readonly=True)118 id = Int(title=_('ID'), readonly=True)
118119
=== modified file 'lib/lp/registry/model/projectgroup.py'
--- lib/lp/registry/model/projectgroup.py 2010-10-06 19:44:28 +0000
+++ lib/lp/registry/model/projectgroup.py 2010-10-07 13:33:43 +0000
@@ -52,6 +52,7 @@
52 FAQSearch,52 FAQSearch,
53 )53 )
54from lp.answers.model.question import QuestionTargetSearch54from lp.answers.model.question import QuestionTargetSearch
55from lp.app.enums import ServiceUsage
55from lp.app.errors import NotFoundError56from lp.app.errors import NotFoundError
56from lp.blueprints.interfaces.specification import (57from lp.blueprints.interfaces.specification import (
57 SpecificationFilter,58 SpecificationFilter,
@@ -492,6 +493,56 @@
492493
493 return ProjectGroupSeries(self, series_name)494 return ProjectGroupSeries(self, series_name)
494495
496 def _get_usage(self, attr):
497 """Determine ProjectGroup usage based on individual projects.
498
499 By default, return ServiceUsage.UNKNOWN.
500 If any project uses Launchpad, return ServiceUsage.LAUNCHPAD.
501 Otherwise, return the ServiceUsage of the last project that was
502 not ServiceUsage.UNKNOWN.
503 """
504 result = ServiceUsage.UNKNOWN
505 for product in self.products:
506 product_usage = getattr(product, attr)
507 if product_usage != ServiceUsage.UNKNOWN:
508 result = product_usage
509 if product_usage == ServiceUsage.LAUNCHPAD:
510 break
511 return result
512
513 @property
514 def answers_usage(self):
515 return self._get_usage('answers_usage')
516
517 @property
518 def blueprints_usage(self):
519 return self._get_usage('blueprints_usage')
520
521 @property
522 def translations_usage(self):
523 if self.has_translatable():
524 return ServiceUsage.LAUNCHPAD
525 return ServiceUsage.UNKNOWN
526
527 @property
528 def codehosting_usage(self):
529 # Project groups do not support submitting code.
530 return ServiceUsage.NOT_APPLICABLE
531
532 @property
533 def bug_tracking_usage(self):
534 return self._get_usage('bug_tracking_usage')
535
536 @property
537 def uses_launchpad(self):
538 if (self.answers_usage == ServiceUsage.LAUNCHPAD
539 or self.blueprints_usage == ServiceUsage.LAUNCHPAD
540 or self.translations_usage == ServiceUsage.LAUNCHPAD
541 or self.codehosting_usage == ServiceUsage.LAUNCHPAD
542 or self.bug_tracking_usage == ServiceUsage.LAUNCHPAD):
543 return True
544 return False
545
495546
496class ProjectGroupSet:547class ProjectGroupSet:
497 implements(IProjectGroupSet)548 implements(IProjectGroupSet)
498549
=== added file 'lib/lp/testing/service_usage_helpers.py'
--- lib/lp/testing/service_usage_helpers.py 1970-01-01 00:00:00 +0000
+++ lib/lp/testing/service_usage_helpers.py 2010-10-07 13:33:43 +0000
@@ -0,0 +1,33 @@
1# Copyright 2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).
3
4"""Helper functions dealing with IServiceUsage."""
5__metaclass__ = type
6
7import transaction
8from zope.component import getUtility
9
10from lp.app.enums import ServiceUsage
11from lp.registry.interfaces.pillar import IPillarNameSet
12from lp.testing import (
13 login,
14 logout,
15 )
16from lp.testing.factory import LaunchpadObjectFactory
17from lp.testing.sampledata import ADMIN_EMAIL
18
19
20def set_service_usage(pillar_name, **kw):
21 factory = LaunchpadObjectFactory()
22 login(ADMIN_EMAIL)
23 pillar = getUtility(IPillarNameSet)[pillar_name]
24 for attr, service_usage_name in kw.items():
25 service_usage = getattr(ServiceUsage, service_usage_name)
26 if attr == 'bug_tracking_usage':
27 pillar.official_malone = (service_usage == ServiceUsage.LAUNCHPAD)
28 if service_usage == ServiceUsage.EXTERNAL:
29 pillar.bugtracker = factory.makeBugTracker()
30 else:
31 setattr(pillar, attr, service_usage)
32 #transaction.commit()
33 logout()