launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #00423
lp:~mwhudson/launchpad/test_traverse-set-participation-bug-611570 into lp:launchpad/devel
Michael Hudson has proposed merging lp:~mwhudson/launchpad/test_traverse-set-participation-bug-611570 into lp:launchpad/devel.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
#611570 lp.testing.publication.test_traverse doesn't set the current participation
https://bugs.launchpad.net/bugs/611570
Hi,
This branch started out by making test_traverse set up a new interaction for the traversal it performs, so as to make the request that is being traversed 'current'. Then I wrote some more tests and discovered that, at least in some sense, the docstring's claim that it 'uses the current user' was inaccurate, so I fixed that too.
The key test helper I use is bonkers, but I think that's zope's fault (you can read the implementation of the browser:page in zope.browserpage.metaconfigure to see where I cribbed the insanity from).
Cheers,
mwh
--
https://code.launchpad.net/~mwhudson/launchpad/test_traverse-set-participation-bug-611570/+merge/31731
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~mwhudson/launchpad/test_traverse-set-participation-bug-611570 into lp:launchpad/devel.
=== modified file 'lib/lp/testing/publication.py'
--- lib/lp/testing/publication.py 2010-04-28 10:13:00 +0000
+++ lib/lp/testing/publication.py 2010-08-04 10:34:45 +0000
@@ -15,13 +15,17 @@
# Z3 doesn't make this available as a utility.
from zope.app import zapi
from zope.app.publication.requestpublicationregistry import factoryRegistry
+from zope.app.security.interfaces import IUnauthenticatedPrincipal
from zope.component import getUtility
from zope.interface import providedBy
from zope.publisher.interfaces.browser import IDefaultSkin
+from zope.security.management import restoreInteraction
from canonical.launchpad.interfaces.launchpad import IOpenLaunchBag
import canonical.launchpad.layers as layers
from canonical.launchpad.webapp import urlsplit
+from canonical.launchpad.webapp.interaction import setupInteraction
+from canonical.launchpad.webapp.publisher import get_current_browser_request
from canonical.launchpad.webapp.servers import ProtocolErrorPublication
@@ -103,8 +107,13 @@
if layer is not None:
layers.setAdditionalLayer(request, layer)
- principal = publication.getPrincipal(request)
- request.setPrincipal(principal)
+ principal = get_current_browser_request().principal
+
+ if IUnauthenticatedPrincipal.providedBy(principal):
+ login = None
+ else:
+ login = principal.person
+ setupInteraction(principal, login, request)
getUtility(IOpenLaunchBag).clear()
app = publication.getApplication(request)
@@ -112,4 +121,7 @@
# Since the last traversed object is the view, the second last should be
# the object that the view is on.
obj = request.traversed_objects[-2]
+
+ restoreInteraction()
+
return obj, view, request
=== added file 'lib/lp/testing/tests/test_publication.py'
--- lib/lp/testing/tests/test_publication.py 1970-01-01 00:00:00 +0000
+++ lib/lp/testing/tests/test_publication.py 2010-08-04 10:34:45 +0000
@@ -0,0 +1,92 @@
+# Copyright 2010 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for the helpers in `lp.testing.publication`."""
+
+__metaclass__ = type
+
+from zope.app.pagetemplate.simpleviewclass import simple
+from zope.component import getSiteManager, getUtility
+from zope.interface import Interface
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+from zope.security.checker import CheckerPublic, Checker, defineChecker
+
+from canonical.launchpad.interfaces.launchpad import ILaunchpadRoot
+from canonical.launchpad.webapp.interfaces import ILaunchBag
+from canonical.launchpad.webapp.publisher import get_current_browser_request
+from canonical.launchpad.webapp.servers import LaunchpadTestRequest
+from canonical.testing import DatabaseFunctionalLayer
+from lp.testing import ANONYMOUS, login, login_person, TestCaseWithFactory
+from lp.testing.publication import test_traverse
+
+
+class TestTestTraverse(TestCaseWithFactory):
+ # Tests for `test_traverse`
+
+ layer = DatabaseFunctionalLayer
+
+ def registerViewCallable(self, view_callable):
+ """Return a URL traversing to which will call `view_callable`.
+
+ :param view_callable: Will be called with no arguments during
+ traversal.
+ """
+ # This method is completely out of control. Thanks, Zope.
+ name = '+' + self.factory.getUniqueString()
+ class new_class(simple):
+ def __init__(self, context, request):
+ view_callable()
+ required = {}
+ for n in ('browserDefault', '__call__', 'publishTraverse'):
+ required[n] = CheckerPublic
+ defineChecker(new_class, Checker(required))
+ getSiteManager().registerAdapter(
+ new_class, (ILaunchpadRoot, IDefaultBrowserLayer), Interface, name)
+ self.addCleanup(
+ getSiteManager().unregisterAdapter, new_class,
+ (ILaunchpadRoot, IDefaultBrowserLayer), Interface, name)
+ return 'https://launchpad.dev/' + name
+
+ def test_traverse_simple(self):
+ # test_traverse called with a product URL returns the product
+ # as the traversed object.
+ login(ANONYMOUS)
+ product = self.factory.makeProduct()
+ context, view, request = test_traverse(
+ 'https://launchpad.dev/' + product.name)
+ self.assertEqual(product, context)
+
+ def test_request_is_current_during_traversal(self):
+ # The request that test_traverse creates is current during
+ # traversal in the sense of get_current_browser_request.
+ login(ANONYMOUS)
+ requests = []
+ def record_current_request():
+ requests.append(get_current_browser_request())
+ context, view, request = test_traverse(
+ self.registerViewCallable(record_current_request))
+ self.assertEqual(1, len(requests))
+ self.assertIs(request, requests[0])
+
+ def test_participation_restored(self):
+ # test_traverse restores the interaction (and hence
+ # participation) that was present before it was called.
+ request = LaunchpadTestRequest()
+ login(ANONYMOUS, request)
+ product = self.factory.makeProduct()
+ test_traverse('https://launchpad.dev/' + product.name)
+ self.assertIs(request, get_current_browser_request())
+
+ def test_uses_current_user(self):
+ # test_traverse performs the traversal as the currently logged
+ # in user.
+ person = self.factory.makePerson()
+ login_person(person)
+ users = []
+ def record_user():
+ users.append(getUtility(ILaunchBag).user)
+ context, view, request = test_traverse(
+ self.registerViewCallable(record_user))
+ self.assertEqual(1, len(users))
+ self.assertEqual(person, users[0])
+