← Back to team overview

launchpad-reviewers team mailing list archive

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

 

Abel Deuring has proposed merging lp:~adeuring/launchpad/bug-596944-model into lp:launchpad/db-devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #596944 Allow projects to disable duplicate detection when reporting a bug
  https://bugs.launchpad.net/bugs/596944


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

-- 
https://code.launchpad.net/~adeuring/launchpad/bug-596944-model/+merge/42253
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~adeuring/launchpad/bug-596944-model into lp:launchpad/db-devel.
=== modified file 'lib/lp/bugs/interfaces/bugtarget.py'
--- lib/lp/bugs/interfaces/bugtarget.py	2010-11-18 14:00:49 +0000
+++ lib/lp/bugs/interfaces/bugtarget.py	2010-11-30 15:18:35 +0000
@@ -297,6 +297,10 @@
             required=False,
             max_length=50000))
 
+    enable_bugfiling_duplicate_search = Bool(
+        title=u"Search for possible duplicate bugs when a new bug is filed",
+        required=False)
+
     def createBug(bug_params):
         """Create a new bug on this target.
 

=== modified file 'lib/lp/bugs/model/bugtarget.py'
--- lib/lp/bugs/model/bugtarget.py	2010-11-18 14:00:49 +0000
+++ lib/lp/bugs/model/bugtarget.py	2010-11-30 15:18:35 +0000
@@ -244,6 +244,10 @@
     All IBugTargets should inherit from this class.
     """
 
+    # The default implementation of the property, used for
+    # IDistribution, IDistroSeries, IProjectGroup.
+    enable_bugfiling_duplicate_search = True
+
 
 class HasBugHeatMixin:
     """Standard functionality for objects implementing IHasBugHeat."""

=== added file 'lib/lp/bugs/tests/test_bugtarget2.py'
--- lib/lp/bugs/tests/test_bugtarget2.py	1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/tests/test_bugtarget2.py	2010-11-30 15:18:35 +0000
@@ -0,0 +1,156 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for BugTargets."""
+
+__metaclass__ = type
+
+from zope.security.interfaces import ForbiddenAttribute
+
+from canonical.testing.layers import DatabaseFunctionalLayer
+from lp.testing import (
+    person_logged_in,
+    TestCaseWithFactory,
+    )
+
+
+class BugTargetBugFilingDuplicateSearchAlwaysOn:
+    """A base class for tests of bug targets where dupes are always searched.
+    """
+
+    def test_enable_bugfiling_duplicate_search(self):
+        # enable_bugfiling_duplicate_search is always True.
+        self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
+
+    def test_enable_bugfiling_duplicate_search_is_read_only(self):
+        # enable_bugfiling_duplicate_search is a read-only attribute
+        with person_logged_in(self.bugtarget.owner):
+            self.assertRaises(
+                ForbiddenAttribute, setattr, self.bugtarget,
+                'enable_bugfiling_duplicate_search', False)
+
+
+class TestDistribution(BugTargetBugFilingDuplicateSearchAlwaysOn,
+                       TestCaseWithFactory):
+    """Tests for distributions as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestDistribution, self).setUp()
+        self.bugtarget = self.factory.makeDistribution()
+
+
+class TestDistroSeries(BugTargetBugFilingDuplicateSearchAlwaysOn,
+                       TestCaseWithFactory):
+    """Tests for distributions as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestDistroSeries, self).setUp()
+        self.bugtarget = self.factory.makeDistroSeries()
+
+
+class TestProjectGroup(BugTargetBugFilingDuplicateSearchAlwaysOn,
+                       TestCaseWithFactory):
+    """Tests for distributions as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestProjectGroup, self).setUp()
+        self.bugtarget = self.factory.makeProject()
+
+
+class BugTargetBugFilingDuplicateSearchSettable:
+    """A base class for tests of bug targets where dupe search is settable.
+    """
+
+    def test_enable_bugfiling_duplicate_search_default(self):
+        # The default value of enable_bugfiling_duplicate_search is True.
+        self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
+
+    def test_enable_bugfiling_duplicate_search_is_changeable(self):
+        # The bug supervisor can change enable_bugfiling_duplicate_search.
+        with person_logged_in(self.bug_supervisor):
+            self.bugtarget.enable_bugfiling_duplicate_search = False
+        self.assertFalse(self.bugtarget.enable_bugfiling_duplicate_search)
+
+
+class TestProduct(BugTargetBugFilingDuplicateSearchSettable,
+                  TestCaseWithFactory):
+    """Tests for products as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestProduct, self).setUp()
+        self.bug_supervisor = self.factory.makePerson()
+        self.bugtarget = self.factory.makeProduct(
+            bug_supervisor=self.bug_supervisor)
+
+
+class TestDistributionSourcePackage(BugTargetBugFilingDuplicateSearchSettable,
+                                    TestCaseWithFactory):
+    """Tests for distributionsourcepackages as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestDistributionSourcePackage, self).setUp()
+        self.bug_supervisor = self.factory.makePerson()
+        distribution = self.factory.makeDistribution(
+            bug_supervisor=self.bug_supervisor)
+        self.bugtarget = self.factory.makeDistributionSourcePackage(
+            distribution=distribution)
+
+
+class BugTargetBugFilingDuplicateSearchInherited:
+    """A base class for tests of bug targets where the dupe search policy
+    is inherited from a parent object.
+    """
+
+    def test_enable_bugfiling_duplicate_search_default(self):
+        # The default value of enable_bugfiling_duplicate_search is True.
+        self.assertTrue(self.bugtarget.enable_bugfiling_duplicate_search)
+
+    def test_enable_bugfiling_duplicate_search_changed_by_parent_change(self):
+        # If enable_bugfiling_duplicate_search is changed for the parent
+        # object, it is changed for the bug traget too.
+        with person_logged_in(self.bug_supervisor):
+            self.bugtarget_parent.enable_bugfiling_duplicate_search = False
+        self.assertFalse(self.bugtarget.enable_bugfiling_duplicate_search)
+
+
+class TestProductSeries(BugTargetBugFilingDuplicateSearchInherited,
+                        TestCaseWithFactory):
+    """Tests for product serieses as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestProductSeries, self).setUp()
+        self.bug_supervisor = self.factory.makePerson()
+        self.bugtarget_parent = self.factory.makeProduct(
+            bug_supervisor=self.bug_supervisor)
+        self.bugtarget = self.factory.makeProductSeries(
+            product=self.bugtarget_parent)
+
+
+class TestSourcePackage(BugTargetBugFilingDuplicateSearchInherited,
+                       TestCaseWithFactory):
+    """Tests for product serieses as bug targets."""
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestSourcePackage, self).setUp()
+        self.bug_supervisor = self.factory.makePerson()
+        distribution = self.factory.makeDistribution(
+            bug_supervisor=self.bug_supervisor)
+        distroseries = self.factory.makeDistroSeries(
+            distribution=distribution)
+        self.bugtarget = self.factory.makeSourcePackage(
+            distroseries=distroseries)
+        self.bugtarget_parent = self.bugtarget.distribution_sourcepackage

=== modified file 'lib/lp/registry/configure.zcml'
--- lib/lp/registry/configure.zcml	2010-11-27 05:40:38 +0000
+++ lib/lp/registry/configure.zcml	2010-11-30 15:18:35 +0000
@@ -449,6 +449,7 @@
                 displayname
                 distribution
                 distro
+                enable_bugfiling_duplicate_search
                 findRelatedArchivePublications
                 findRelatedArchives
                 getBugCounts
@@ -512,7 +513,9 @@
             permission="launchpad.BugSupervisor"
             set_attributes="
                 bug_reported_acknowledgement
-                bug_reporting_guidelines"/>
+                bug_reporting_guidelines
+                enable_bugfiling_duplicate_search
+                "/>
     </class>
     <adapter
         for="lp.registry.interfaces.distributionsourcepackage.IDistributionSourcePackage"
@@ -1179,6 +1182,7 @@
         <require
             permission="launchpad.BugSupervisor"
             set_attributes="
+                enable_bugfiling_duplicate_search
                 bug_reported_acknowledgement
                 bug_reporting_guidelines
                 bugtracker

=== modified file 'lib/lp/registry/interfaces/projectgroup.py'
--- lib/lp/registry/interfaces/projectgroup.py	2010-11-05 09:59:37 +0000
+++ lib/lp/registry/interfaces/projectgroup.py	2010-11-30 15:18:35 +0000
@@ -311,6 +311,10 @@
             required=False,
             max_length=50000))
 
+    enable_bugfiling_duplicate_search = Bool(
+        title=u"Search for possible duplicate bugs when a new bug is filed",
+        required=False, readonly=True)
+
     def getProduct(name):
         """Get a product with name `name`."""
 

=== modified file 'lib/lp/registry/model/distributionsourcepackage.py'
--- lib/lp/registry/model/distributionsourcepackage.py	2010-11-05 09:16:14 +0000
+++ lib/lp/registry/model/distributionsourcepackage.py	2010-11-30 15:18:35 +0000
@@ -101,11 +101,12 @@
 
 class DistributionSourcePackageProperty:
 
-    def __init__(self, attrname):
+    def __init__(self, attrname, default=None):
         self.attrname = attrname
+        self.default = default
 
     def __get__(self, obj, class_):
-        return getattr(obj._self_in_database, self.attrname, None)
+        return getattr(obj._self_in_database, self.attrname, self.default)
 
     def __set__(self, obj, value):
         if obj._self_in_database is None:
@@ -152,6 +153,8 @@
     po_message_count = DistributionSourcePackageProperty('po_message_count')
     is_upstream_link_allowed = DistributionSourcePackageProperty(
         'is_upstream_link_allowed')
+    enable_bugfiling_duplicate_search = DistributionSourcePackageProperty(
+        'enable_bugfiling_duplicate_search', default=True)
 
     def __init__(self, distribution, sourcepackagename):
         self.distribution = distribution
@@ -607,3 +610,4 @@
     bug_count = Int()
     po_message_count = Int()
     is_upstream_link_allowed = Bool()
+    enable_bugfiling_duplicate_search = Bool()

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2010-11-27 05:40:38 +0000
+++ lib/lp/registry/model/product.py	2010-11-30 15:18:35 +0000
@@ -453,6 +453,7 @@
         default=None)
     bug_reporting_guidelines = StringCol(default=None)
     bug_reported_acknowledgement = StringCol(default=None)
+    enable_bugfiling_duplicate_search = BoolCol(notNull=True, default=True)
     _cached_licenses = None
 
     def _validate_active(self, attr, value):

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py	2010-11-27 05:40:38 +0000
+++ lib/lp/registry/model/productseries.py	2010-11-30 15:18:35 +0000
@@ -270,6 +270,11 @@
         return self.product.bug_reported_acknowledgement
 
     @property
+    def enable_bugfiling_duplicate_search(self):
+        """See `IBugTarget`."""
+        return self.product.enable_bugfiling_duplicate_search
+
+    @property
     def sourcepackages(self):
         """See IProductSeries"""
         from lp.registry.model.sourcepackage import SourcePackage

=== modified file 'lib/lp/registry/model/sourcepackage.py'
--- lib/lp/registry/model/sourcepackage.py	2010-11-15 16:25:05 +0000
+++ lib/lp/registry/model/sourcepackage.py	2010-11-30 15:18:35 +0000
@@ -476,6 +476,12 @@
         """See `IBugTarget`."""
         return self.distribution.bug_reported_acknowledgement
 
+    @property
+    def enable_bugfiling_duplicate_search(self):
+        """See `IBugTarget`."""
+        return (
+            self.distribution_sourcepackage.enable_bugfiling_duplicate_search)
+
     def _customizeSearchParams(self, search_params):
         """Customize `search_params` for this source package."""
         search_params.setSourcePackage(self)