Merge lp:~brian-murray/launchpad/bug-320596 into lp:launchpad

Proposed by Brian Murray
Status: Merged
Approved by: Brian Murray
Approved revision: no longer in the source branch.
Merged at revision: 11458
Proposed branch: lp:~brian-murray/launchpad/bug-320596
Merge into: lp:launchpad
Diff against target: 362 lines (+176/-112)
5 files modified
lib/lp/bugs/interfaces/bugtarget.py (+120/-108)
lib/lp/bugs/interfaces/bugtask.py (+2/-2)
lib/lp/bugs/stories/webservice/xx-bug-target.txt (+2/-2)
lib/lp/bugs/tests/test_bugtask.py (+9/-0)
lib/lp/bugs/tests/test_searchtasks_webservice.py (+43/-0)
To merge this branch: bzr merge lp:~brian-murray/launchpad/bug-320596
Reviewer Review Type Date Requested Status
Abel Deuring (community) code Approve
Robert Collins (community) Needs Fixing
Review via email: mp+30690@code.launchpad.net

Commit message

For the devel version of the API have omit_targeted searchTasks parameter default to False.

Description of the change

Remove the default value of True for omit_targeted so that bug tasks targeted to a milestone are no longer hidden in search results.

Tests modified:

bin/test -cvvt xx-bug.txt -t bugtask-search.txt

To post a comment you must log in.
Revision history for this message
Robert Collins (lifeless) wrote :

So, I have some needs fixing and a question.

needs fixing: please don't add these things to doctests: none of your tests look like documentation, so they shouldn't be expressed as documentation.

question: looks like you're breaking the 1.0 API to me, I thought that wasn't permitted.

review: Needs Fixing
Revision history for this message
Brian Murray (brian-murray) wrote :

I think having the default value of omit_targeted be False in the API is actually broken. This is a different default value than the web interface and resulted in terribly confusing behavior - see bug 320596 (and its duplicates). However, I'll special case the default value of it if you think that is best.

Revision history for this message
Robert Collins (lifeless) wrote :

I don't hold the value to be sacred; however its my understanding that
we promised not to change the behaviour of the 1.0 API - we can change
devel, just not 1.0.

Revision history for this message
Brian Murray (brian-murray) wrote :

This is ready for review again. omit_targeted is left defaulting to True and in devel the default value is changed to False.

Revision history for this message
Abel Deuring (adeuring) wrote :

Hi Brian,

nice work! Just one minor nitpicks: I find the name "modifiable_params" and "modified_params" a bit confusing. What about "params_for_api_1_0" and "params_for_devel"? And since these variables are defined on mudole level, perhaps even "searchtasks_params_for_api_1_0"? (Having modified_params and modifiable_params for a second exported method might lead to funny results ;)

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/bugs/interfaces/bugtarget.py'
2--- lib/lp/bugs/interfaces/bugtarget.py 2010-08-20 20:31:18 +0000
3+++ lib/lp/bugs/interfaces/bugtarget.py 2010-08-26 20:46:45 +0000
4@@ -29,11 +29,13 @@
5 exported,
6 LAZR_WEBSERVICE_EXPORTED,
7 operation_parameters,
8+ operation_removed_in_version,
9 operation_returns_collection_of,
10 REQUEST_USER,
11 )
12 from lazr.restful.fields import Reference
13 from lazr.restful.interface import copy_field
14+
15 from zope.interface import (
16 Attribute,
17 Interface,
18@@ -57,6 +59,117 @@
19 )
20 from lp.services.fields import Tag
21
22+search_tasks_params_for_api_1_0 = {
23+ "order_by": List(
24+ title=_('List of fields by which the results are ordered.'),
25+ value_type=Text(),
26+ required=False),
27+ "search_text": copy_field(IBugTaskSearch['searchtext']),
28+ "status": copy_field(IBugTaskSearch['status']),
29+ "importance": copy_field(IBugTaskSearch['importance']),
30+ "assignee": Reference(schema=Interface),
31+ "bug_reporter": Reference(schema=Interface),
32+ "bug_supervisor": Reference(schema=Interface),
33+ "bug_commenter": Reference(schema=Interface),
34+ "bug_subscriber": Reference(schema=Interface),
35+ "structural_subscriber": Reference(schema=Interface),
36+ "owner": Reference(schema=Interface),
37+ "affected_user": Reference(schema=Interface),
38+ "has_patch": copy_field(IBugTaskSearch['has_patch']),
39+ "has_cve": copy_field(IBugTaskSearch['has_cve']),
40+ "tags": copy_field(IBugTaskSearch['tag']),
41+ "tags_combinator": copy_field(IBugTaskSearch['tags_combinator']),
42+ "omit_duplicates": copy_field(IBugTaskSearch['omit_dupes']),
43+ "omit_targeted": copy_field(IBugTaskSearch['omit_targeted']),
44+ "status_upstream": copy_field(IBugTaskSearch['status_upstream']),
45+ "milestone_assignment": copy_field(IBugTaskSearch['milestone_assignment']),
46+ "milestone": copy_field(IBugTaskSearch['milestone']),
47+ "component": copy_field(IBugTaskSearch['component']),
48+ "nominated_for": Reference(schema=Interface),
49+ "has_no_package": copy_field(IBugTaskSearch['has_no_package']),
50+ "hardware_bus": Choice(
51+ title=_(u"The bus of a hardware device related to a bug"),
52+ # The vocabulary should be HWBus; this is fixed in
53+ # _schema_circular_imports to avoid circular imports.
54+ vocabulary=DBEnumeratedType, required=False),
55+ "hardware_vendor_id": TextLine(
56+ title=_(
57+ u"The vendor ID of a hardware device related to a bug."),
58+ description=_(
59+ u"Allowed values of the vendor ID depend on the bus of the "
60+ "device.\n\n"
61+ "Vendor IDs of PCI, PCCard and USB devices are hexadecimal "
62+ "string representations of 16 bit integers in the format "
63+ "'0x01ab': The prefix '0x', followed by exactly 4 digits; "
64+ "where a digit is one of the characters 0..9, a..f. The "
65+ "characters A..F are not allowed.\n\n"
66+ "SCSI vendor IDs are strings with exactly 8 characters. "
67+ "Shorter names are right-padded with space (0x20) characters."
68+ "\n\n"
69+ "IDs for other buses may be arbitrary strings."),
70+ required=False),
71+ "hardware_product_id": TextLine(
72+ title=_(
73+ u"The product ID of a hardware device related to a bug."),
74+ description=_(
75+ u"Allowed values of the product ID depend on the bus of the "
76+ "device.\n\n"
77+ "Product IDs of PCI, PCCard and USB devices are hexadecimal "
78+ "string representations of 16 bit integers in the format "
79+ "'0x01ab': The prefix '0x', followed by exactly 4 digits; "
80+ "where a digit is one of the characters 0..9, a..f. The "
81+ "characters A..F are not allowed.\n\n"
82+ "SCSI product IDs are strings with exactly 16 characters. "
83+ "Shorter names are right-padded with space (0x20) characters."
84+ "\n\n"
85+ "IDs for other buses may be arbitrary strings."),
86+ required=False),
87+ "hardware_driver_name": TextLine(
88+ title=_(
89+ u"The driver controlling a hardware device related to a "
90+ "bug."),
91+ required=False),
92+ "hardware_driver_package_name": TextLine(
93+ title=_(
94+ u"The package of the driver which controls a hardware "
95+ "device related to a bug."),
96+ required=False),
97+ "hardware_owner_is_bug_reporter": Bool(
98+ title=_(
99+ u"Search for bugs reported by people who own the given "
100+ "device or who use the given hardware driver."),
101+ required=False),
102+ "hardware_owner_is_affected_by_bug": Bool(
103+ title=_(
104+ u"Search for bugs where people affected by a bug own the "
105+ "given device or use the given hardware driver."),
106+ required=False),
107+ "hardware_owner_is_subscribed_to_bug": Bool(
108+ title=_(
109+ u"Search for bugs where a bug subscriber owns the "
110+ "given device or uses the given hardware driver."),
111+ required=False),
112+ "hardware_is_linked_to_bug": Bool(
113+ title=_(
114+ u"Search for bugs which are linked to hardware reports "
115+ "which contain the given device or whcih contain a device"
116+ "controlled by the given driver."),
117+ required=False),
118+ "linked_branches": Choice(
119+ title=_(
120+ u"Search for bugs that are linked to branches or for bugs "
121+ "that are not linked to branches."),
122+ vocabulary=BugBranchSearch, required=False),
123+ "modified_since": Datetime(
124+ title=_(
125+ u"Search for bugs that have been modified since the given "
126+ "date."),
127+ required=False),
128+ }
129+search_tasks_params_for_api_devel = search_tasks_params_for_api_1_0.copy()
130+search_tasks_params_for_api_devel["omit_targeted"] = copy_field(
131+ IBugTaskSearch['omit_targeted'], default=False)
132+
133
134 class IHasBugs(Interface):
135 """An entity which has a collection of bug tasks."""
136@@ -85,114 +198,13 @@
137 "True if a BugTask has ever been reported for this target.")
138
139 @call_with(search_params=None, user=REQUEST_USER)
140- @operation_parameters(
141- order_by=List(
142- title=_('List of fields by which the results are ordered.'),
143- value_type=Text(),
144- required=False),
145- search_text=copy_field(IBugTaskSearch['searchtext']),
146- status=copy_field(IBugTaskSearch['status']),
147- importance=copy_field(IBugTaskSearch['importance']),
148- assignee=Reference(schema=Interface),
149- bug_reporter=Reference(schema=Interface),
150- bug_supervisor=Reference(schema=Interface),
151- bug_commenter=Reference(schema=Interface),
152- bug_subscriber=Reference(schema=Interface),
153- structural_subscriber=Reference(schema=Interface),
154- owner=Reference(schema=Interface),
155- affected_user=Reference(schema=Interface),
156- has_patch=copy_field(IBugTaskSearch['has_patch']),
157- has_cve=copy_field(IBugTaskSearch['has_cve']),
158- tags=copy_field(IBugTaskSearch['tag']),
159- tags_combinator=copy_field(IBugTaskSearch['tags_combinator']),
160- omit_duplicates=copy_field(IBugTaskSearch['omit_dupes']),
161- omit_targeted=copy_field(IBugTaskSearch['omit_targeted']),
162- status_upstream=copy_field(IBugTaskSearch['status_upstream']),
163- milestone_assignment=copy_field(
164- IBugTaskSearch['milestone_assignment']),
165- milestone=copy_field(IBugTaskSearch['milestone']),
166- component=copy_field(IBugTaskSearch['component']),
167- nominated_for=Reference(schema=Interface),
168- has_no_package=copy_field(IBugTaskSearch['has_no_package']),
169- hardware_bus=Choice(
170- title=u'The bus of a hardware device related to a bug',
171- # The vocabulary should be HWBus; this is fixed in
172- # _schema_circular_imports to avoid circular imports.
173- vocabulary=DBEnumeratedType, required=False),
174- hardware_vendor_id=TextLine(
175- title=(
176- u"The vendor ID of a hardware device related to a bug."),
177- description=(
178- u"Allowed values of the vendor ID depend on the bus of the "
179- "device.\n\n"
180- "Vendor IDs of PCI, PCCard and USB devices are hexadecimal "
181- "string representations of 16 bit integers in the format "
182- "'0x01ab': The prefix '0x', followed by exactly 4 digits; "
183- "where a digit is one of the characters 0..9, a..f. The "
184- "characters A..F are not allowed.\n\n"
185- "SCSI vendor IDs are strings with exactly 8 characters. "
186- "Shorter names are right-padded with space (0x20) characters."
187- "\n\n"
188- "IDs for other buses may be arbitrary strings."),
189- required=False),
190- hardware_product_id=TextLine(
191- title=(
192- u"The product ID of a hardware device related to a bug."),
193- description=(
194- u"Allowed values of the product ID depend on the bus of the "
195- "device.\n\n"
196- "Product IDs of PCI, PCCard and USB devices are hexadecimal "
197- "string representations of 16 bit integers in the format "
198- "'0x01ab': The prefix '0x', followed by exactly 4 digits; "
199- "where a digit is one of the characters 0..9, a..f. The "
200- "characters A..F are not allowed.\n\n"
201- "SCSI product IDs are strings with exactly 16 characters. "
202- "Shorter names are right-padded with space (0x20) characters."
203- "\n\n"
204- "IDs for other buses may be arbitrary strings."),
205- required=False),
206- hardware_driver_name=TextLine(
207- title=(
208- u"The driver controlling a hardware device related to a "
209- "bug."),
210- required=False),
211- hardware_driver_package_name=TextLine(
212- title=(
213- u"The package of the driver which controls a hardware "
214- "device related to a bug."),
215- required=False),
216- hardware_owner_is_bug_reporter=Bool(
217- title=(
218- u"Search for bugs reported by people who own the given "
219- "device or who use the given hardware driver."),
220- required=False),
221- hardware_owner_is_affected_by_bug=Bool(
222- title=(
223- u"Search for bugs where people affected by a bug own the "
224- "given device or use the given hardware driver."),
225- required=False),
226- hardware_owner_is_subscribed_to_bug=Bool(
227- title=(
228- u"Search for bugs where a bug subscriber owns the "
229- "given device or uses the given hardware driver."),
230- required=False),
231- hardware_is_linked_to_bug=Bool(
232- title=(
233- u"Search for bugs which are linked to hardware reports "
234- "which contain the given device or whcih contain a device"
235- "controlled by the given driver."),
236- required=False),
237- linked_branches=Choice(
238- title=(
239- u"Search for bugs that are linked to branches or for bugs "
240- "that are not linked to branches."),
241- vocabulary=BugBranchSearch, required=False),
242- modified_since=Datetime(
243- title=(
244- u"Search for bugs that have been modified since the given "
245- "date."),
246- required=False),
247- )
248+ @operation_parameters(**search_tasks_params_for_api_devel)
249+ @operation_returns_collection_of(IBugTask)
250+ @export_read_operation()
251+ @operation_removed_in_version('devel')
252+
253+ @call_with(search_params=None, user=REQUEST_USER)
254+ @operation_parameters(**search_tasks_params_for_api_1_0)
255 @operation_returns_collection_of(IBugTask)
256 @export_read_operation()
257 def searchTasks(search_params, user=None,
258
259=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
260--- lib/lp/bugs/interfaces/bugtask.py 2010-08-22 18:31:30 +0000
261+++ lib/lp/bugs/interfaces/bugtask.py 2010-08-26 20:46:45 +0000
262@@ -892,7 +892,7 @@
263 title=_('Omit bugs marked as duplicate,'), required=False,
264 default=True)
265 omit_targeted = Bool(
266- title=_('Omit bugs targeted to series'), required=False,
267+ title=_('Omit bugs targeted to a series'), required=False,
268 default=True)
269 statusexplanation = TextLine(
270 title=_("Status notes"), required=False)
271@@ -1063,7 +1063,7 @@
272
273
274 class IDistroSeriesBugTask(IBugTask):
275- """A bug needing fixing in a distrorealease, or a specific package."""
276+ """A bug needing fixing in a distrorelease, or a specific package."""
277 sourcepackagename = Choice(
278 title=_("Source Package Name"), required=True,
279 vocabulary='SourcePackageName')
280
281=== modified file 'lib/lp/bugs/stories/webservice/xx-bug-target.txt'
282--- lib/lp/bugs/stories/webservice/xx-bug-target.txt 2010-07-14 15:42:40 +0000
283+++ lib/lp/bugs/stories/webservice/xx-bug-target.txt 2010-08-26 20:46:45 +0000
284@@ -57,8 +57,8 @@
285 >>> product = factory.makeProduct(name='tags-test-product', owner=salgado)
286 >>> logout()
287
288-The webserice client is logged in as salgado, so we can add a new
289-official tag.
290+The webservice client is logged in as salgado, so we can add a new official
291+tag.
292
293 >>> print webservice.named_post(
294 ... '/tags-test-product', 'addOfficialBugTag',
295
296=== modified file 'lib/lp/bugs/tests/test_bugtask.py'
297--- lib/lp/bugs/tests/test_bugtask.py 2010-08-22 18:31:30 +0000
298+++ lib/lp/bugs/tests/test_bugtask.py 2010-08-26 20:46:45 +0000
299@@ -830,6 +830,15 @@
300 self.assertStatementCount(1,
301 lambda:[task.getConjoinedMaster for task in tasks])
302
303+ def test_omit_targeted_default_is_false(self):
304+ # The default value of omit_targeted is false so bugs targeted
305+ # to a series are not hidden.
306+ target = self.factory.makeDistroRelease()
307+ self.login()
308+ task1 = self.factory.makeBugTask(target=target)
309+ default_result = target.searchTasks(None)
310+ self.assertEqual([task1], list(default_result))
311+
312
313 def test_suite():
314 suite = unittest.TestSuite()
315
316=== added file 'lib/lp/bugs/tests/test_searchtasks_webservice.py'
317--- lib/lp/bugs/tests/test_searchtasks_webservice.py 1970-01-01 00:00:00 +0000
318+++ lib/lp/bugs/tests/test_searchtasks_webservice.py 2010-08-26 20:46:45 +0000
319@@ -0,0 +1,43 @@
320+# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
321+# GNU Affero General Public License version 3 (see the file LICENSE).
322+
323+"""Webservice unit tests related to Launchpad Bugs."""
324+
325+__metaclass__ = type
326+
327+from unittest import TestLoader
328+
329+from canonical.launchpad.ftests import login
330+from lp.testing import TestCaseWithFactory
331+from canonical.launchpad.testing.pages import LaunchpadWebServiceCaller
332+from canonical.testing import DatabaseFunctionalLayer
333+
334+
335+class TestOmitTargetedParameter(TestCaseWithFactory):
336+ """Test all values for the omit_targeted search parameter."""
337+ layer = DatabaseFunctionalLayer
338+
339+ def setUp(self):
340+ TestCaseWithFactory.setUp(self)
341+ login('foo.bar@canonical.com')
342+ self.distro = self.factory.makeDistribution(name='mebuntu')
343+ self.release = self.factory.makeDistroRelease(name='inkanyamba',
344+ distribution=self.distro)
345+ self.bug = self.factory.makeBugTask(target=self.release)
346+
347+ self.webservice = LaunchpadWebServiceCaller('launchpad-library',
348+ 'salgado-change-anything')
349+
350+ def test_omit_targeted_old_default_true(self):
351+ response = self.webservice.named_get('/mebuntu/inkanyamba',
352+ 'searchTasks', api_version='1.0').jsonBody()
353+ self.assertEqual(response['total_size'], 0)
354+
355+ def test_omit_targeted_new_default_false(self):
356+ response = self.webservice.named_get('/mebuntu/inkanyamba',
357+ 'searchTasks', api_version='devel').jsonBody()
358+ self.assertEqual(response['total_size'], 1)
359+
360+
361+def test_suite():
362+ return TestLoader().loadTestsFromName(__name__)