← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~abentley/launchpad/proprietary-project-policies into lp:launchpad

 

Aaron Bentley has proposed merging lp:~abentley/launchpad/proprietary-project-policies into lp:launchpad.

Commit message:
Fix policies for proprietary products.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1076412 in Launchpad itself: "Proprietary projects should only allow proprietary policies on its artifacts"
  https://bugs.launchpad.net/launchpad/+bug/1076412

For more details, see:
https://code.launchpad.net/~abentley/launchpad/proprietary-project-policies/+merge/134511

= Summary =
Fix bug #1076412: Proprietary projects should only allow proprietary policies
on its artifacts

== Proposed fix ==
Changing a project to Proprietary or Embargoed changes its sharing policies, and warns of any public artifacts.  Sharing policies of Proprietary projects cannot be changed such that they would permit public types.

== Pre-implementation notes ==
Discussed with Deryck

== LOC Rationale ==
Part of Private Projects

== Implementation details ==
At the model level, changing Product information type from Public now sets the sharing policies as through the Product were being created.  Introduced bug_policy_default, branch_policy_default, specification_policy_default to support this, and updated createProduct to use them.

At the view level, changing Product information type from Public now emits a warning if there are any public artifacts.

If the Product is proprietary, attempting to set a sharing policy that would permit public information types raises an exception.

Updated failing tests, fixed lint.  Fixed LaunchpadObjectFactory.makeProduct to use licenses to provoke commercial subscriptions, to avoid multiple subscription creations.

== Tests ==
bin/test -v -t test_warning_on_public_artifacts -t  test_getPublicWarning -t test_change_info_type_proprietary_sets_policies -t test_change_info_type_embargoed_sets_policies -t test_proprietary_to_public_leaves_policies -t test_proprietary_products_forbid_public_policies




== Demo and Q/A ==
Create a product.  Create a bug, branch and blueprint on the product.  Change its information type to Proprietary.  It should warn you about the public artifacts, and it should set the policies to Proprietary (only).  Set the artifacts to proprietary.  Set the project to public.  It should not update the policies or warn you.  Set the project back to proprietary.  It should not warn you.


= Launchpad lint =

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/registry/errors.py
  lib/lp/registry/browser/product.py
  lib/lp/testing/factory.py
  lib/lp/registry/browser/tests/test_product.py
  lib/lp/registry/tests/test_milestone.py
  lib/lp/registry/model/product.py
  lib/lp/registry/tests/test_product.py
-- 
https://code.launchpad.net/~abentley/launchpad/proprietary-project-policies/+merge/134511
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~abentley/launchpad/proprietary-project-policies into lp:launchpad.
=== modified file 'lib/lp/registry/browser/product.py'
--- lib/lp/registry/browser/product.py	2012-11-12 22:27:55 +0000
+++ lib/lp/registry/browser/product.py	2012-11-15 16:44:23 +0000
@@ -105,6 +105,7 @@
     InformationType,
     PROPRIETARY_INFORMATION_TYPES,
     PUBLIC_PROPRIETARY_INFORMATION_TYPES,
+    PUBLIC_INFORMATION_TYPES,
     ServiceUsage,
     )
 from lp.app.errors import NotFoundError
@@ -128,6 +129,9 @@
 from lp.blueprints.browser.specificationtarget import (
     HasSpecificationsMenuMixin,
     )
+from lp.blueprints.enums import (
+    SpecificationFilter,
+    )
 from lp.bugs.browser.bugtask import (
     BugTargetTraversalMixin,
     get_buglisting_search_filter_url,
@@ -1446,10 +1450,47 @@
 
     @action("Change", name='change')
     def change_action(self, action, data):
+        old_info_type = self.context.information_type
         try:
             self.updateContextFromData(data)
         except CannotChangeInformationType as e:
             self.setFieldError('information_type', str(e))
+        warning = self.getPublicWarning(old_info_type)
+        if warning is not None:
+            self.request.response.addWarningNotification(warning)
+
+    def getPublicWarning(self, old_info_type):
+        """Get warning if public artifacts might expose the product.
+
+        :param old_info_type: The former information type of the product.
+        """
+        if (old_info_type != InformationType.PUBLIC or
+            self.context.information_type == InformationType.PUBLIC):
+            return None
+        public_bugs = self.context.searchTasks(None,
+            information_type=PUBLIC_INFORMATION_TYPES,
+            omit_duplicates=False, omit_targeted=False)
+        public_artifacts = []
+        if not public_bugs.is_empty():
+            public_artifacts.append('bugs')
+        # Default returns all public branches.
+        public_branches = self.context.getBranches()
+        if not public_branches.is_empty():
+            public_artifacts.append('branches')
+        # All specs located by an ALL search are public.
+        public_specs = self.context.specifications(
+            None, filter=[SpecificationFilter.ALL])
+        if not public_specs.is_empty():
+            public_artifacts.append('blueprints')
+        if len(public_artifacts) == 0:
+            return None
+        elif len(public_artifacts) < 3:
+            list_phrase = ' and '.join(public_artifacts)
+        else:
+            list_phrase = 'bugs, branches, and blueprints'
+        return ('Some %s are public.  This project will not be fully '
+                '%s until they have been changed.' %
+                (list_phrase, self.context.information_type.title))
 
 
 class ProductValidationMixin:

=== modified file 'lib/lp/registry/browser/tests/test_product.py'
--- lib/lp/registry/browser/tests/test_product.py	2012-11-12 22:27:55 +0000
+++ lib/lp/registry/browser/tests/test_product.py	2012-11-15 16:44:23 +0000
@@ -25,6 +25,7 @@
 from lp.app.enums import (
     InformationType,
     PROPRIETARY_INFORMATION_TYPES,
+    PUBLIC_PROPRIETARY_INFORMATION_TYPES,
     ServiceUsage,
     )
 from lp.registry.browser.product import (
@@ -552,6 +553,118 @@
             self.assertEqual(
                 InformationType.PUBLIC, updated_product.information_type)
 
+    def test_warning_on_public_artifacts(self):
+        # When changing to proprietary, any public artifacts will trigger a
+        # warning.
+        self.useFixture(FeatureFixture(
+            {u'disclosure.private_projects.enabled': u'on'}))
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(owner=owner)
+        bug = self.factory.makeBug(target=product)
+
+        def make_proprietary():
+            with person_logged_in(None):
+                browser = self.getViewBrowser(product, '+edit',
+                    user=product.owner)
+                info_type = browser.getControl(name='field.information_type')
+                info_type.value = ['PROPRIETARY']
+                browser.getControl('Change').click()
+            with person_logged_in(owner):
+                product.information_type = InformationType.PUBLIC
+            return browser
+        browser = make_proprietary()
+
+        def assertWarning(browser, text):
+            warning_tag = Tag('warning', 'div', text=text,
+                              attrs={'class': 'warning message'})
+            self.assertThat(browser.contents, HTMLContains(warning_tag))
+        assertWarning(
+            browser, 'Some bugs are public.  This project will not be fully '
+            'Proprietary until they have been changed.')
+        browser = make_proprietary()
+        with person_logged_in(bug.owner):
+            bug.transitionToInformationType(InformationType.PROPRIETARY,
+                                            bug.owner)
+        browser = make_proprietary()
+        self.assertThat(browser.contents, Not(HTMLContains(
+            Tag('warning', 'div', attrs={'class': 'warning message'}))))
+
+    def test_getPublicWarning_artifacts(self):
+        # The warning indicates what kinds of artifacts are public, in
+        # grammatical English.
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(owner=owner)
+        bug = self.factory.makeBug(target=product)
+        view = create_initialized_view(product, '+edit')
+        with person_logged_in(owner):
+            product.information_type = InformationType.PROPRIETARY
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some bugs are public.  This project will not be fully '
+            'Proprietary until they have been changed.', warning)
+        spec = self.factory.makeSpecification(product=product)
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some bugs and blueprints are public.  This project will not be '
+            'fully Proprietary until they have been changed.', warning)
+        branch = self.factory.makeBranch(product=product, owner=owner,
+                information_type=InformationType.PUBLIC)
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some bugs, branches, and blueprints are public.  This project '
+            'will not be fully Proprietary until they have been changed.',
+            warning)
+        with person_logged_in(owner):
+            bug.transitionToInformationType(
+                InformationType.PROPRIETARY, owner)
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some branches and blueprints are public.  This project '
+            'will not be fully Proprietary until they have been changed.',
+            warning)
+        with person_logged_in(owner):
+            branch.transitionToInformationType(
+                InformationType.PROPRIETARY, owner)
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some blueprints are public.  This project will not be fully '
+            'Proprietary until they have been changed.', warning)
+        with person_logged_in(owner):
+            spec.transitionToInformationType(
+                InformationType.PROPRIETARY, owner)
+        self.assertIs(None, view.getPublicWarning(InformationType.PUBLIC))
+
+    def test_getPublicWarning_embargoed(self):
+        # The message reflects an Embargoed product type.
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(owner=owner)
+        self.factory.makeBug(target=product)
+        with person_logged_in(owner):
+            product.information_type = InformationType.EMBARGOED
+            view = create_initialized_view(product, '+edit')
+        warning = view.getPublicWarning(InformationType.PUBLIC)
+        self.assertEqual(
+            'Some bugs are public.  This project will not be fully '
+            'Embargoed until they have been changed.', warning)
+
+    def test_getPublicWarning_transition(self):
+        # The warning is emitted only when transitioning from PUBLIC to a
+        # proprietary type.
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(owner=owner)
+        self.factory.makeBug(target=product)
+        view = create_initialized_view(product, '+edit')
+        for from_type in PUBLIC_PROPRIETARY_INFORMATION_TYPES:
+            for to_type in PUBLIC_PROPRIETARY_INFORMATION_TYPES:
+                with person_logged_in(owner):
+                    product.information_type = to_type
+                warning = view.getPublicWarning(from_type)
+                if (to_type in PROPRIETARY_INFORMATION_TYPES and
+                    from_type == InformationType.PUBLIC):
+                    self.assertIsNot(None, warning)
+                else:
+                    self.assertIs(None, warning)
+
 
 class ProductSetReviewLicensesViewTestCase(TestCaseWithFactory):
     """Tests the ProductSetReviewLicensesView."""

=== modified file 'lib/lp/registry/errors.py'
--- lib/lp/registry/errors.py	2012-10-22 02:30:44 +0000
+++ lib/lp/registry/errors.py	2012-11-15 16:44:23 +0000
@@ -24,6 +24,7 @@
     'InclusiveTeamLinkageError',
     'PPACreationError',
     'PrivatePersonLinkageError',
+    'ProprietaryProduct',
     'TeamMembershipTransitionError',
     'TeamMembershipPolicyError',
     'UserCannotChangeMembershipSilently',
@@ -87,6 +88,10 @@
     """
 
 
+class ProprietaryProduct(Exception):
+    """Cannot make the change because the project is proprietary."""
+
+
 class NoSuchSourcePackageName(NameLookupFailed):
     """Raised when we can't find a particular sourcepackagename."""
     _message_prefix = "No such source package"

=== modified file 'lib/lp/registry/model/product.py'
--- lib/lp/registry/model/product.py	2012-11-12 11:21:14 +0000
+++ lib/lp/registry/model/product.py	2012-11-15 16:44:23 +0000
@@ -123,6 +123,7 @@
     )
 from lp.code.enums import BranchType
 from lp.code.interfaces.branch import DEFAULT_BRANCH_STATUS_IN_LISTING
+from lp.code.model.branch import Branch
 from lp.code.model.branchnamespace import BRANCH_POLICY_ALLOWED_TYPES
 from lp.code.model.hasbranches import (
     HasBranchesMixin,
@@ -139,6 +140,7 @@
 from lp.registry.errors import (
     CannotChangeInformationType,
     CommercialSubscribersOnly,
+    ProprietaryProduct,
     VoucherAlreadyRedeemed,
     )
 from lp.registry.interfaces.accesspolicy import (
@@ -332,6 +334,27 @@
     def __init__(self, msg):
         super(UnDeactivateable, self).__init__(msg)
 
+bug_policy_default = {
+    InformationType.PUBLIC: BugSharingPolicy.PUBLIC,
+    InformationType.PROPRIETARY: BugSharingPolicy.PROPRIETARY,
+    InformationType.EMBARGOED: BugSharingPolicy.PROPRIETARY,
+}
+
+
+branch_policy_default = {
+    InformationType.PUBLIC: BranchSharingPolicy.PUBLIC,
+    InformationType.EMBARGOED: BranchSharingPolicy.EMBARGOED_OR_PROPRIETARY,
+    InformationType.PROPRIETARY: BranchSharingPolicy.PROPRIETARY,
+}
+
+
+specification_policy_default = {
+    InformationType.PUBLIC: SpecificationSharingPolicy.PUBLIC,
+    InformationType.EMBARGOED:
+        SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY,
+    InformationType.PROPRIETARY: SpecificationSharingPolicy.PROPRIETARY,
+}
+
 
 class Product(SQLBase, BugTargetBase, MakesAnnouncements,
               HasDriversMixin, HasSpecificationsMixin, HasSprintsMixin,
@@ -469,12 +492,19 @@
         return self._information_type or InformationType.PUBLIC
 
     def _set_information_type(self, value):
+        old_info_type = self._information_type
         self._information_type = value
         # Make sure that policies are updated to grant permission to the
         # maintainer as required for the Product.
         # However, only on edits. If this is a new Product it's handled
         # already.
         if not self._SO_creating:
+            if (old_info_type == InformationType.PUBLIC and
+                value != InformationType.PUBLIC):
+                self.setBranchSharingPolicy(branch_policy_default[value])
+                self.setBugSharingPolicy(bug_policy_default[value])
+                self.setSpecificationSharingPolicy(
+                    specification_policy_default[value])
             self._ensurePolicies([value])
 
     information_type = property(_get_information_type, _set_information_type)
@@ -623,6 +653,10 @@
             raise CommercialSubscribersOnly(
                 "A current commercial subscription is required to use "
                 "proprietary %s." % kind)
+        if self.information_type != InformationType.PUBLIC:
+            if InformationType.PUBLIC in allowed_types[var]:
+                raise ProprietaryProduct(
+                    "The project is %s." % self.information_type.title)
         required_policies = set(allowed_types[var]).intersection(
             set(PRIVATE_INFORMATION_TYPES))
         self._ensurePolicies(required_policies)
@@ -1482,7 +1516,6 @@
     @property
     def recipes(self):
         """See `IHasRecipes`."""
-        from lp.code.model.branch import Branch
         store = Store.of(self)
         return store.find(
             SourcePackageRecipe,
@@ -1819,28 +1852,14 @@
             bug_supervisor=bug_supervisor, driver=driver,
             information_type=information_type)
 
-        # Set up the sharing policies and product licence.
-        bug_sharing_policy_to_use = BugSharingPolicy.PUBLIC
-        branch_sharing_policy_to_use = BranchSharingPolicy.PUBLIC
-        specification_sharing_policy_to_use = (
-            SpecificationSharingPolicy.PUBLIC)
+        # Set up the product licence.
         if len(licenses) > 0:
             product._setLicenses(licenses, reset_project_reviewed=False)
-        if information_type == InformationType.PROPRIETARY:
-            bug_sharing_policy_to_use = BugSharingPolicy.PROPRIETARY
-            branch_sharing_policy_to_use = BranchSharingPolicy.PROPRIETARY
-            specification_sharing_policy_to_use = (
-                SpecificationSharingPolicy.PROPRIETARY)
-        if information_type == InformationType.EMBARGOED:
-            bug_sharing_policy_to_use = BugSharingPolicy.PROPRIETARY
-            branch_sharing_policy_to_use = (
-                BranchSharingPolicy.EMBARGOED_OR_PROPRIETARY)
-            specification_sharing_policy_to_use = (
-                SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY)
-        product.setBugSharingPolicy(bug_sharing_policy_to_use)
-        product.setBranchSharingPolicy(branch_sharing_policy_to_use)
+        product.setBugSharingPolicy(bug_policy_default[information_type])
+        product.setBranchSharingPolicy(
+            branch_policy_default[information_type])
         product.setSpecificationSharingPolicy(
-            specification_sharing_policy_to_use)
+            specification_policy_default[information_type])
 
         # Create a default trunk series and set it as the development focus
         trunk = product.newSeries(

=== modified file 'lib/lp/registry/tests/test_milestone.py'
--- lib/lp/registry/tests/test_milestone.py	2012-10-26 08:59:24 +0000
+++ lib/lp/registry/tests/test_milestone.py	2012-11-15 16:44:23 +0000
@@ -483,7 +483,7 @@
         public_milestone = self.factory.makeMilestone(product=public_product)
         product = self.factory.makeProduct(
             owner=owner, information_type=InformationType.PROPRIETARY,
-            project=projectgroup, bug_sharing_policy=BugSharingPolicy.PUBLIC)
+            project=projectgroup)
         target_milestone = self.factory.makeMilestone(
             product=product, name=public_milestone.name)
         milestone = projectgroup.getMilestone(name=public_milestone.name)
@@ -530,8 +530,12 @@
         # way to get a proprietary milestone.
         milestone, target_milestone, owner = self.makeMixedMilestone()
         with person_logged_in(owner):
+            product = target_milestone.product
+            product.information_type = InformationType.PUBLIC
+            product.setBugSharingPolicy(BugSharingPolicy.PUBLIC)
             bugtask = self.factory.makeBugTask(
                 target=target_milestone.product)
+            product.information_type = InformationType.PROPRIETARY
         with person_logged_in(bugtask.owner):
             bugtask.transitionToMilestone(target_milestone, owner)
         self.assertContentEqual([], milestone.bugtasks(None))

=== modified file 'lib/lp/registry/tests/test_product.py'
--- lib/lp/registry/tests/test_product.py	2012-11-13 17:03:49 +0000
+++ lib/lp/registry/tests/test_product.py	2012-11-15 16:44:23 +0000
@@ -49,9 +49,13 @@
     SpecificationPriority,
     SpecificationSort,
     )
-
+from lp.blueprints.model.specification import (
+    SPECIFICATION_POLICY_ALLOWED_TYPES,
+    )
 from lp.bugs.interfaces.bugsummary import IBugSummaryDimension
+from lp.bugs.interfaces.bugtarget import BUG_POLICY_ALLOWED_TYPES
 from lp.bugs.interfaces.bugsupervisor import IHasBugSupervisor
+from lp.code.model.branchnamespace import BRANCH_POLICY_ALLOWED_TYPES
 from lp.registry.enums import (
     BranchSharingPolicy,
     BugSharingPolicy,
@@ -64,6 +68,7 @@
     CannotChangeInformationType,
     CommercialSubscribersOnly,
     InclusiveTeamLinkageError,
+    ProprietaryProduct,
     )
 from lp.registry.interfaces.accesspolicy import (
     IAccessPolicyGrantSource,
@@ -386,6 +391,53 @@
         expected = [InformationType.USERDATA, InformationType.PRIVATESECURITY]
         self.assertContentEqual(expected, [policy.type for policy in aps])
 
+    def test_change_info_type_proprietary_sets_policies(self):
+        # Changing information type from public to proprietary sets the
+        # appropriate policies
+        product = self.factory.makeProduct()
+        with person_logged_in(product.owner):
+            product.information_type = InformationType.PROPRIETARY
+            self.assertEqual(
+                BranchSharingPolicy.PROPRIETARY, product.branch_sharing_policy)
+            self.assertEqual(
+                BugSharingPolicy.PROPRIETARY, product.bug_sharing_policy)
+            self.assertEqual(
+                SpecificationSharingPolicy.PROPRIETARY,
+                product.specification_sharing_policy)
+
+    def test_change_info_type_embargoed_sets_policies(self):
+        # Changing information type from public to embargoed sets the
+        # appropriate policies
+        product = self.factory.makeProduct()
+        with person_logged_in(product.owner):
+            product.information_type = InformationType.EMBARGOED
+            self.assertEqual(
+                BranchSharingPolicy.EMBARGOED_OR_PROPRIETARY,
+                product.branch_sharing_policy)
+            self.assertEqual(
+                BugSharingPolicy.PROPRIETARY, product.bug_sharing_policy)
+            self.assertEqual(
+                SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY,
+                product.specification_sharing_policy)
+
+    def test_proprietary_to_public_leaves_policies(self):
+        # Changing information type from public leaves sharing policies
+        # unchanged.
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(
+            information_type=InformationType.PROPRIETARY, owner=owner)
+        with person_logged_in(owner):
+            product.information_type = InformationType.PUBLIC
+            # Setting information type to the current type should be a no-op
+            product.information_type = InformationType.PUBLIC
+        self.assertEqual(
+            BranchSharingPolicy.PROPRIETARY, product.branch_sharing_policy)
+        self.assertEqual(
+            BugSharingPolicy.PROPRIETARY, product.bug_sharing_policy)
+        self.assertEqual(
+            SpecificationSharingPolicy.PROPRIETARY,
+            product.specification_sharing_policy)
+
     def createProduct(self, information_type=None, license=None):
         # convenience method for testing IProductSet.createProduct rather than
         # self.factory.makeProduct
@@ -965,17 +1017,15 @@
     def test_information_type_prevents_pruning(self):
         # Access policies for Product.information_type are not pruned.
         owner = self.factory.makePerson()
-        for info_type in [
-            InformationType.PROPRIETARY, InformationType.EMBARGOED]:
-            product = self.factory.makeProduct(
-                information_type=info_type, owner=owner)
-            with person_logged_in(owner):
-                product.setBugSharingPolicy(BugSharingPolicy.PUBLIC)
-                product.setSpecificationSharingPolicy(
-                    SpecificationSharingPolicy.PUBLIC)
-                product.setBranchSharingPolicy(BranchSharingPolicy.PUBLIC)
-            self.assertIsNot(None, getUtility(IAccessPolicySource).find(
-                [(product, info_type)]).one())
+        product = self.factory.makeProduct(
+            information_type=InformationType.EMBARGOED, owner=owner)
+        with person_logged_in(owner):
+            product.setBugSharingPolicy(BugSharingPolicy.PROPRIETARY)
+            product.setSpecificationSharingPolicy(
+                SpecificationSharingPolicy.PROPRIETARY)
+            product.setBranchSharingPolicy(BranchSharingPolicy.PROPRIETARY)
+        self.assertIsNot(None, getUtility(IAccessPolicySource).find(
+            [(product, InformationType.EMBARGOED)]).one())
 
 
 class TestProductBugInformationTypes(TestCaseWithFactory):
@@ -1521,6 +1571,28 @@
                 [InformationType.PRIVATESECURITY, InformationType.PROPRIETARY],
                 getAccessPolicyTypes(product))
 
+    def test_proprietary_products_forbid_public_policies(self):
+        # A proprietary project forbids any sharing policy that would permit
+        # public artifacts.
+        owner = self.product.owner
+        with person_logged_in(owner):
+            self.product.licenses = [License.OTHER_PROPRIETARY]
+            self.product.information_type = InformationType.PROPRIETARY
+        policies_permitting_public = [self.public_policy]
+        policies_permitting_public.extend(
+            policy for policy in self.commercial_policies if
+            InformationType.PUBLIC in self.allowed_types[policy])
+        for policy in policies_permitting_public:
+            with ExpectedException(
+                ProprietaryProduct, "The project is Proprietary."):
+                self.setSharingPolicy(policy, owner)
+        with person_logged_in(owner):
+            self.product.information_type = InformationType.EMBARGOED
+        for policy in policies_permitting_public:
+            with ExpectedException(
+                ProprietaryProduct, "The project is Embargoed."):
+                self.setSharingPolicy(policy, owner)
+
 
 class ProductBugSharingPolicyTestCase(BaseSharingPolicyTests,
                                       TestCaseWithFactory):
@@ -1535,6 +1607,7 @@
         BugSharingPolicy.PROPRIETARY_OR_PUBLIC,
         BugSharingPolicy.PROPRIETARY,
         )
+    allowed_types = BUG_POLICY_ALLOWED_TYPES
 
     def setSharingPolicy(self, policy, user):
         with person_logged_in(user):
@@ -1559,6 +1632,7 @@
         BranchSharingPolicy.PROPRIETARY,
         BranchSharingPolicy.EMBARGOED_OR_PROPRIETARY,
         )
+    allowed_types = BRANCH_POLICY_ALLOWED_TYPES
 
     def setSharingPolicy(self, policy, user):
         with person_logged_in(user):
@@ -1609,6 +1683,7 @@
         SpecificationSharingPolicy.PROPRIETARY,
         SpecificationSharingPolicy.EMBARGOED_OR_PROPRIETARY,
         )
+    allowed_types = SPECIFICATION_POLICY_ALLOWED_TYPES
 
     def setSharingPolicy(self, policy, user):
         with person_logged_in(user):
@@ -2052,15 +2127,15 @@
         self.assertIn(proprietary, result)
 
     def test_getTranslatables_filters_private_products(self):
-        # ProductSet.getTranslatables() returns rivate translatable
+        # ProductSet.getTranslatables() returns private translatable
         # products only for user that have grants for these products.
         owner = self.factory.makePerson()
         product = self.factory.makeProduct(
-            owner=owner, translations_usage=ServiceUsage.LAUNCHPAD)
+            owner=owner, translations_usage=ServiceUsage.LAUNCHPAD,
+            information_type=InformationType.PROPRIETARY)
         series = self.factory.makeProductSeries(product)
-        self.factory.makePOTemplate(productseries=series)
         with person_logged_in(owner):
-            product.information_type = InformationType.PROPRIETARY
+            self.factory.makePOTemplate(productseries=series)
         # Anonymous users do not see private products.
         with person_logged_in(ANONYMOUS):
             translatables = getUtility(IProductSet).getTranslatables()

=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py	2012-10-26 07:15:49 +0000
+++ lib/lp/testing/factory.py	2012-11-15 16:44:23 +0000
@@ -977,7 +977,15 @@
             else:
                 displayname = name.capitalize()
         if licenses is None:
-            if information_type in PROPRIETARY_INFORMATION_TYPES:
+            if (information_type in PROPRIETARY_INFORMATION_TYPES or
+                (bug_sharing_policy is not None and
+                 bug_sharing_policy != BugSharingPolicy.PUBLIC) or
+                (branch_sharing_policy is not None and
+                 branch_sharing_policy != BranchSharingPolicy.PUBLIC) or
+                (specification_sharing_policy is not None and
+                 specification_sharing_policy !=
+                 SpecificationSharingPolicy.PUBLIC)
+                ):
                 licenses = [License.OTHER_PROPRIETARY]
             else:
                 licenses = [License.GNU_GPL_V2]
@@ -1008,14 +1016,6 @@
             naked_product.bug_supervisor = bug_supervisor
         if driver is not None:
             naked_product.driver = driver
-        if ((branch_sharing_policy and
-            branch_sharing_policy != BranchSharingPolicy.PUBLIC) or
-            (bug_sharing_policy and
-            bug_sharing_policy != BugSharingPolicy.PUBLIC) or
-            (specification_sharing_policy and
-            specification_sharing_policy !=
-                SpecificationSharingPolicy.PUBLIC)):
-            self.makeCommercialSubscription(product)
         if branch_sharing_policy:
             naked_product.setBranchSharingPolicy(branch_sharing_policy)
         if bug_sharing_policy:
@@ -1023,8 +1023,6 @@
         if specification_sharing_policy:
             naked_product.setSpecificationSharingPolicy(
                 specification_sharing_policy)
-        if information_type is not None:
-            naked_product.information_type = information_type
         return product
 
     def makeProductSeries(self, product=None, name=None, owner=None,


Follow ups