← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:distribution-portlet-requires-subscription into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:distribution-portlet-requires-subscription into launchpad:master.

Commit message:
Add Distribution:+portlet-requires-subscription

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/417649

I added a reference to this to Distribution:+index recently, but apparently forgot to add the portlet itself.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:distribution-portlet-requires-subscription into launchpad:master.
diff --git a/lib/lp/registry/browser/configure.zcml b/lib/lp/registry/browser/configure.zcml
index 07fada1..bc05ae3 100644
--- a/lib/lp/registry/browser/configure.zcml
+++ b/lib/lp/registry/browser/configure.zcml
@@ -2264,6 +2264,13 @@
         permission="zope.Public"
         template="../templates/distribution-details.pt"
         />
+    <browser:page
+        name="+portlet-requires-subscription"
+        for="lp.registry.interfaces.distribution.IDistribution"
+        class="lp.registry.browser.distribution.DistributionView"
+        permission="zope.Public"
+        template="../templates/distribution-portlet-requires-subscription.pt"
+        />
     <browser:pages
         for="lp.registry.interfaces.distribution.IDistribution"
         class="lp.registry.browser.distribution.DistributionReassignmentView"
diff --git a/lib/lp/registry/browser/tests/test_distribution.py b/lib/lp/registry/browser/tests/test_distribution.py
index b0c3b61..ebc686b 100644
--- a/lib/lp/registry/browser/tests/test_distribution.py
+++ b/lib/lp/registry/browser/tests/test_distribution.py
@@ -3,6 +3,8 @@
 
 """Tests for Distribution page."""
 
+import re
+
 from fixtures import FakeLogger
 from lazr.restful.fields import Reference
 from lazr.restful.interfaces import (
@@ -20,6 +22,7 @@ from zope.schema.vocabulary import SimpleVocabulary
 from zope.security.proxy import removeSecurityProxy
 
 from lp.app.browser.lazrjs import vocabulary_to_choice_edit_items
+from lp.app.enums import InformationType
 from lp.registry.enums import (
     DistributionDefaultTraversalPolicy,
     EXCLUSIVE_TEAM_POLICY,
@@ -501,6 +504,43 @@ class TestDistributionPage(TestCaseWithFactory):
             self.distro.official_packages = True
         self.assertThat(view(), builds_link)
 
+    def test_requires_subscription_owner(self):
+        # If the distribution is proprietary and doesn't have much time left
+        # on its commercial subscription, the owner sees a portlet directing
+        # them to purchase a subscription.
+        owner = self.distro.owner
+        with admin_logged_in():
+            self.distro.information_type = InformationType.PROPRIETARY
+        login_person(owner)
+        view = create_initialized_view(self.distro, "+index", principal=owner)
+        warning = soupmatchers.HTMLContains(soupmatchers.Within(
+            soupmatchers.Tag(
+                "Portlet container", "div",
+                attrs={"id": "portlet-requires-subscription"}),
+            soupmatchers.Tag(
+                "Heading", "h2",
+                text=re.compile(
+                    r"Purchasing a commercial subscription is required"))))
+        self.assertThat(view(), warning)
+
+    def test_requires_subscription_non_owner(self):
+        # If the distribution is proprietary and doesn't have much time left
+        # on its commercial subscription, non-owners do not see a portlet
+        # directing them to purchase a subscription.
+        with admin_logged_in():
+            self.distro.information_type = InformationType.PROPRIETARY
+            policy = self.factory.makeAccessPolicy(
+                pillar=self.distro, check_existing=True)
+            self.factory.makeAccessPolicyGrant(
+                policy=policy, grantee=self.simple_user)
+        login_person(self.simple_user)
+        view = create_initialized_view(
+            self.distro, "+index", principal=self.simple_user)
+        warning = soupmatchers.HTMLContains(soupmatchers.Tag(
+            "Portlet container", "div",
+            attrs={"id": "portlet-requires-subscription"}))
+        self.assertThat(view(), Not(warning))
+
 
 class TestDistributionView(TestCaseWithFactory):
     """Tests the DistributionView."""
diff --git a/lib/lp/registry/templates/distribution-portlet-requires-subscription.pt b/lib/lp/registry/templates/distribution-portlet-requires-subscription.pt
new file mode 100644
index 0000000..2bea13a
--- /dev/null
+++ b/lib/lp/registry/templates/distribution-portlet-requires-subscription.pt
@@ -0,0 +1,36 @@
+<tal:root
+  xmlns:tal="http://xml.zope.org/namespaces/tal";
+  xmlns:metal="http://xml.zope.org/namespaces/metal";
+  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
+  omit-tag="">
+<div id="portlet-requires-subscription"
+  style=""
+  tal:condition="context/commercial_subscription_is_due">
+  <h2>
+    Purchasing a commercial subscription is required
+  </h2>
+
+  <img style="float:left;" alt="Expiration warning"
+    src="/@@/expiration-large" />
+
+  <p tal:condition="context/commercial_subscription/date_expires | nothing">
+    <strong>Current subscription expires
+    <tal:date_expire
+     replace="structure context/commercial_subscription/date_expires/fmt:displaydatetitle"
+     />.</strong>
+  </p>
+
+  <p>
+    Private distributions do not qualify for free hosting.
+    If you have authorization from Canonical to use Launchpad's
+    commercial features, then
+    <a href="mailto:commercial@xxxxxxxxxxxxx";>contact us</a>
+    to have that applied to this project.
+  </p>
+
+  <p>
+    <a href="mailto:commercial@xxxxxxxxxxxxx";>Contact us</a> if you
+    have any questions about licensing or commercial hosting.
+  </p>
+</div>
+</tal:root>