← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stevenk/launchpad/death-to-private_bugs into lp:launchpad

 

Steve Kowalik has proposed merging lp:~stevenk/launchpad/death-to-private_bugs into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stevenk/launchpad/death-to-private_bugs/+merge/128398

Now that all projects have moved to sharing, we can destroy the legacy code. First on the chopping block is IProduct.private_bugs. We can't delete the attribute itself, since it's exported over the API, but IProduct.setPrivateBugs() and friends can take the bullet instead. I have also deleted every test that mentioned private_bugs and then actually went on to use the attribute (since some tests will mention private_bugs and then just play with private bugs).

The actual database column Product.private_bugs will be dropped in a later branch, and once this one is deployed.
-- 
https://code.launchpad.net/~stevenk/launchpad/death-to-private_bugs/+merge/128398
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stevenk/launchpad/death-to-private_bugs into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py	2012-10-03 18:06:22 +0000
+++ lib/lp/bugs/browser/bugtarget.py	2012-10-07 23:54:23 +0000
@@ -119,10 +119,7 @@
 from lp.bugs.publisher import BugsLayer
 from lp.bugs.utilities.filebugdataparser import FileBugData
 from lp.hardwaredb.interfaces.hwdb import IHWSubmissionSet
-from lp.registry.browser.product import (
-    ProductConfigureBase,
-    ProductPrivateBugsMixin,
-    )
+from lp.registry.browser.product import ProductConfigureBase
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distributionsourcepackage import (
     IDistributionSourcePackage,
@@ -158,8 +155,6 @@
 
     bug_supervisor = copy_field(
         IHasBugSupervisor['bug_supervisor'], readonly=False)
-    private_bugs = copy_field(
-        IProduct['private_bugs'], readonly=False)
     official_malone = copy_field(ILaunchpadUsage['official_malone'])
     enable_bug_expiration = copy_field(
         ILaunchpadUsage['enable_bug_expiration'])
@@ -180,8 +175,7 @@
     return product
 
 
-class ProductConfigureBugTrackerView(ProductPrivateBugsMixin,
-                                     ProductConfigureBase):
+class ProductConfigureBugTrackerView(ProductConfigureBase):
     """View class to configure the bug tracker for a project."""
 
     label = "Configure bug tracker"
@@ -202,7 +196,6 @@
             "bug_reporting_guidelines",
             "bug_reported_acknowledgement",
             "enable_bugfiling_duplicate_search",
-            "private_bugs"
             ]
         if check_permission("launchpad.Edit", self.context):
             field_names.append("bug_supervisor")

=== modified file 'lib/lp/bugs/browser/tests/test_bugs.py'
--- lib/lp/bugs/browser/tests/test_bugs.py	2012-10-04 23:06:58 +0000
+++ lib/lp/bugs/browser/tests/test_bugs.py	2012-10-07 23:54:23 +0000
@@ -141,26 +141,6 @@
         related_bug = self.factory.makeBug()
         self._assert_getBugData(related_bug)
 
-    def test_createBug_default_private_bugs_true(self):
-        # createBug() does not adapt the default kwargs when they are none.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(True, project.owner)
-            bug = self.application.createBug(
-                project.owner, 'title', 'description', project)
-            self.assertEqual(InformationType.USERDATA, bug.information_type)
-
-    def test_createBug_public_bug_private_bugs_true(self):
-        # createBug() adapts a kwarg to InformationType if one is is not None.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(True, project.owner)
-            bug = self.application.createBug(
-                project.owner, 'title', 'description', project, private=False)
-            self.assertEqual(InformationType.PUBLIC, bug.information_type)
-
     def test_createBug_default_sharing_policy_proprietary(self):
         # createBug() does not adapt the default kwargs when they are none.
         project = self.factory.makeProduct(
@@ -183,16 +163,6 @@
             project.owner, 'title', 'description', project, private=False)
         self.assertEqual(InformationType.PUBLIC, bug.information_type)
 
-    def test_createBug_default_private_bugs_false(self):
-        # createBug() does not adapt the default kwargs when they are none.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(False, project.owner)
-            bug = self.application.createBug(
-                project.owner, 'title', 'description', project)
-            self.assertEqual(InformationType.PUBLIC, bug.information_type)
-
     def test_createBug_proprietary_project(self):
         # crateBug() make proprietary bugs for proprietary projects.
         project = self.factory.makeProduct(
@@ -203,13 +173,3 @@
             bug = self.application.createBug(
                 project.owner, 'title', 'description', project)
             self.assertEqual(InformationType.PROPRIETARY, bug.information_type)
-
-    def test_createBug_private_bug_private_bugs_false(self):
-        # createBug() adapts a kwarg to InformationType if one is is not None.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(False, project.owner)
-            bug = self.application.createBug(
-                project.owner, 'title', 'description', project, private=True)
-            self.assertEqual(InformationType.USERDATA, bug.information_type)

=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_configure.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_configure.py	2012-08-21 04:04:47 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_configure.py	2012-10-07 23:54:23 +0000
@@ -38,7 +38,6 @@
             'field.bug_reporting_guidelines': 'guidelines',
             'field.bug_reported_acknowledgement': 'acknowledgement message',
             'field.enable_bugfiling_duplicate_search': False,
-            'field.private_bugs': 'off',
             'field.actions.change': 'Change',
             }
 
@@ -50,8 +49,7 @@
         fields = [
             'bugtracker', 'enable_bug_expiration', 'remote_product',
             'bug_reporting_guidelines', 'bug_reported_acknowledgement',
-            'enable_bugfiling_duplicate_search', 'private_bugs',
-            'bug_supervisor']
+            'enable_bugfiling_duplicate_search', 'bug_supervisor']
         self.assertEqual(fields, view.field_names)
         self.assertEqual('http://launchpad.dev/boing', view.next_url)
         self.assertEqual('http://launchpad.dev/boing', view.cancel_url)
@@ -65,7 +63,7 @@
         fields = [
             'bugtracker', 'enable_bug_expiration', 'remote_product',
             'bug_reporting_guidelines', 'bug_reported_acknowledgement',
-            'enable_bugfiling_duplicate_search', 'private_bugs']
+            'enable_bugfiling_duplicate_search']
         self.assertEqual(fields, view.field_names)
         self.assertEqual('http://launchpad.dev/boing', view.next_url)
         self.assertEqual('http://launchpad.dev/boing', view.cancel_url)
@@ -160,62 +158,3 @@
         self.assertEqual([], view.errors)
         self.assertEqual(
             'new guidelines', self.product.bug_reporting_guidelines)
-
-    def test_commercial_subscriber_can_turn_on_private_bugs(self):
-        # Verify commercial subscribers can set private_bugs to on.
-        form = self._makeForm()
-        self.factory.makeCommercialSubscription(self.product)
-        form['field.private_bugs'] = 'on'
-        login_person(self.bug_supervisor)
-        view = create_initialized_view(
-            self.product, name='+configure-bugtracker', form=form)
-        self.assertEqual([], view.errors)
-        self.assertTrue(self.product.private_bugs)
-
-    def test_expired_commercial_subscriber_cannot_turn_on_private_bugs(self):
-        # Verify expired commercial subscribers cannot set private_bugs to on.
-        form = self._makeForm()
-        self.factory.makeCommercialSubscription(self.product, expired=True)
-        form['field.private_bugs'] = 'on'
-        login_person(self.bug_supervisor)
-        view = create_initialized_view(
-            self.product, name='+configure-bugtracker', form=form)
-        self.assertEqual(
-            [u'A valid commercial subscription is required to turn on '
-             u'default private bugs.'],
-            view.errors)
-
-    def test_unauthorised_cannot_turn_on_private_bugs(self):
-        # Verify unauthorised users cannot set private_bugs to on.
-        form = self._makeForm()
-        form['field.private_bugs'] = 'on'
-        view = create_initialized_view(
-            self.product, name='+configure-bugtracker', form=form)
-        self.assertEqual(
-            [u'A valid commercial subscription is required to turn on '
-             u'default private bugs.'],
-            view.errors)
-
-    def test_unauthorised_cannot_turn_off_private_bugs(self):
-        # Verify unauthorised user cannot set private_bugs off.
-        registry_expert = self.factory.makeRegistryExpert()
-        self.product.setPrivateBugs(True, registry_expert)
-        anyperson = self.factory.makePerson()
-        login_person(anyperson)
-        form = self._makeForm()
-        view = create_initialized_view(
-            self.product, name='+configure-bugtracker', form=form)
-        self.assertEqual(
-            [u'Only bug supervisors can turn off default private bugs.'],
-            view.errors)
-
-    def test_bug_supervisor_can_turn_off_private_bugs(self):
-        # Verify the bug supervisor can always set private_bugs off.
-        registry_expert = self.factory.makeRegistryExpert()
-        self.product.setPrivateBugs(True, registry_expert)
-        form = self._makeForm()
-        login_person(self.bug_supervisor)
-        view = create_initialized_view(
-            self.product, name='+configure-bugtracker', form=form)
-        self.assertEqual([], view.errors)
-        self.assertFalse(self.product.private_bugs)

=== modified file 'lib/lp/bugs/browser/tests/test_bugtarget_filebug.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_filebug.py	2012-10-04 15:12:52 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_filebug.py	2012-10-07 23:54:23 +0000
@@ -366,7 +366,7 @@
             }]
         self.assertEqual(expected_guidelines, view.bug_reporting_guidelines)
 
-    def filebug_via_view(self, private_bugs=False, information_type=None,
+    def filebug_via_view(self, information_type=None,
                          bug_sharing_policy=None, extra_data_token=None):
         form = {
             'field.title': 'A bug',
@@ -376,8 +376,6 @@
         if information_type:
             form['field.information_type'] = information_type
         product = self.factory.makeLegacyProduct(official_malone=True)
-        if private_bugs:
-            removeSecurityProxy(product).private_bugs = True
         if bug_sharing_policy:
             self.factory.makeCommercialSubscription(product=product)
             with person_logged_in(product.owner):
@@ -394,8 +392,7 @@
             return (getUtility(IBugSet).getByNameOrID(bug_number), view)
 
     def test_filebug_default_information_type(self):
-        # If we don't specify the bug's information_type, it is PUBLIC for
-        # products with private_bugs=False.
+        # If we don't specify the bug's information_type, it is PUBLIC.
         bug, view = self.filebug_via_view()
         self.assertEqual(
             InformationType.PUBLIC, view.default_information_type)
@@ -407,14 +404,6 @@
         self.assertEqual(
             InformationType.PRIVATESECURITY, bug.information_type)
 
-    def test_filebug_information_type_with_private_bugs(self):
-        # If we don't specify the bug's information_type, it is USERDATA for
-        # products with private_bugs=True.
-        bug, view = self.filebug_via_view(private_bugs=True)
-        self.assertEqual(
-            InformationType.USERDATA, view.default_information_type)
-        self.assertEqual(InformationType.USERDATA, bug.information_type)
-
     def test_filebug_information_type_with_bug_sharing_policy(self):
         # If we don't specify the bug's information_type, it follows the
         # target's getDefaultBugInformationType().
@@ -711,7 +700,7 @@
 
     layer = DatabaseFunctionalLayer
 
-    def filebug_via_view(self, private_bugs=False, bug_sharing_policy=None,
+    def filebug_via_view(self, bug_sharing_policy=None,
                          security_related=False):
         form = {
             'field.title': 'A bug',
@@ -720,8 +709,6 @@
             'field.actions.submit_bug': 'Submit Bug Request',
         }
         product = self.factory.makeLegacyProduct(official_malone=True)
-        if private_bugs:
-            removeSecurityProxy(product).private_bugs = True
         if bug_sharing_policy:
             self.factory.makeCommercialSubscription(product=product)
             with person_logged_in(product.owner):
@@ -735,31 +722,16 @@
             return getUtility(IBugSet).getByNameOrID(bug_number)
 
     def test_filebug_non_security_related(self):
-        # Non security related bugs are PUBLIC for products with
-        # private_bugs=False.
+        # Non security related bugs are PUBLIC.
         bug = self.filebug_via_view()
         self.assertEqual(InformationType.PUBLIC, bug.information_type)
 
     def test_filebug_security_related(self):
-        # Security related bugs are PRIVATESECURITY for products with
-        # private_bugs=False.
+        # Security related bugs are PRIVATESECURITY.
         bug = self.filebug_via_view(security_related=True)
         self.assertEqual(
             InformationType.PRIVATESECURITY, bug.information_type)
 
-    def test_filebug_security_related_with_private_bugs(self):
-        # Security related bugs are PRIVATESECURITY for products with
-        # private_bugs=True.
-        bug = self.filebug_via_view(private_bugs=True, security_related=True)
-        self.assertEqual(
-            InformationType.PRIVATESECURITY, bug.information_type)
-
-    def test_filebug_with_private_bugs(self):
-        # Non security related bugs are USERDATA for products with
-        # private_bugs=True.
-        bug = self.filebug_via_view(private_bugs=True)
-        self.assertEqual(InformationType.USERDATA, bug.information_type)
-
     def test_filebug_with_proprietary_sharing(self):
         # Non security related bugs are PROPRIETARY for products with a
         # proprietary sharing policy.
@@ -818,7 +790,7 @@
 
     layer = DatabaseFunctionalLayer
 
-    def _assert_cache_values(self, view, duplicate_search, private_bugs=False):
+    def _assert_cache_values(self, view, duplicate_search):
         cache = IJSONRequestCache(view.request).objects
         self.assertEqual(
             duplicate_search, cache['enable_bugfiling_duplicate_search'])
@@ -865,7 +837,6 @@
             bugtask_importance_data.append(new_item)
         self.assertEqual(
             bugtask_importance_data, cache['bugtask_importance_data'])
-        self.assertEqual(cache['bug_private_by_default'], private_bugs)
         bugtask_info_type_data = {}
         if not IProjectGroup.providedBy(view.context):
             for item in view.context.getAllowedBugInformationTypes():
@@ -884,14 +855,6 @@
         view = create_initialized_view(project, '+filebug', principal=user)
         self._assert_cache_values(view, True)
 
-    def test_product_private_bugs(self):
-        project = self.factory.makeLegacyProduct(
-            official_malone=True, private_bugs=True)
-        user = self.factory.makePerson()
-        login_person(user)
-        view = create_initialized_view(project, '+filebug', principal=user)
-        self._assert_cache_values(view, True, True)
-
     def test_product_no_duplicate_search(self):
         product = self.factory.makeProduct(official_malone=True)
         removeSecurityProxy(product).enable_bugfiling_duplicate_search = False

=== removed file 'lib/lp/bugs/doc/bug-private-by-default.txt'
--- lib/lp/bugs/doc/bug-private-by-default.txt	2012-09-17 16:13:40 +0000
+++ lib/lp/bugs/doc/bug-private-by-default.txt	1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
-Private by default bugs
-=======================
-
-A product with private bugs by default must always have a bug supervisor
-(this is enforced by a DB constraint).
-
-    >>> from lp.bugs.interfaces.bug import CreateBugParams
-    >>> from lp.app.enums import InformationType
-    >>> from lp.registry.interfaces.person import IPersonSet
-    >>> from lp.registry.interfaces.product import IProductSet
-    >>> from lp.testing.dbuser import switch_dbuser
-
-    >>> switch_dbuser('launchpad')
-    >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
-    >>> name16 = getUtility(IPersonSet).get(16)
-    >>> landscape = getUtility(IProductSet).getByName('landscape')
-    >>> landscape.private_bugs
-    True
-
-    >>> login('no-priv@xxxxxxxxxxxxx')
-
-    >>> bug_params = CreateBugParams(
-    ...     owner=no_priv, title='Some bug', comment='I like monkeys.')
-
-    >>> bug = landscape.createBug(bug_params)
-    >>> [landscape_task] = bug.bugtasks
-    >>> landscape_task.bug.private
-    True
-
-    >>> landscape_task.bug.security_related
-    False
-
-    >>> landscape.bug_supervisor.name
-    u'landscape-developers'
-
-    >>> landscape.owner.name
-    u'name12'
-
-    >>> sorted(sub.name for sub in landscape_task.bug.getDirectSubscribers())
-    [u'landscape-developers', u'no-priv']
-
-The bug supervisor is always subscribed, except in the case of a security
-related bug.
-
-    >>> security_bug_params = CreateBugParams(
-    ...     owner=no_priv, title='Security bug',
-    ...     comment='A monkey took my GPG keys.',
-    ...     information_type=InformationType.PRIVATESECURITY)
-    >>> security_bug = landscape.createBug(security_bug_params)
-    >>> [security_bug_task] = security_bug.bugtasks
-    >>> security_bug_task.bug.private
-    True

=== modified file 'lib/lp/bugs/model/bug.py'
--- lib/lp/bugs/model/bug.py	2012-10-04 14:22:59 +0000
+++ lib/lp/bugs/model/bug.py	2012-10-07 23:54:23 +0000
@@ -2629,7 +2629,7 @@
         # XXX: ElliotMurphy 2007-06-14: If we ever allow filing private
         # non-security bugs, this test might be simplified to checking
         # params.private.
-        if (IProduct.providedBy(params.target) and params.target.private_bugs
+        if (IProduct.providedBy(params.target)
             and params.target.bug_sharing_policy is None
             and params.information_type not in SECURITY_INFORMATION_TYPES):
             # Subscribe the bug supervisor to all bugs,

=== modified file 'lib/lp/bugs/model/tests/test_bug.py'
--- lib/lp/bugs/model/tests/test_bug.py	2012-10-03 16:11:18 +0000
+++ lib/lp/bugs/model/tests/test_bug.py	2012-10-07 23:54:23 +0000
@@ -586,7 +586,7 @@
             self.assertEqual(0, len(recorder.events))
 
 
-class TestBugPrivateAndSecurityRelatedUpdatesMixin:
+class TestBugPrivateAndSecurityRelatedUpdatesMixin(TestCaseWithFactory):
 
     layer = DatabaseFunctionalLayer
 
@@ -625,8 +625,6 @@
         bug_product = self.factory.makeProduct(
             owner=product_owner, bug_supervisor=bug_supervisor,
             driver=product_driver)
-        if self.private_project:
-            removeSecurityProxy(bug_product).private_bugs = True
         bug = self.factory.makeBug(owner=bug_owner, target=bug_product)
         with person_logged_in(bug_owner):
             if private_security_related:
@@ -939,24 +937,6 @@
                 InformationType.PUBLIC, bug.owner)
 
 
-class TestBugPrivateAndSecurityRelatedUpdatesPrivateProject(
-        TestBugPrivateAndSecurityRelatedUpdatesMixin, TestCaseWithFactory):
-
-    def setUp(self):
-        s = super(TestBugPrivateAndSecurityRelatedUpdatesPrivateProject, self)
-        s.setUp()
-        self.private_project = True
-
-
-class TestBugPrivateAndSecurityRelatedUpdatesPublicProject(
-        TestBugPrivateAndSecurityRelatedUpdatesMixin, TestCaseWithFactory):
-
-    def setUp(self):
-        s = super(TestBugPrivateAndSecurityRelatedUpdatesPublicProject, self)
-        s.setUp()
-        self.private_project = False
-
-
 class TestBugPrivateAndSecurityRelatedUpdatesSpecialCase(TestCaseWithFactory):
 
     layer = DatabaseFunctionalLayer

=== modified file 'lib/lp/bugs/scripts/bugimport.py'
--- lib/lp/bugs/scripts/bugimport.py	2012-06-29 08:40:05 +0000
+++ lib/lp/bugs/scripts/bugimport.py	2012-10-07 23:54:23 +0000
@@ -295,9 +295,6 @@
 
         private = get_value(bugnode, 'private') == 'True'
         security_related = get_value(bugnode, 'security_related') == 'True'
-        # If the product has private_bugs, we force private to True.
-        if self.product.private_bugs:
-            private = True
         information_type = convert_to_information_type(
             private, security_related)
 
@@ -323,11 +320,6 @@
             bug.linkMessage(msg)
             self.createAttachments(bug, msg, commentnode)
 
-        # Security bugs must be created private, so set it correctly.
-        if not self.product.private_bugs:
-            information_type = convert_to_information_type(
-                private, security_related)
-            bug.transitionToInformationType(information_type, owner)
         bug.name = get_value(bugnode, 'nickname')
         description = get_value(bugnode, 'description')
         if description:

=== modified file 'lib/lp/bugs/scripts/tests/test_bugimport.py'
--- lib/lp/bugs/scripts/tests/test_bugimport.py	2012-08-08 05:22:14 +0000
+++ lib/lp/bugs/scripts/tests/test_bugimport.py	2012-10-07 23:54:23 +0000
@@ -656,19 +656,6 @@
         self.assertEqual(bug101.private, False)
         self.assertEqual(bug101.security_related, True)
 
-    def test_public_bug_product_private_bugs(self):
-        # Test that if we import a public bug into a product with 
-        # private_bugs, the bug is private.
-        product = getUtility(IProductSet).getByName('netapplet')
-        removeSecurityProxy(product).private_bugs = True
-        importer = bugimport.BugImporter(
-            product, 'bugs.xml', 'bug-map.pickle', verify_users=True)
-        bugnode = ET.fromstring(public_security_bug)
-        bug101 = importer.importBug(bugnode)
-        self.assertIsNot(None, bug101)
-        self.assertTrue(bug101.private)
-        self.assertTrue(bug101.security_related)
-
 
 class BugImportCacheTestCase(TestCase):
     """Test of bug mapping cache load/save routines."""

=== modified file 'lib/lp/bugs/tests/test_bug.py'
--- lib/lp/bugs/tests/test_bug.py	2012-09-06 09:32:21 +0000
+++ lib/lp/bugs/tests/test_bug.py	2012-10-07 23:54:23 +0000
@@ -302,24 +302,12 @@
         bug = self.createBug(owner=person, target=target)
         self.assertContentEqual([person], bug.getDirectSubscribers())
 
-    def test_createBug_legacy_private_bugs_subscribers(self):
-        # If a project is using the legacy private_bugs setting, the bug
-        # supervisor is subscribed to new non-security bugs.
-        person = self.factory.makePerson()
-        target = self.factory.makeLegacyProduct(
-            private_bugs=True, bug_supervisor=self.factory.makePerson())
-        bug = self.createBug(owner=person, target=target)
-        with person_logged_in(person):
-            self.assertContentEqual(
-                [person, target.bug_supervisor], bug.getDirectSubscribers())
-
     def test_createBug_proprietary_subscribers(self):
         # If a project's sharing policy requests proprietary bugs, only
-        # the reporter is subscribed. Even if private_bugs is set.
+        # the reporter is subscribed.
         person = self.factory.makePerson()
         target = self.factory.makeProduct(
-            bug_sharing_policy=BugSharingPolicy.PROPRIETARY,
-            private_bugs=True)
+            bug_sharing_policy=BugSharingPolicy.PROPRIETARY)
         bug = self.createBug(owner=person, target=target)
         with person_logged_in(person):
             self.assertContentEqual(

=== modified file 'lib/lp/bugs/tests/test_bugs_webservice.py'
--- lib/lp/bugs/tests/test_bugs_webservice.py	2012-10-03 10:18:42 +0000
+++ lib/lp/bugs/tests/test_bugs_webservice.py	2012-10-07 23:54:23 +0000
@@ -400,37 +400,6 @@
 
     layer = DatabaseFunctionalLayer
 
-    def test_default_private_bugs_true(self):
-        # Verify the path through user submission, to MaloneApplication to
-        # BugSet, and back to the user creates a private bug according
-        # to the project's bugs are private by default rule.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        target_url = api_url(project)
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(True, project.owner)
-        webservice = launchpadlib_for('test', 'salgado')
-        bugs_collection = webservice.load('/bugs')
-        bug = bugs_collection.createBug(
-            target=target_url, title='title', description='desc')
-        self.assertEqual('Private', bug.information_type)
-
-    def test_explicit_private_private_bugs_true(self):
-        # Verify the path through user submission, to MaloneApplication to
-        # BugSet, and back to the user creates a private bug because the
-        # user commands it.
-        project = self.factory.makeLegacyProduct(
-            licenses=[License.OTHER_PROPRIETARY])
-        target_url = api_url(project)
-        with person_logged_in(project.owner):
-            project.setPrivateBugs(True, project.owner)
-        webservice = launchpadlib_for('test', 'salgado')
-        bugs_collection = webservice.load('/bugs')
-        bug = bugs_collection.createBug(
-            target=target_url, title='title', description='desc',
-            private=True)
-        self.assertEqual('Private', bug.information_type)
-
     def test_default_sharing_policy_proprietary(self):
         # Verify the path through user submission, to MaloneApplication to
         # BugSet, and back to the user creates a private bug according

=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2012-10-06 23:40:20 +0000
+++ lib/lp/registry/browser/product.py	2012-10-07 23:54:23 +0000
@@ -26,7 +26,6 @@
     'ProductOverviewMenu',
     'ProductPackagesView',
     'ProductPackagesPortletView',
-    'ProductPrivateBugsMixin',
     'ProductPurchaseSubscriptionView',
     'ProductRdfView',
     'ProductReviewLicenseView',
@@ -1377,37 +1376,6 @@
     usage_fieldname = 'answers_usage'
 
 
-class ProductPrivateBugsMixin():
-    """A mixin for setting the product private_bugs field."""
-    def setUpFields(self):
-        # private_bugs is readonly since we are using a mutator but we need
-        # to edit it on the form.
-        super(ProductPrivateBugsMixin, self).setUpFields()
-        self.form_fields = self.form_fields.omit('private_bugs')
-        private_bugs = copy_field(IProduct['private_bugs'], readonly=False)
-        self.form_fields += form.Fields(private_bugs, render_context=True)
-
-    def validate(self, data):
-        super(ProductPrivateBugsMixin, self).validate(data)
-        private_bugs = data.get('private_bugs')
-        if private_bugs is None:
-            return
-        try:
-            self.context.checkPrivateBugsTransitionAllowed(
-                private_bugs, self.user)
-        except Exception as e:
-            self.setFieldError('private_bugs', e.message)
-
-    def updateContextFromData(self, data, context=None, notify_modified=True):
-        # private_bugs uses a mutator to check permissions, so it needs to
-        # be handled separately.
-        if 'private_bugs' in data:
-            self.context.setPrivateBugs(data['private_bugs'], self.user)
-            del data['private_bugs']
-        parent = super(ProductPrivateBugsMixin, self)
-        return parent.updateContextFromData(data, context, notify_modified)
-
-
 class ProductEditView(ProductLicenseMixin, LaunchpadEditFormView):
     """View class that lets you edit a Product object."""
 
@@ -1479,17 +1447,10 @@
                         canonical_url(self.context, view_name='+packages')))
 
 
-class ProductAdminView(ProductPrivateBugsMixin, ProductEditView,
-                       ProductValidationMixin):
+class ProductAdminView(ProductEditView, ProductValidationMixin):
     """View for $project/+admin"""
     label = "Administer project details"
-    default_field_names = [
-        "name",
-        "owner",
-        "active",
-        "autoupdate",
-        "private_bugs",
-        ]
+    default_field_names = ["name", "owner", "active", "autoupdate"]
 
     @property
     def page_title(self):
@@ -1557,17 +1518,12 @@
         return canonical_url(self.context)
 
 
-class ProductReviewLicenseView(ReturnToReferrerMixin, ProductPrivateBugsMixin,
-                               ProductEditView, ProductValidationMixin):
+class ProductReviewLicenseView(ReturnToReferrerMixin, ProductEditView,
+                               ProductValidationMixin):
     """A view to review a project and change project privileges."""
     label = "Review project"
-    field_names = [
-        "project_reviewed",
-        "license_approved",
-        "active",
-        "private_bugs",
-        "reviewer_whiteboard",
-        ]
+    field_names = ["project_reviewed", "license_approved", "active",
+        "reviewer_whiteboard"]
 
     @property
     def page_title(self):

=== modified file 'lib/lp/registry/browser/tests/product-views.txt'
--- lib/lp/registry/browser/tests/product-views.txt	2012-08-08 07:22:51 +0000
+++ lib/lp/registry/browser/tests/product-views.txt	2012-10-07 23:54:23 +0000
@@ -153,8 +153,7 @@
 judge the licences.
 
     >>> view.field_names
-    ['project_reviewed', 'license_approved', 'active', 'private_bugs',
-     'reviewer_whiteboard']
+    ['project_reviewed', 'license_approved', 'active', 'reviewer_whiteboard']
 
 The reviewer cannot deactivate a project if it is linked
 to a source package.
@@ -193,15 +192,10 @@
     >>> print product.reviewer_whiteboard
     Looks bogus
 
-The reviewer can enable privileged features like private bugs. He can
-also reactivate the project at the same time.
-
-    >>> firefox.private_bugs
-    False
+The reviewer can reactivate the project.
 
     >>> form = {
     ...     'field.active': 'on',
-    ...     'field.private_bugs': 'on',
     ...     'field.reviewer_whiteboard': 'Reinstated old project',
     ...     'field.actions.change': 'Change',
     ...     }
@@ -212,8 +206,6 @@
     []
     >>> firefox.active
     True
-    >>> firefox.private_bugs
-    True
     >>> print firefox.reviewer_whiteboard
     Reinstated old project
 

=== modified file 'lib/lp/registry/interfaces/product.py'
--- lib/lp/registry/interfaces/product.py	2012-10-05 05:34:13 +0000
+++ lib/lp/registry/interfaces/product.py	2012-10-07 23:54:23 +0000
@@ -785,24 +785,6 @@
             description=_('Security contact (obsolete; always None)')),
             ('devel', dict(exported=False)), as_of='1.0')
 
-    def checkPrivateBugsTransitionAllowed(private_bugs, user):
-        """Can the private_bugs attribute be changed to the value by the user?
-
-        Generally, the permission is restricted to ~registry or ~admin or
-        bug supervisors.
-        In addition, a valid commercial subscription is required to turn on
-        private bugs when being done by a bug supervisor. However, no
-        commercial subscription is required to turn off private bugs.
-        """
-
-    @mutator_for(private_bugs)
-    @call_with(user=REQUEST_USER)
-    @operation_parameters(private_bugs=copy_field(private_bugs))
-    @export_write_operation()
-    @operation_for_version("devel")
-    def setPrivateBugs(private_bugs, user):
-        """Mutator for private_bugs that checks entitlement."""
-
     def getAllowedBugInformationTypes():
         """Get the information types that a bug in this project can have.
 

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2012-10-06 23:40:20 +0000
+++ lib/lp/registry/model/product.py	2012-10-07 23:54:23 +0000
@@ -52,7 +52,6 @@
     implements,
     providedBy,
     )
-from zope.security.interfaces import Unauthorized
 from zope.security.proxy import removeSecurityProxy
 
 from lp.answers.enums import QUESTION_STATUS_DEFAULT_SEARCH
@@ -531,8 +530,7 @@
         notNull=True, default=False)
     project_reviewed = BoolCol(dbName='reviewed', notNull=True, default=False)
     reviewer_whiteboard = StringCol(notNull=False, default=None)
-    private_bugs = BoolCol(
-        dbName='private_bugs', notNull=True, default=False)
+    private_bugs = False
     bug_sharing_policy = EnumCol(
         enum=BugSharingPolicy, notNull=False, default=None)
     branch_sharing_policy = EnumCol(
@@ -593,40 +591,6 @@
                                notNull=True, default=False,
                                storm_validator=_validate_license_approved)
 
-    def checkPrivateBugsTransitionAllowed(self, private_bugs, user):
-        """See `IProductPublic`."""
-        from lp.security import (
-            BugTargetOwnerOrBugSupervisorOrAdmins,
-            ModerateByRegistryExpertsOrAdmins,
-            )
-        if user is not None:
-            person_roles = IPersonRoles(user)
-            moderator_check = ModerateByRegistryExpertsOrAdmins(self)
-            moderator = moderator_check.checkAuthenticated(person_roles)
-            if moderator:
-                return True
-
-            bug_supervisor_check = BugTargetOwnerOrBugSupervisorOrAdmins(self)
-            bug_supervisor = (
-                bug_supervisor_check.checkAuthenticated(person_roles))
-            if (bug_supervisor and
-                    (not private_bugs
-                     or self.has_current_commercial_subscription)):
-                return
-        if private_bugs:
-            raise CommercialSubscribersOnly(
-                'A valid commercial subscription is required to turn on '
-                'default private bugs.')
-        raise Unauthorized(
-            'Only bug supervisors can turn off default private bugs.')
-
-    def setPrivateBugs(self, private_bugs, user):
-        """ See `IProductEditRestricted`."""
-        if self.private_bugs == private_bugs:
-            return
-        self.checkPrivateBugsTransitionAllowed(private_bugs, user)
-        self.private_bugs = private_bugs
-
     def _prepare_to_set_sharing_policy(self, var, enum, kind, allowed_types):
         if (var not in [enum.PUBLIC, enum.FORBIDDEN] and
             not self.has_current_commercial_subscription):
@@ -671,8 +635,6 @@
         """See `IDistribution.`"""
         if self.bug_sharing_policy is not None:
             return BUG_POLICY_DEFAULT_TYPES[self.bug_sharing_policy]
-        elif self.private_bugs:
-            return InformationType.USERDATA
         else:
             return InformationType.PUBLIC
 

=== modified file 'lib/lp/registry/model/productjob.py'
--- lib/lp/registry/model/productjob.py	2012-09-19 06:39:47 +0000
+++ lib/lp/registry/model/productjob.py	2012-10-07 23:54:23 +0000
@@ -473,7 +473,6 @@
             self.product.active = False
         else:
             naked_product = removeSecurityProxy(self.product)
-            naked_product.private_bugs = False
             naked_product.setBranchSharingPolicy(BranchSharingPolicy.FORBIDDEN)
             naked_product.setBugSharingPolicy(BugSharingPolicy.FORBIDDEN)
             for series in self.product.series:

=== modified file 'lib/lp/registry/tests/test_product.py'
--- lib/lp/registry/tests/test_product.py	2012-10-04 17:37:33 +0000
+++ lib/lp/registry/tests/test_product.py	2012-10-07 23:54:23 +0000
@@ -279,86 +279,6 @@
             closed_team = self.factory.makeTeam(membership_policy=policy)
             self.factory.makeProduct(owner=closed_team)
 
-    def test_private_bugs_on_not_allowed_for_anonymous(self):
-        # Anonymous cannot turn on private bugs.
-        product = self.factory.makeProduct()
-        self.assertRaises(
-            CommercialSubscribersOnly,
-            product.checkPrivateBugsTransitionAllowed, True, None)
-
-    def test_private_bugs_off_not_allowed_for_anonymous(self):
-        # Anonymous cannot turn private bugs off.
-        product = self.factory.makeProduct()
-        self.assertRaises(
-            Unauthorized,
-            product.checkPrivateBugsTransitionAllowed, False, None)
-
-    def test_private_bugs_on_not_allowed_for_unauthorised(self):
-        # Unauthorised users cannot turn on private bugs.
-        product = self.factory.makeProduct()
-        someone = self.factory.makePerson()
-        self.assertRaises(
-            CommercialSubscribersOnly,
-            product.checkPrivateBugsTransitionAllowed, True, someone)
-
-    def test_private_bugs_off_not_allowed_for_unauthorised(self):
-        # Unauthorised users cannot turn private bugs off.
-        product = self.factory.makeProduct()
-        someone = self.factory.makePerson()
-        self.assertRaises(
-            Unauthorized,
-            product.checkPrivateBugsTransitionAllowed, False, someone)
-
-    def test_private_bugs_on_allowed_for_moderators(self):
-        # Moderators can turn on private bugs.
-        product = self.factory.makeProduct()
-        registry_expert = self.factory.makeRegistryExpert()
-        product.checkPrivateBugsTransitionAllowed(True, registry_expert)
-
-    def test_private_bugs_off_allowed_for_moderators(self):
-        # Moderators can turn private bugs off.
-        product = self.factory.makeProduct()
-        registry_expert = self.factory.makeRegistryExpert()
-        product.checkPrivateBugsTransitionAllowed(False, registry_expert)
-
-    def test_private_bugs_on_allowed_for_commercial_subscribers(self):
-        # Commercial subscribers can turn on private bugs.
-        bug_supervisor = self.factory.makePerson()
-        product = self.factory.makeProduct(bug_supervisor=bug_supervisor)
-        self.factory.makeCommercialSubscription(product)
-        product.checkPrivateBugsTransitionAllowed(True, bug_supervisor)
-
-    def test_private_bugs_on_not_allowed_for_expired_subscribers(self):
-        # Expired Commercial subscribers cannot turn on private bugs.
-        bug_supervisor = self.factory.makePerson()
-        product = self.factory.makeProduct(bug_supervisor=bug_supervisor)
-        self.factory.makeCommercialSubscription(product, expired=True)
-        self.assertRaises(
-            CommercialSubscribersOnly,
-            product.setPrivateBugs, True, bug_supervisor)
-
-    def test_private_bugs_off_allowed_for_bug_supervisors(self):
-        # Bug supervisors can turn private bugs off.
-        bug_supervisor = self.factory.makePerson()
-        product = self.factory.makeProduct(bug_supervisor=bug_supervisor)
-        product.checkPrivateBugsTransitionAllowed(False, bug_supervisor)
-
-    def test_unauthorised_set_private_bugs_raises(self):
-        # Test Product.setPrivateBugs raises an error if user unauthorised.
-        product = self.factory.makeProduct()
-        someone = self.factory.makePerson()
-        self.assertRaises(
-            CommercialSubscribersOnly,
-            product.setPrivateBugs, True, someone)
-
-    def test_set_private_bugs(self):
-        # Test Product.setPrivateBugs()
-        bug_supervisor = self.factory.makePerson()
-        product = self.factory.makeProduct(bug_supervisor=bug_supervisor)
-        self.factory.makeCommercialSubscription(product)
-        product.setPrivateBugs(True, bug_supervisor)
-        self.assertTrue(product.private_bugs)
-
     def test_product_creation_grants_maintainer_access(self):
         # Creating a new product creates an access grant for the maintainer
         # for all default policies.
@@ -653,9 +573,9 @@
             'official_codehosting', 'official_malone', 'owner',
             'parent_subscription_target', 'packagedInDistros', 'packagings',
             'past_sprints', 'personHasDriverRights', 'pillar',
-            'primary_translatable', 'private_bugs',
-            'programminglang', 'project', 'qualifies_for_free_hosting',
-            'recipes', 'redeemSubscriptionVoucher', 'registrant', 'releases',
+            'primary_translatable', 'programminglang', 'project',
+            'qualifies_for_free_hosting', 'recipes',
+            'redeemSubscriptionVoucher', 'registrant', 'releases',
             'remote_product', 'removeCustomLanguageCode',
             'removeTeamFromBranchVisibilityPolicy', 'screenshotsurl',
             'searchFAQs', 'searchQuestions', 'searchTasks', 'security_contact',
@@ -887,8 +807,8 @@
 
     layer = DatabaseFunctionalLayer
 
-    def makeProductWithPolicy(self, bug_sharing_policy, private_bugs=False):
-        product = self.factory.makeProduct(private_bugs=private_bugs)
+    def makeProductWithPolicy(self, bug_sharing_policy):
+        product = self.factory.makeProduct()
         self.factory.makeCommercialSubscription(product=product)
         with person_logged_in(product.owner):
             product.setBugSharingPolicy(bug_sharing_policy)
@@ -903,24 +823,6 @@
         self.assertEqual(
             InformationType.PUBLIC, product.getDefaultBugInformationType())
 
-    def test_legacy_private_bugs(self):
-        # The deprecated private_bugs attribute overrides the default
-        # information type to USERDATA.
-        product = self.factory.makeLegacyProduct(private_bugs=True)
-        self.assertContentEqual(
-            FREE_INFORMATION_TYPES, product.getAllowedBugInformationTypes())
-        self.assertEqual(
-            InformationType.USERDATA, product.getDefaultBugInformationType())
-
-    def test_sharing_policy_overrides_private_bugs(self):
-        # bug_sharing_policy overrides private_bugs.
-        product = self.makeProductWithPolicy(
-            BugSharingPolicy.PUBLIC, private_bugs=True)
-        self.assertContentEqual(
-            FREE_INFORMATION_TYPES, product.getAllowedBugInformationTypes())
-        self.assertEqual(
-            InformationType.PUBLIC, product.getDefaultBugInformationType())
-
     def test_sharing_policy_public_or_proprietary(self):
         # bug_sharing_policy can enable Proprietary.
         product = self.makeProductWithPolicy(

=== modified file 'lib/lp/registry/tests/test_productjob.py'
--- lib/lp/registry/tests/test_productjob.py	2012-09-28 06:15:58 +0000
+++ lib/lp/registry/tests/test_productjob.py	2012-10-07 23:54:23 +0000
@@ -723,8 +723,7 @@
         job = CommercialExpiredJob.create(product, reviewer)
         job._deactivateCommercialFeatures()
         clear_property_cache(product)
-        self.assertIs(True, product.active)
-        self.assertIs(False, product.private_bugs)
+        self.assertTrue(product.active)
         self.assertEqual(
             BranchSharingPolicy.FORBIDDEN, product.branch_sharing_policy)
         self.assertEqual(

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2012-10-04 17:37:33 +0000
+++ lib/lp/testing/factory.py	2012-10-07 23:54:23 +0000
@@ -963,10 +963,9 @@
         self, name=None, project=None, displayname=None,
         licenses=None, owner=None, registrant=None,
         title=None, summary=None, official_malone=None,
-        translations_usage=None, bug_supervisor=None, private_bugs=False,
-        driver=None, icon=None, bug_sharing_policy=None,
-        branch_sharing_policy=None, specification_sharing_policy=None,
-        information_type=None):
+        translations_usage=None, bug_supervisor=None, driver=None, icon=None,
+        bug_sharing_policy=None, branch_sharing_policy=None,
+        specification_sharing_policy=None, information_type=None):
         """Create and return a new, arbitrary Product."""
         if owner is None:
             owner = self.makePerson()
@@ -1009,8 +1008,6 @@
             naked_product.bug_supervisor = bug_supervisor
         if driver is not None:
             naked_product.driver = driver
-        if private_bugs:
-            naked_product.private_bugs = private_bugs
         if ((branch_sharing_policy and
             branch_sharing_policy != BranchSharingPolicy.PUBLIC) or
             (bug_sharing_policy and


Follow ups