Merge lp:~adeuring/launchpad/bug-596944-model into lp:launchpad/db-devel

Proposed by Abel Deuring
Status: Merged
Approved by: Leonard Richardson
Approved revision: no longer in the source branch.
Merged at revision: 10022
Proposed branch: lp:~adeuring/launchpad/bug-596944-model
Merge into: lp:launchpad/db-devel
Diff against target: 314 lines (+191/-3)
9 files modified
lib/lp/bugs/interfaces/bugtarget.py (+4/-0)
lib/lp/bugs/model/bugtarget.py (+4/-0)
lib/lp/bugs/tests/test_bugtarget2.py (+156/-0)
lib/lp/registry/configure.zcml (+5/-1)
lib/lp/registry/interfaces/projectgroup.py (+4/-0)
lib/lp/registry/model/distributionsourcepackage.py (+6/-2)
lib/lp/registry/model/product.py (+1/-0)
lib/lp/registry/model/productseries.py (+5/-0)
lib/lp/registry/model/sourcepackage.py (+6/-0)
To merge this branch: bzr merge lp:~adeuring/launchpad/bug-596944-model
Reviewer Review Type Date Requested Status
Leonard Richardson (community) Approve
Review via email: mp+42253@code.launchpad.net

Commit message

[incr] [r=leonardr][ui=none][bug=596944] property enable_bugfiling_duplicate_search added to bug target model classes.

Description of the change

This branch is a step to fix bug 596944: Allow projects to
disable duplicate detection when reporting a bug. It adds a
new property enable_bugfiling_duplicate_search to bug target
classes and to ProjectGroup.

The option to enable or disable dupe search will be selectable
only for products and for source packages (see also this
branch: lp:~adeuring/launchpad/bug-596944-schema); I added the
property to all bug targets so that we don't need to check in
browser code if the current bug target has the property
enable_bugfiling_duplicate_search.

So we have three cases:
- enable_bugfiling_duplicate_search is always True: This is the
  case for distributions and for project groups
- enable_bugfiling_duplicate_search is settable: products and
  DSPs
- enable_bugfiling_duplicate_search is inherited from a parent
  object: product series and source package.

test: ./bin/test -vvt test_bugtarget2

no lint

To post a comment you must log in.
Revision history for this message
Leonard Richardson (leonardr) :
review: Approve

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-11-18 14:00:49 +0000
3+++ lib/lp/bugs/interfaces/bugtarget.py 2010-11-30 15:18:35 +0000
4@@ -297,6 +297,10 @@
5 required=False,
6 max_length=50000))
7
8+ enable_bugfiling_duplicate_search = Bool(
9+ title=u"Search for possible duplicate bugs when a new bug is filed",
10+ required=False)
11+
12 def createBug(bug_params):
13 """Create a new bug on this target.
14
15
16=== modified file 'lib/lp/bugs/model/bugtarget.py'
17--- lib/lp/bugs/model/bugtarget.py 2010-11-18 14:00:49 +0000
18+++ lib/lp/bugs/model/bugtarget.py 2010-11-30 15:18:35 +0000
19@@ -244,6 +244,10 @@
20 All IBugTargets should inherit from this class.
21 """
22
23+ # The default implementation of the property, used for
24+ # IDistribution, IDistroSeries, IProjectGroup.
25+ enable_bugfiling_duplicate_search = True
26+
27
28 class HasBugHeatMixin:
29 """Standard functionality for objects implementing IHasBugHeat."""
30
31=== added file 'lib/lp/bugs/tests/test_bugtarget2.py'
32--- lib/lp/bugs/tests/test_bugtarget2.py 1970-01-01 00:00:00 +0000
33+++ lib/lp/bugs/tests/test_bugtarget2.py 2010-11-30 15:18:35 +0000
34@@ -0,0 +1,156 @@
35+# Copyright 2010 Canonical Ltd. This software is licensed under the
36+# GNU Affero General Public License version 3 (see the file LICENSE).
37+
38+"""Tests for BugTargets."""
39+
40+__metaclass__ = type
41+
42+from zope.security.interfaces import ForbiddenAttribute
43+
44+from canonical.testing.layers import DatabaseFunctionalLayer
45+from lp.testing import (
46+ person_logged_in,
47+ TestCaseWithFactory,
48+ )
49+
50+
51+class BugTargetBugFilingDuplicateSearchAlwaysOn:
52+ """A base class for tests of bug targets where dupes are always searched.
53+ """
54+
55+ def test_enable_bugfiling_duplicate_search(self):
56+ # enable_bugfiling_duplicate_search is always True.
57+ self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
58+
59+ def test_enable_bugfiling_duplicate_search_is_read_only(self):
60+ # enable_bugfiling_duplicate_search is a read-only attribute
61+ with person_logged_in(self.bugtarget.owner):
62+ self.assertRaises(
63+ ForbiddenAttribute, setattr, self.bugtarget,
64+ 'enable_bugfiling_duplicate_search', False)
65+
66+
67+class TestDistribution(BugTargetBugFilingDuplicateSearchAlwaysOn,
68+ TestCaseWithFactory):
69+ """Tests for distributions as bug targets."""
70+
71+ layer = DatabaseFunctionalLayer
72+
73+ def setUp(self):
74+ super(TestDistribution, self).setUp()
75+ self.bugtarget = self.factory.makeDistribution()
76+
77+
78+class TestDistroSeries(BugTargetBugFilingDuplicateSearchAlwaysOn,
79+ TestCaseWithFactory):
80+ """Tests for distributions as bug targets."""
81+
82+ layer = DatabaseFunctionalLayer
83+
84+ def setUp(self):
85+ super(TestDistroSeries, self).setUp()
86+ self.bugtarget = self.factory.makeDistroSeries()
87+
88+
89+class TestProjectGroup(BugTargetBugFilingDuplicateSearchAlwaysOn,
90+ TestCaseWithFactory):
91+ """Tests for distributions as bug targets."""
92+
93+ layer = DatabaseFunctionalLayer
94+
95+ def setUp(self):
96+ super(TestProjectGroup, self).setUp()
97+ self.bugtarget = self.factory.makeProject()
98+
99+
100+class BugTargetBugFilingDuplicateSearchSettable:
101+ """A base class for tests of bug targets where dupe search is settable.
102+ """
103+
104+ def test_enable_bugfiling_duplicate_search_default(self):
105+ # The default value of enable_bugfiling_duplicate_search is True.
106+ self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
107+
108+ def test_enable_bugfiling_duplicate_search_is_changeable(self):
109+ # The bug supervisor can change enable_bugfiling_duplicate_search.
110+ with person_logged_in(self.bug_supervisor):
111+ self.bugtarget.enable_bugfiling_duplicate_search = False
112+ self.assertFalse(self.bugtarget.enable_bugfiling_duplicate_search)
113+
114+
115+class TestProduct(BugTargetBugFilingDuplicateSearchSettable,
116+ TestCaseWithFactory):
117+ """Tests for products as bug targets."""
118+
119+ layer = DatabaseFunctionalLayer
120+
121+ def setUp(self):
122+ super(TestProduct, self).setUp()
123+ self.bug_supervisor = self.factory.makePerson()
124+ self.bugtarget = self.factory.makeProduct(
125+ bug_supervisor=self.bug_supervisor)
126+
127+
128+class TestDistributionSourcePackage(BugTargetBugFilingDuplicateSearchSettable,
129+ TestCaseWithFactory):
130+ """Tests for distributionsourcepackages as bug targets."""
131+
132+ layer = DatabaseFunctionalLayer
133+
134+ def setUp(self):
135+ super(TestDistributionSourcePackage, self).setUp()
136+ self.bug_supervisor = self.factory.makePerson()
137+ distribution = self.factory.makeDistribution(
138+ bug_supervisor=self.bug_supervisor)
139+ self.bugtarget = self.factory.makeDistributionSourcePackage(
140+ distribution=distribution)
141+
142+
143+class BugTargetBugFilingDuplicateSearchInherited:
144+ """A base class for tests of bug targets where the dupe search policy
145+ is inherited from a parent object.
146+ """
147+
148+ def test_enable_bugfiling_duplicate_search_default(self):
149+ # The default value of enable_bugfiling_duplicate_search is True.
150+ self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
151+
152+ def test_enable_bugfiling_duplicate_search_changed_by_parent_change(self):
153+ # If enable_bugfiling_duplicate_search is changed for the parent
154+ # object, it is changed for the bug traget too.
155+ with person_logged_in(self.bug_supervisor):
156+ self.bugtarget_parent.enable_bugfiling_duplicate_search = False
157+ self.assertFalse(self.bugtarget.enable_bugfiling_duplicate_search)
158+
159+
160+class TestProductSeries(BugTargetBugFilingDuplicateSearchInherited,
161+ TestCaseWithFactory):
162+ """Tests for product serieses as bug targets."""
163+
164+ layer = DatabaseFunctionalLayer
165+
166+ def setUp(self):
167+ super(TestProductSeries, self).setUp()
168+ self.bug_supervisor = self.factory.makePerson()
169+ self.bugtarget_parent = self.factory.makeProduct(
170+ bug_supervisor=self.bug_supervisor)
171+ self.bugtarget = self.factory.makeProductSeries(
172+ product=self.bugtarget_parent)
173+
174+
175+class TestSourcePackage(BugTargetBugFilingDuplicateSearchInherited,
176+ TestCaseWithFactory):
177+ """Tests for product serieses as bug targets."""
178+
179+ layer = DatabaseFunctionalLayer
180+
181+ def setUp(self):
182+ super(TestSourcePackage, self).setUp()
183+ self.bug_supervisor = self.factory.makePerson()
184+ distribution = self.factory.makeDistribution(
185+ bug_supervisor=self.bug_supervisor)
186+ distroseries = self.factory.makeDistroSeries(
187+ distribution=distribution)
188+ self.bugtarget = self.factory.makeSourcePackage(
189+ distroseries=distroseries)
190+ self.bugtarget_parent = self.bugtarget.distribution_sourcepackage
191
192=== modified file 'lib/lp/registry/configure.zcml'
193--- lib/lp/registry/configure.zcml 2010-11-27 05:40:38 +0000
194+++ lib/lp/registry/configure.zcml 2010-11-30 15:18:35 +0000
195@@ -449,6 +449,7 @@
196 displayname
197 distribution
198 distro
199+ enable_bugfiling_duplicate_search
200 findRelatedArchivePublications
201 findRelatedArchives
202 getBugCounts
203@@ -512,7 +513,9 @@
204 permission="launchpad.BugSupervisor"
205 set_attributes="
206 bug_reported_acknowledgement
207- bug_reporting_guidelines"/>
208+ bug_reporting_guidelines
209+ enable_bugfiling_duplicate_search
210+ "/>
211 </class>
212 <adapter
213 for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"
214@@ -1179,6 +1182,7 @@
215 <require
216 permission="launchpad.BugSupervisor"
217 set_attributes="
218+ enable_bugfiling_duplicate_search
219 bug_reported_acknowledgement
220 bug_reporting_guidelines
221 bugtracker
222
223=== modified file 'lib/lp/registry/interfaces/projectgroup.py'
224--- lib/lp/registry/interfaces/projectgroup.py 2010-11-05 09:59:37 +0000
225+++ lib/lp/registry/interfaces/projectgroup.py 2010-11-30 15:18:35 +0000
226@@ -311,6 +311,10 @@
227 required=False,
228 max_length=50000))
229
230+ enable_bugfiling_duplicate_search = Bool(
231+ title=u"Search for possible duplicate bugs when a new bug is filed",
232+ required=False, readonly=True)
233+
234 def getProduct(name):
235 """Get a product with name `name`."""
236
237
238=== modified file 'lib/lp/registry/model/distributionsourcepackage.py'
239--- lib/lp/registry/model/distributionsourcepackage.py 2010-11-05 09:16:14 +0000
240+++ lib/lp/registry/model/distributionsourcepackage.py 2010-11-30 15:18:35 +0000
241@@ -101,11 +101,12 @@
242
243 class DistributionSourcePackageProperty:
244
245- def __init__(self, attrname):
246+ def __init__(self, attrname, default=None):
247 self.attrname = attrname
248+ self.default = default
249
250 def __get__(self, obj, class_):
251- return getattr(obj._self_in_database, self.attrname, None)
252+ return getattr(obj._self_in_database, self.attrname, self.default)
253
254 def __set__(self, obj, value):
255 if obj._self_in_database is None:
256@@ -152,6 +153,8 @@
257 po_message_count = DistributionSourcePackageProperty('po_message_count')
258 is_upstream_link_allowed = DistributionSourcePackageProperty(
259 'is_upstream_link_allowed')
260+ enable_bugfiling_duplicate_search = DistributionSourcePackageProperty(
261+ 'enable_bugfiling_duplicate_search', default=True)
262
263 def __init__(self, distribution, sourcepackagename):
264 self.distribution = distribution
265@@ -607,3 +610,4 @@
266 bug_count = Int()
267 po_message_count = Int()
268 is_upstream_link_allowed = Bool()
269+ enable_bugfiling_duplicate_search = Bool()
270
271=== modified file 'lib/lp/registry/model/product.py'
272--- lib/lp/registry/model/product.py 2010-11-27 05:40:38 +0000
273+++ lib/lp/registry/model/product.py 2010-11-30 15:18:35 +0000
274@@ -453,6 +453,7 @@
275 default=None)
276 bug_reporting_guidelines = StringCol(default=None)
277 bug_reported_acknowledgement = StringCol(default=None)
278+ enable_bugfiling_duplicate_search = BoolCol(notNull=True, default=True)
279 _cached_licenses = None
280
281 def _validate_active(self, attr, value):
282
283=== modified file 'lib/lp/registry/model/productseries.py'
284--- lib/lp/registry/model/productseries.py 2010-11-27 05:40:38 +0000
285+++ lib/lp/registry/model/productseries.py 2010-11-30 15:18:35 +0000
286@@ -270,6 +270,11 @@
287 return self.product.bug_reported_acknowledgement
288
289 @property
290+ def enable_bugfiling_duplicate_search(self):
291+ """See `IBugTarget`."""
292+ return self.product.enable_bugfiling_duplicate_search
293+
294+ @property
295 def sourcepackages(self):
296 """See IProductSeries"""
297 from lp.registry.model.sourcepackage import SourcePackage
298
299=== modified file 'lib/lp/registry/model/sourcepackage.py'
300--- lib/lp/registry/model/sourcepackage.py 2010-11-15 16:25:05 +0000
301+++ lib/lp/registry/model/sourcepackage.py 2010-11-30 15:18:35 +0000
302@@ -476,6 +476,12 @@
303 """See `IBugTarget`."""
304 return self.distribution.bug_reported_acknowledgement
305
306+ @property
307+ def enable_bugfiling_duplicate_search(self):
308+ """See `IBugTarget`."""
309+ return (
310+ self.distribution_sourcepackage.enable_bugfiling_duplicate_search)
311+
312 def _customizeSearchParams(self, search_params):
313 """Customize `search_params` for this source package."""
314 search_params.setSourcePackage(self)

Subscribers

People subscribed via source and target branches

to status/vote changes: