launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #00333
[Merge] lp:~mwhudson/launchpad/vostok-traverse-distro into lp:launchpad/devel
Michael Hudson has proposed merging lp:~mwhudson/launchpad/vostok-traverse-distro into lp:launchpad/devel with lp:~mwhudson/launchpad/vostok-main-template as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Hi,
This branch adds a navigation for the vostok root that allows you to traverse
to distributions.
Cheers,
mwh
--
https://code.launchpad.net/~mwhudson/launchpad/vostok-traverse-distro/+merge/31241
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~mwhudson/launchpad/vostok-traverse-distro into lp:launchpad/devel.
=== modified file 'lib/lp/testing/factory.py'
--- lib/lp/testing/factory.py 2010-07-28 22:46:12 +0000
+++ lib/lp/testing/factory.py 2010-07-29 05:18:50 +0000
@@ -846,7 +846,7 @@
url = self.getUniqueURL()
else:
raise UnknownBranchTypeError(
- 'Unrecognized branch type: %r' % (branch_type,))
+ 'Unrecognized branch type: %r' % branch_type)
namespace = get_branch_namespace(
owner, product=product, distroseries=distroseries,
@@ -1656,7 +1656,7 @@
return library_file_alias
def makeDistribution(self, name=None, displayname=None, owner=None,
- members=None, title=None):
+ members=None, title=None, aliases=None):
"""Make a new distribution."""
if name is None:
name = self.getUniqueString()
@@ -1671,9 +1671,12 @@
owner = self.makePerson()
if members is None:
members = self.makeTeam(owner)
- return getUtility(IDistributionSet).new(
+ distro = getUtility(IDistributionSet).new(
name, displayname, title, description, summary, domainname,
members, owner)
+ if aliases is not None:
+ removeSecurityProxy(distro).setAliases(aliases)
+ return distro
def makeDistroRelease(self, distribution=None, version=None,
status=SeriesStatus.DEVELOPMENT,
@@ -1808,7 +1811,7 @@
def makeRecipeText(self, *branches):
if len(branches) == 0:
- branches = (self.makeAnyBranch(), )
+ branches = (self.makeAnyBranch(),)
base_branch = branches[0]
other_branches = branches[1:]
text = MINIMAL_RECIPE_TEXT % base_branch.bzr_identity
=== modified file 'lib/lp/vostok/browser/configure.zcml'
--- lib/lp/vostok/browser/configure.zcml 2010-07-29 05:18:48 +0000
+++ lib/lp/vostok/browser/configure.zcml 2010-07-29 05:18:50 +0000
@@ -27,4 +27,9 @@
layer="lp.vostok.publisher.VostokLayer"
/>
+ <browser:navigation
+ module="lp.vostok.publisher"
+ classes="VostokRootNavigation"
+ />
+
</configure>
=== modified file 'lib/lp/vostok/publisher.py'
--- lib/lp/vostok/publisher.py 2010-07-29 05:18:48 +0000
+++ lib/lp/vostok/publisher.py 2010-07-29 05:18:50 +0000
@@ -7,19 +7,24 @@
__all__ = [
'VostokBrowserRequest',
'VostokLayer',
+ 'VostokRootNavigation',
'vostok_request_publication_factory',
]
+from zope.component import getUtility
from zope.interface import implements, Interface
from zope.publisher.interfaces.browser import (
IBrowserRequest, IDefaultBrowserLayer)
+from canonical.launchpad.webapp import canonical_url, Navigation
from canonical.launchpad.webapp.publication import LaunchpadBrowserPublication
from canonical.launchpad.webapp.servers import (
LaunchpadBrowserRequest, VirtualHostRequestPublicationFactory)
from canonical.launchpad.webapp.vhosts import allvhosts
+from lp.registry.interfaces.distribution import IDistributionSet
+
class VostokLayer(IBrowserRequest, IDefaultBrowserLayer):
"""The Vostok layer."""
@@ -46,6 +51,19 @@
implements(IVostokRoot)
+class VostokRootNavigation(Navigation):
+
+ usedfor = IVostokRoot
+
+ def traverse(self, name):
+ distro = getUtility(IDistributionSet)[name]
+ if distro is not None and distro.name != name:
+ # This distro was accessed through one of its aliases, so we
+ # must redirect to its canonical URL.
+ return self.redirectSubTree(canonical_url(distro), status=301)
+ return distro
+
+
class VostokBrowserPublication(LaunchpadBrowserPublication):
root_object_interface = IVostokRoot
=== added file 'lib/lp/vostok/tests/test_navigation.py'
--- lib/lp/vostok/tests/test_navigation.py 1970-01-01 00:00:00 +0000
+++ lib/lp/vostok/tests/test_navigation.py 2010-07-29 05:18:50 +0000
@@ -0,0 +1,47 @@
+# Copyright 2010 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for vostok's root navigation."""
+
+__metaclass__ = type
+
+from zope.component import getMultiAdapter
+from zope.publisher.interfaces.browser import IBrowserPublisher
+
+from canonical.launchpad.webapp import canonical_url
+from canonical.launchpad.webapp.interfaces import NotFoundError
+from canonical.launchpad.webapp.servers import LaunchpadTestRequest
+from canonical.testing.layers import DatabaseFunctionalLayer
+
+from lp.testing import TestCaseWithFactory
+from lp.vostok.publisher import VostokRootNavigation, VostokRoot
+
+
+class TestRootNavigation(TestCaseWithFactory):
+
+ layer = DatabaseFunctionalLayer
+
+ @property
+ def _navigation(self):
+ return getMultiAdapter(
+ (VostokRoot(), LaunchpadTestRequest()), IBrowserPublisher,
+ name='')
+
+ def test_use_VostokRootNavigation(self):
+ self.assertIsInstance(self._navigation, VostokRootNavigation)
+
+ def test_traverse_to_distributions(self):
+ distro = self.factory.makeDistribution()
+ traversed = self._navigation.traverse(distro.name)
+ self.assertEqual(distro, traversed)
+
+ def test_traverse_to_distribution_aliases(self):
+ # When we traverse to a distribution using one of its aliases, we're
+ # redirected to the distribution's page.
+ distro = self.factory.makeDistribution(aliases=['f00'])
+ redirection_view = self._navigation.traverse('f00')
+ self.assertEqual(canonical_url(distro), redirection_view.target)
+
+ def test_can_not_traverse_to_projects(self):
+ path = self.factory.makeProject().name
+ self.assertRaises(NotFoundError, self._navigation.traverse, path)