← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~deryck/launchpad/series-information-type into lp:launchpad

 

Deryck Hodge has proposed merging lp:~deryck/launchpad/series-information-type into lp:launchpad with lp:~deryck/launchpad/milestone-information-type as a prerequisite.

Commit message:
Enable privacy portlet for ProductSeries. (Part of private projects feature work.)

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1063348 in Launchpad itself: "MIlestones and Series should get their information_type from Product"
  https://bugs.launchpad.net/launchpad/+bug/1063348

For more details, see:
https://code.launchpad.net/~deryck/launchpad/series-information-type/+merge/128392

This branch adds a privacy portlet for ProductSeries, along with a number of tests to ensure the portlet works, that ProductSeries' views get their information_type correctly, and that ProductSeries is adapted to Product for IInformationType.

I'm going to self-review since this is just like my previous branch for milestone, only applying the same fix for ProductSeries.  Abel reviewed that branch, and this one does mostly the same thing.  I feel confident in the changes, which are largely just adding tests and wiring up a portlet template.
-- 
https://code.launchpad.net/~deryck/launchpad/series-information-type/+merge/128392
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~deryck/launchpad/series-information-type into lp:launchpad.
=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml	2012-10-07 20:40:28 +0000
+++ lib/lp/registry/browser/configure.zcml	2012-10-07 20:40:28 +0000
@@ -1697,6 +1697,9 @@
         <browser:page
             name="+table-releases"
             template="../templates/productseries-table-releases.pt"/>
+        <browser:page
+            name="+portlet-privacy"
+            template="../templates/productseries-portlet-privacy.pt"/>
     </browser:pages>
     <browser:page
         name="+ubuntupkg"

=== modified file 'lib/lp/registry/browser/productseries.py'
--- lib/lp/registry/browser/productseries.py	2012-10-05 07:10:15 +0000
+++ lib/lp/registry/browser/productseries.py	2012-10-07 20:40:28 +0000
@@ -55,6 +55,7 @@
     )
 
 from lp import _
+from lp.app.browser.informationtype import InformationTypePortletMixin
 from lp.app.browser.launchpadform import (
     action,
     custom_widget,
@@ -424,7 +425,8 @@
             product.displayname)
 
 
-class ProductSeriesView(LaunchpadView, MilestoneOverlayMixin):
+class ProductSeriesView(
+    LaunchpadView, MilestoneOverlayMixin, InformationTypePortletMixin):
     """A view to show a series with translations."""
 
     def initialize(self):

=== modified file 'lib/lp/registry/browser/tests/test_productseries_views.py'
--- lib/lp/registry/browser/tests/test_productseries_views.py	2012-06-19 18:27:50 +0000
+++ lib/lp/registry/browser/tests/test_productseries_views.py	2012-10-07 20:40:28 +0000
@@ -7,7 +7,9 @@
 
 
 import soupmatchers
+from zope.security.proxy import removeSecurityProxy
 
+from lp.app.enums import InformationType
 from lp.bugs.interfaces.bugtask import (
     BugTaskStatus,
     BugTaskStatusSearch,
@@ -22,6 +24,57 @@
 from lp.testing.views import create_initialized_view
 
 
+class TestProductSeries(BrowserTestCase):
+
+    layer = DatabaseFunctionalLayer
+
+    def test_information_type_public(self):
+        # A ProductSeries view should include its information_type,
+        # which defaults to Public for new projects.
+        series = self.factory.makeProductSeries()
+        view = create_initialized_view(series, '+index')
+        self.assertEqual('Public', view.information_type)
+
+    def test_information_type_proprietary(self):
+        # A ProductSeries view should get its information_type
+        # from the related product even if the product is changed to
+        # PROPRIETARY.
+        product = self.factory.makeProduct()
+        self.factory.makeCommercialSubscription(product)
+        information_type = InformationType.PROPRIETARY
+        removeSecurityProxy(product).information_type = information_type
+        series = self.factory.makeProductSeries(product=product)
+        view = create_initialized_view(series, '+index')
+        self.assertEqual('Proprietary', view.information_type)
+
+    def test_privacy_portlet(self):
+        # A ProductSeries page should include a privacy portlet that
+        # accurately describes the information_type.
+        owner = self.factory.makePerson()
+        product = self.factory.makeProduct(owner=owner)
+        self.factory.makeCommercialSubscription(product)
+        information_type = InformationType.PROPRIETARY
+        removeSecurityProxy(product).information_type = information_type
+        series = self.factory.makeProductSeries(product=product)
+        policy = self.factory.makeAccessPolicy(pillar=product)
+        grant = self.factory.makeAccessPolicyGrant(
+            policy=policy, grantee=owner)
+        privacy_portlet = soupmatchers.Tag(
+            'info-type-portlet', 'span',
+            attrs={'id': 'information-type-summary'})
+        privacy_portlet_proprietary = soupmatchers.Tag(
+            'info-type-text', 'strong', attrs={'id': 'information-type'},
+            text='Proprietary')
+        browser = self.getViewBrowser(series, '+index', user=owner)
+        # First, assert that the portlet exists.
+        self.assertThat(
+            browser.contents, soupmatchers.HTMLContains(privacy_portlet))
+        # Then, assert that the text displayed matches the information_type.
+        self.assertThat(
+            browser.contents, soupmatchers.HTMLContains(
+            privacy_portlet_proprietary))
+
+
 class TestProductSeriesHelp(TestCaseWithFactory):
     layer = DatabaseFunctionalLayer
 

=== modified file 'lib/lp/registry/templates/productseries-index.pt'
--- lib/lp/registry/templates/productseries-index.pt	2012-02-01 15:31:32 +0000
+++ lib/lp/registry/templates/productseries-index.pt	2012-10-07 20:40:28 +0000
@@ -214,6 +214,8 @@
         </ul>
       </div>
 
+      <tal:privacy replace="structure context/@@+portlet-privacy" />
+
       <div id="downloads" class="top-portlet downloads"
         tal:define="release view/latest_release_with_download_files">
         <h2>Downloads</h2>

=== added file 'lib/lp/registry/templates/productseries-portlet-privacy.pt'
--- lib/lp/registry/templates/productseries-portlet-privacy.pt	1970-01-01 00:00:00 +0000
+++ lib/lp/registry/templates/productseries-portlet-privacy.pt	2012-10-07 20:40:28 +0000
@@ -0,0 +1,15 @@
+<div
+  xmlns:tal="http://xml.zope.org/namespaces/tal";
+  xmlns:metal="http://xml.zope.org/namespaces/metal";
+  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
+  id="privacy"
+  tal:attributes="class view/privacy_portlet_css"
+>
+    <span id="information-type-summary"
+      tal:attributes="class view/information_type_css;">This series
+      contains <strong id="information-type" tal:content="view/information_type">
+    </strong> information</span>
+
+    <div id="information-type-description" style="padding-top: 5px" tal:content="view/information_type_description"></div>
+</div>
+

=== modified file 'lib/lp/registry/tests/test_productseries.py'
--- lib/lp/registry/tests/test_productseries.py	2012-01-01 02:58:52 +0000
+++ lib/lp/registry/tests/test_productseries.py	2012-10-07 20:40:28 +0000
@@ -9,6 +9,8 @@
 from zope.component import getUtility
 from zope.security.proxy import removeSecurityProxy
 
+from lp.app.enums import InformationType
+from lp.app.interfaces.informationtype import IInformationType
 from lp.registry.interfaces.distribution import IDistributionSet
 from lp.registry.interfaces.distroseries import IDistroSeriesSet
 from lp.registry.interfaces.productseries import (
@@ -33,6 +35,23 @@
     )
 
 
+
+class TestProductSeries(TestCaseWithFactory):
+    """Tests for ProductSeries."""
+
+    layer = DatabaseFunctionalLayer
+
+    def test_information_type_from_product(self):
+        # ProductSeries should inherit information_type from its product."""
+        product = self.factory.makeProduct()
+        self.factory.makeCommercialSubscription(product)
+        information_type = InformationType.PROPRIETARY
+        removeSecurityProxy(product).information_type = information_type
+        series = self.factory.makeProductSeries(product=product)
+        self.assertEqual(
+            IInformationType(series).information_type, information_type)
+
+
 class ProductSeriesReleasesTestCase(TestCaseWithFactory):
     """Test for ProductSeries.release property."""
 


Follow ups