← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~gary/launchpad/add-target-subscription-page into lp:launchpad

 

Gary Poster has proposed merging lp:~gary/launchpad/add-target-subscription-page into lp:launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~gary/launchpad/add-target-subscription-page/+merge/53095

This branch is an incremental branch that adds a page on which JS can be built to address bug 674422.  It is very similar at this time to lp.bugs.browser.bugsubscription.BugSubscriptionListView, which exists for the same reasons as part of the same effort.

make lint is happy.

You could kind of say I had a pre-imp with Benji about this; I am supporting an effort that he is leading.

Thank you 
-- 
https://code.launchpad.net/~gary/launchpad/add-target-subscription-page/+merge/53095
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~gary/launchpad/add-target-subscription-page into lp:launchpad.
=== modified file 'lib/lp/bugs/browser/bugtarget.py'
--- lib/lp/bugs/browser/bugtarget.py	2011-02-24 15:30:54 +0000
+++ lib/lp/bugs/browser/bugtarget.py	2011-03-11 21:38:57 +0000
@@ -24,10 +24,7 @@
 import cgi
 from cStringIO import StringIO
 from datetime import datetime
-from operator import (
-    attrgetter,
-    itemgetter,
-    )
+from operator import itemgetter
 import urllib
 
 from lazr.restful.interface import copy_field
@@ -129,6 +126,9 @@
 from lp.bugs.interfaces.malone import IMaloneApplication
 from lp.bugs.interfaces.securitycontact import IHasSecurityContact
 from lp.bugs.model.bugtask import BugTask
+from lp.bugs.model.structuralsubscription import (
+    get_all_structural_subscriptions_for_target,
+    )
 from lp.bugs.utilities.filebugdataparser import FileBugData
 from lp.hardwaredb.interfaces.hwdb import IHWSubmissionSet
 from lp.registry.browser.product import ProductConfigureBase
@@ -1560,3 +1560,18 @@
     def proxiedUrlForLibraryFile(self, patch):
         """Return the proxied download URL for a Librarian file."""
         return ProxiedLibraryFileAlias(patch.libraryfile, patch).http_url
+
+
+class TargetSubscriptionView(LaunchpadView):
+    """A view to show all a person's structural subscriptions to a target."""
+
+    @property
+    def label(self):
+        return "Your subscriptions to %s" % (self.context.displayname,)
+
+    page_title = label
+
+    @property
+    def structural_subscriptions(self):
+        return get_all_structural_subscriptions_for_target(
+            self.context, self.user)

=== modified file 'lib/lp/bugs/browser/configure.zcml'
--- lib/lp/bugs/browser/configure.zcml	2011-02-11 11:12:18 +0000
+++ lib/lp/bugs/browser/configure.zcml	2011-03-11 21:38:57 +0000
@@ -1200,6 +1200,12 @@
             permission="zope.Public"
             class="lp.bugs.browser.structuralsubscription.StructuralSubscribersPortletView"
             template="../templates/structural-subscription-target-portlet-subscribers.pt"/>
+        <browser:page
+            for="lp.bugs.interfaces.structuralsubscription.IStructuralSubscriptionTarget"
+            name="+subscriptions"
+            class="lp.bugs.browser.bugtarget.TargetSubscriptionView"
+            permission="launchpad.AnyPerson"
+            template="../templates/bugtarget-subscription-list.pt"/>
     </facet>
 
     <browser:url

=== added file 'lib/lp/bugs/browser/tests/test_bugtarget_subscription.py'
--- lib/lp/bugs/browser/tests/test_bugtarget_subscription.py	1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/browser/tests/test_bugtarget_subscription.py	2011-03-11 21:38:57 +0000
@@ -0,0 +1,37 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for TestSubscriptionView."""
+
+__metaclass__ = type
+
+from canonical.launchpad.ftests import LaunchpadFormHarness
+from canonical.testing.layers import LaunchpadFunctionalLayer
+from lp.bugs.browser.bugtarget import TargetSubscriptionView
+from lp.testing import (
+    person_logged_in,
+    TestCaseWithFactory,
+    )
+
+
+class TargetSubscriptionViewTestCase(TestCaseWithFactory):
+    """Tests for the TargetSubscriptionView."""
+
+    layer = LaunchpadFunctionalLayer
+
+    def setUp(self):
+        super(TargetSubscriptionViewTestCase, self).setUp()
+        self.product = self.factory.makeProduct(
+            name='widgetsrus', displayname='Widgets R Us')
+        self.subscriber = self.factory.makePerson()
+
+    def test_identify_structural_subscriptions(self):
+        # This shows simply that we can identify the structural
+        # subscriptions for the page.  The content will come later.
+        with person_logged_in(self.subscriber):
+            sub = self.product.addBugSubscription(
+                self.subscriber, self.subscriber)
+            harness = LaunchpadFormHarness(
+                self.product, TargetSubscriptionView)
+            self.assertEqual(
+                list(harness.view.structural_subscriptions), [sub])

=== modified file 'lib/lp/bugs/model/structuralsubscription.py'
--- lib/lp/bugs/model/structuralsubscription.py	2011-03-07 21:05:12 +0000
+++ lib/lp/bugs/model/structuralsubscription.py	2011-03-11 21:38:57 +0000
@@ -4,6 +4,7 @@
 __metaclass__ = type
 __all__ = [
     'get_all_structural_subscriptions',
+    'get_all_structural_subscriptions_for_target',
     'get_structural_subscribers',
     'get_structural_subscription_targets',
     'StructuralSubscription',
@@ -42,6 +43,7 @@
     getUtility,
     )
 from zope.interface import implements
+from zope.security.proxy import ProxyFactory
 
 from canonical.database.constants import UTC_NOW
 from canonical.database.sqlbase import quote
@@ -81,6 +83,7 @@
 from lp.registry.interfaces.productseries import IProductSeries
 from lp.registry.interfaces.projectgroup import IProjectGroup
 from lp.registry.interfaces.sourcepackage import ISourcePackage
+from lp.registry.model.teammembership import TeamParticipation
 from lp.services.propertycache import cachedproperty
 
 
@@ -504,6 +507,20 @@
             yield (bugtask, bugtask.milestone)
 
 
+@ProxyFactory
+def get_all_structural_subscriptions_for_target(target, person):
+    """Find the personal and team structural subscriptions to the target.
+    """
+    # This is here because of a circular import.
+    from lp.registry.model.person import Person
+    return IStore(StructuralSubscription).find(
+        StructuralSubscription,
+        IStructuralSubscriptionTargetHelper(target).join,
+        StructuralSubscription.subscriber == Person.id,
+        TeamParticipation.personID == person.id,
+        TeamParticipation.teamID == Person.id)
+
+
 def _get_all_structural_subscriptions(find, targets, *conditions):
     """Find the structural subscriptions for the given targets.
 

=== added file 'lib/lp/bugs/templates/bugtarget-subscription-list.pt'
--- lib/lp/bugs/templates/bugtarget-subscription-list.pt	1970-01-01 00:00:00 +0000
+++ lib/lp/bugs/templates/bugtarget-subscription-list.pt	2011-03-11 21:38:57 +0000
@@ -0,0 +1,25 @@
+<html
+  xmlns="http://www.w3.org/1999/xhtml";
+  xmlns:tal="http://xml.zope.org/namespaces/tal";
+  xmlns:metal="http://xml.zope.org/namespaces/metal";
+  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
+  xml:lang="en"
+  lang="en"
+  dir="ltr"
+  metal:use-macro="view/macro:page/main_only"
+  i18n:domain="malone"
+>
+
+<body>
+  <div metal:fill-slot="main">
+
+    <div id="maincontent">
+      <div id="nonportlets" class="readable">
+
+      </div>
+    </div>
+
+  </div>
+
+</body>
+</html>

=== modified file 'lib/lp/bugs/tests/test_structuralsubscriptiontarget.py'
--- lib/lp/bugs/tests/test_structuralsubscriptiontarget.py	2011-03-07 15:59:50 +0000
+++ lib/lp/bugs/tests/test_structuralsubscriptiontarget.py	2011-03-11 21:38:57 +0000
@@ -24,6 +24,7 @@
 from canonical.launchpad.webapp.interfaces import ILaunchBag
 from canonical.launchpad.webapp.testing import verifyObject
 from canonical.testing.layers import (
+    DatabaseFunctionalLayer,
     LaunchpadFunctionalLayer,
     LaunchpadZopelessLayer,
     )
@@ -32,7 +33,10 @@
     IStructuralSubscriptionTarget,
     IStructuralSubscriptionTargetHelper,
     )
-from lp.bugs.model.structuralsubscription import StructuralSubscription
+from lp.bugs.model.structuralsubscription import (
+    StructuralSubscription,
+    get_all_structural_subscriptions_for_target,
+    )
 from lp.bugs.tests.test_bugtarget import bugtarget_filebug
 from lp.registry.errors import (
     DeleteSubscriptionError,
@@ -46,9 +50,11 @@
     login,
     login_celebrity,
     login_person,
+    person_logged_in,
     TestCaseWithFactory,
     )
 from lp.testing.matchers import Provides
+from lp.testing.factory import is_security_proxied_or_harmless
 
 
 class RestrictedStructuralSubscriptionTestBase:
@@ -426,6 +432,51 @@
             compile_storm(helper.join))
 
 
+class TestGetAllStructuralSubscriptionsForTarget(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestGetAllStructuralSubscriptionsForTarget, self).setUp()
+        self.subscriber = self.factory.makePerson()
+        self.team = self.factory.makeTeam(members=[self.subscriber])
+        login_person(self.subscriber)
+        self.product = self.factory.makeProduct()
+        self.milestone = self.factory.makeMilestone(product=self.product)
+
+    def getSubscriptions(self):
+        subscriptions = get_all_structural_subscriptions_for_target(
+            self.product, self.subscriber)
+        self.assertTrue(is_security_proxied_or_harmless(subscriptions))
+        return subscriptions
+
+    def test_no_subscriptions(self):
+        subscriptions = self.getSubscriptions()
+        self.assertEqual([], list(subscriptions))
+
+    def test_self_subscription(self):
+        sub = self.product.addBugSubscription(
+            self.subscriber, self.subscriber)
+        subscriptions = self.getSubscriptions()
+        self.assertEqual([sub], list(subscriptions))
+
+    def test_team_subscription(self):
+        with person_logged_in(self.team.teamowner):
+            sub = self.product.addBugSubscription(
+                self.team, self.team.teamowner)
+        subscriptions = self.getSubscriptions()
+        self.assertEqual([sub], list(subscriptions))
+
+    def test_both_subscriptions(self):
+        self_sub = self.product.addBugSubscription(
+            self.subscriber, self.subscriber)
+        with person_logged_in(self.team.teamowner):
+            team_sub = self.product.addBugSubscription(
+                self.team, self.team.teamowner)
+        subscriptions = self.getSubscriptions()
+        self.assertEqual(set([self_sub, team_sub]), set(subscriptions))
+
+
 def distributionSourcePackageSetUp(test):
     setUp(test)
     ubuntu = getUtility(IDistributionSet).getByName('ubuntu')