launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #13080
[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