← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/launchpad:remove-zope.app.testing.ztapi into launchpad:master

 

Colin Watson has proposed merging ~cjwatson/launchpad:remove-zope.app.testing.ztapi into launchpad:master with ~cjwatson/launchpad:remove-test-event-listener as a prerequisite.

Commit message:
Remove all uses of zope.app.testing.ztapi

We want to move away from using zope.app.testing.  Some parts of this
are complicated, but ztapi can be replaced using the various
Zope*Fixture classes with just some rearrangement of arguments, and the
fixtures are easier to use in Launchpad anyway.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/374630
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/launchpad:remove-zope.app.testing.ztapi into launchpad:master.
diff --git a/lib/lp/app/stories/basics/xx-developerexceptions.txt b/lib/lp/app/stories/basics/xx-developerexceptions.txt
index d0ec3e2..a63c448 100644
--- a/lib/lp/app/stories/basics/xx-developerexceptions.txt
+++ b/lib/lp/app/stories/basics/xx-developerexceptions.txt
@@ -6,13 +6,18 @@ occurs. Other users get no traceback and only the OOPS ID.
 To be able to test, a page that generates HTTP 500 errors is registered.
 Accessing that page gives us the OOPS error page.
 
-    >>> from zope.app.testing import ztapi
+    >>> from zope.interface import Interface
+    >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+    >>> from lp.testing.fixture import ZopeAdapterFixture
+
     >>> class ErrorView(object):
     ...     """A broken view"""
     ...     def __call__(self, *args, **kw):
     ...         raise Exception('Oops')
     ...
-    >>> ztapi.browserView(None, "error-test", ErrorView)
+    >>> error_view_fixture = ZopeAdapterFixture(
+    ...     ErrorView, (None, IDefaultBrowserLayer), Interface, "error-test")
+    >>> error_view_fixture.setUp()
 
 As our test runner runs in 'always show tracebacks' mode, we need to
 switch this off for these tests to work
@@ -82,11 +87,13 @@ And the OOPS ID is displayed but not linkified.
     <code class="oopsid">OOPS-...</code>)
     ...
 
-To avoid affecting other tests, reset the show_tracebacks config item.
+To avoid affecting other tests, reset the show_tracebacks config item and
+unregister the adapter.
 
     >>> test_config_data = config.pop('test_data')
     >>> config.canonical.show_tracebacks
     True
+    >>> error_view_fixture.cleanUp()
 
 
 = HTTPCaller handle_errors =
diff --git a/lib/lp/app/stories/basics/xx-opstats.txt b/lib/lp/app/stories/basics/xx-opstats.txt
index 897ae19..47e7780 100644
--- a/lib/lp/app/stories/basics/xx-opstats.txt
+++ b/lib/lp/app/stories/basics/xx-opstats.txt
@@ -98,13 +98,18 @@ may also include the odd case where the OOPS system has failed and a
 fallback error page is rendered by Zope3. There doesn't seem to be any
 particular need to differentiate these cases though:
 
-    >>> from zope.app.testing import ztapi
+    >>> from zope.interface import Interface
+    >>> from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+    >>> from lp.testing.fixture import ZopeAdapterFixture
+
     >>> class ErrorView(object):
     ...     """A broken view"""
     ...     def __call__(self, *args, **kw):
     ...         raise Exception('Oops')
     ...
-    >>> ztapi.browserView(None, "error-test", ErrorView)
+    >>> error_view_fixture = ZopeAdapterFixture(
+    ...     ErrorView, (None, IDefaultBrowserLayer), Interface, "error-test")
+    >>> error_view_fixture.setUp()
     >>> output = http("GET /error-test HTTP/1.1\nHost: launchpad.test\n")
     >>> output.getStatus()
     500
@@ -134,6 +139,8 @@ the site.
     http requests: 1
     requests: 1
 
+    >>> error_view_fixture.cleanUp()
+
 Number of XML-RPC Faults
 ------------------------
 
diff --git a/lib/lp/services/webapp/doc/menus.txt b/lib/lp/services/webapp/doc/menus.txt
index d79969c..d29f08e 100644
--- a/lib/lp/services/webapp/doc/menus.txt
+++ b/lib/lp/services/webapp/doc/menus.txt
@@ -768,11 +768,16 @@ object. Let's say that the default view name for an IStreet is '+baz'.
 This is the common case where the overview link is the default view
 name.
 
+    >>> from zope.publisher.interfaces import IDefaultViewName
+    >>> from zope.publisher.interfaces.browser import IBrowserRequest
+    >>> from lp.testing.fixture import ZopeAdapterFixture
+
     >>> class IStreet(Interface):
     ...     """A street."""
     >>> directlyProvides(street, IStreet, IThingHavingFacets)
-    >>> from zope.app.testing import ztapi
-    >>> ztapi.setDefaultViewName(IStreet, '+baz', None)
+    >>> street_default_view_fixture = ZopeAdapterFixture(
+    ...     '+baz', (IStreet, IBrowserRequest), IDefaultViewName)
+    >>> street_default_view_fixture.setUp()
 
     >>> request = FakeRequest(
     ...     'http://launchpad.test/sesamestreet/+baz',
@@ -795,6 +800,8 @@ infrastructure actually calculates a shortened URL for this case.
     http://launchpad.test/sesamestreet/+bar True
     http://launchpad.test/sesamestreet False
 
+    >>> street_default_view_fixture.cleanUp()
+
 You can traverse to an individual menu item from the facet menu:
 
     >>> view = LaunchpadView(house, request)
diff --git a/lib/lp/services/webapp/tests/test_authorization.py b/lib/lp/services/webapp/tests/test_authorization.py
index ee63806..5f5db72 100644
--- a/lib/lp/services/webapp/tests/test_authorization.py
+++ b/lib/lp/services/webapp/tests/test_authorization.py
@@ -10,18 +10,12 @@ from random import getrandbits
 import StringIO
 
 import transaction
-from zope.app.testing import ztapi
-from zope.component import (
-    provideAdapter,
-    provideUtility,
-    )
 from zope.interface import (
     implementer,
     Interface,
     provider,
     )
 from zope.security.interfaces import Unauthorized
-import zope.testing.cleanup
 
 from lp.app.interfaces.security import IAuthorization
 from lp.app.security import AuthorizationBase
@@ -61,7 +55,10 @@ from lp.testing import (
     TestCase,
     )
 from lp.testing.factory import ObjectFactory
-from lp.testing.fixture import ZopeAdapterFixture
+from lp.testing.fixture import (
+    ZopeAdapterFixture,
+    ZopeUtilityFixture,
+    )
 from lp.testing.layers import (
     DatabaseFunctionalLayer,
     ZopelessLayer,
@@ -226,11 +223,9 @@ class TestCheckPermissionCaching(TestCase):
 
     def setUp(self):
         """Register a new permission and a fake store selector."""
-        zope.testing.cleanup.cleanUp()
         super(TestCheckPermissionCaching, self).setUp()
         self.factory = ObjectFactory()
-        provideUtility(FakeStoreSelector, IStoreSelector)
-        self.addCleanup(zope.testing.cleanup.cleanUp)
+        self.useFixture(ZopeUtilityFixture(FakeStoreSelector, IStoreSelector))
 
     def makeRequest(self):
         """Construct an arbitrary `LaunchpadBrowserRequest` object."""
@@ -246,11 +241,11 @@ class TestCheckPermissionCaching(TestCase):
             `Checker` created by ``checker_factory``.
         """
         permission = self.factory.getUniqueString()
-        provideUtility(
-            PermissionAccessLevel(), ILaunchpadPermission, permission)
+        self.useFixture(ZopeUtilityFixture(
+            PermissionAccessLevel(), ILaunchpadPermission, permission))
         checker_factory = CheckerFactory()
-        provideAdapter(
-            checker_factory, [Object], IAuthorization, name=permission)
+        self.useFixture(ZopeAdapterFixture(
+            checker_factory, [Object], IAuthorization, name=permission))
         return Object(), permission, checker_factory
 
     def test_checkPermission_cache_unauthenticated(self):
@@ -386,9 +381,8 @@ class TestCheckPermissionCaching(TestCase):
         # checkUnauthenticatedPermission caches the result of
         # checkUnauthenticated for a particular object and permission.
         # We set a principal to ensure that it is not used even if set.
-        provideUtility(PlacelessAuthUtility(), IPlacelessAuthUtility)
-        zope.testing.cleanup.addCleanUp(
-            ztapi.unprovideUtility, (IPlacelessAuthUtility,))
+        self.useFixture(ZopeUtilityFixture(
+            PlacelessAuthUtility(), IPlacelessAuthUtility))
         principal = FakeLaunchpadPrincipal()
         request = self.makeRequest()
         request.setPrincipal(principal)
@@ -409,9 +403,8 @@ class TestCheckPermissionCaching(TestCase):
     def test_checkUnauthenticatedPermission_commit_clears_cache(self):
         # Committing a transaction clears the cache.
         # We set a principal to ensure that it is not used even if set.
-        provideUtility(PlacelessAuthUtility(), IPlacelessAuthUtility)
-        zope.testing.cleanup.addCleanUp(
-            ztapi.unprovideUtility, (IPlacelessAuthUtility,))
+        self.useFixture(ZopeUtilityFixture(
+            PlacelessAuthUtility(), IPlacelessAuthUtility))
         principal = FakeLaunchpadPrincipal()
         request = self.makeRequest()
         request.setPrincipal(principal)
@@ -435,16 +428,15 @@ class TestCheckPermissionCaching(TestCase):
 class TestLaunchpadSecurityPolicy_getPrincipalsAccessLevel(TestCase):
 
     def setUp(self):
-        zope.testing.cleanup.cleanUp()
         cls = TestLaunchpadSecurityPolicy_getPrincipalsAccessLevel
         super(cls, self).setUp()
         self.principal = LaunchpadPrincipal(
             'foo.bar@xxxxxxxxxxxxx', 'foo', 'foo', object())
         self.security = LaunchpadSecurityPolicy()
-        provideAdapter(
-            adapt_loneobject_to_container, [ILoneObject], ILaunchpadContainer)
-        provideAdapter(LoneObjectURL, [ILoneObject], ICanonicalUrlData)
-        self.addCleanup(zope.testing.cleanup.cleanUp)
+        self.useFixture(ZopeAdapterFixture(
+            adapt_loneobject_to_container, [ILoneObject], ILaunchpadContainer))
+        self.useFixture(ZopeAdapterFixture(
+            LoneObjectURL, [ILoneObject], ICanonicalUrlData))
 
     def test_no_scope(self):
         """Principal's access level is used when no scope is given."""
diff --git a/lib/lp/services/webapp/tests/test_authutility.py b/lib/lp/services/webapp/tests/test_authutility.py
index c6b5b91..d2dfcbc 100644
--- a/lib/lp/services/webapp/tests/test_authutility.py
+++ b/lib/lp/services/webapp/tests/test_authutility.py
@@ -6,14 +6,9 @@ __metaclass__ = type
 import base64
 
 import testtools
-from zope.app.testing import ztapi
 from zope.app.testing.placelesssetup import PlacelessSetup
 from zope.authentication.interfaces import ILoginPassword
-from zope.component import (
-    getUtility,
-    provideAdapter,
-    provideUtility,
-    )
+from zope.component import getUtility
 from zope.interface import implementer
 from zope.principalregistry.principalregistry import UnauthenticatedPrincipal
 from zope.publisher.browser import TestRequest
@@ -31,6 +26,10 @@ from lp.services.webapp.interfaces import (
     IPlacelessAuthUtility,
     IPlacelessLoginSource,
     )
+from lp.testing.fixture import (
+    ZopeAdapterFixture,
+    ZopeUtilityFixture,
+    )
 
 
 @implementer(IPerson)
@@ -64,13 +63,14 @@ class TestPlacelessAuth(PlacelessSetup, testtools.TestCase):
     def setUp(self):
         testtools.TestCase.setUp(self)
         PlacelessSetup.setUp(self)
-        provideUtility(DummyPlacelessLoginSource(), IPlacelessLoginSource)
-        provideUtility(PlacelessAuthUtility(), IPlacelessAuthUtility)
-        provideAdapter(BasicAuthAdapter, (IHTTPCredentials,), ILoginPassword)
+        self.useFixture(ZopeUtilityFixture(
+            DummyPlacelessLoginSource(), IPlacelessLoginSource))
+        self.useFixture(ZopeUtilityFixture(
+            PlacelessAuthUtility(), IPlacelessAuthUtility))
+        self.useFixture(ZopeAdapterFixture(
+            BasicAuthAdapter, (IHTTPCredentials,), ILoginPassword))
 
     def tearDown(self):
-        ztapi.unprovideUtility(IPlacelessLoginSource)
-        ztapi.unprovideUtility(IPlacelessAuthUtility)
         PlacelessSetup.tearDown(self)
         testtools.TestCase.tearDown(self)
 
diff --git a/lib/lp/services/webapp/tests/test_error.py b/lib/lp/services/webapp/tests/test_error.py
index b9b9f28..7ad4e83 100644
--- a/lib/lp/services/webapp/tests/test_error.py
+++ b/lib/lp/services/webapp/tests/test_error.py
@@ -24,7 +24,8 @@ from testtools.matchers import (
     MatchesListwise,
     )
 import transaction
-from zope.app.testing import ztapi
+from zope.interface import Interface
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
 
 from lp.services.webapp.error import (
     DisconnectionErrorView,
@@ -37,6 +38,7 @@ from lp.testing.fixture import (
     CaptureOops,
     PGBouncerFixture,
     Urllib2Fixture,
+    ZopeAdapterFixture,
     )
 from lp.testing.layers import (
     DatabaseLayer,
@@ -234,7 +236,9 @@ class TestDatabaseErrorViews(TestCase):
             """A view that raises an OperationalError"""
             def __call__(self, *args, **kw):
                 raise OperationalError()
-        ztapi.browserView(None, "error-test", BrokenView())
+        self.useFixture(ZopeAdapterFixture(
+            BrokenView(), (None, IDefaultBrowserLayer), Interface,
+            "error-test"))
 
         url = 'http://launchpad.test/error-test'
         error = self.getHTTPError(url)
diff --git a/lib/lp/testing/__init__.py b/lib/lp/testing/__init__.py
index 1aa11ea..6a0d9b2 100644
--- a/lib/lp/testing/__init__.py
+++ b/lib/lp/testing/__init__.py
@@ -107,7 +107,6 @@ from testtools.matchers import (
     )
 from testtools.testcase import ExpectedException as TTExpectedException
 import transaction
-from zope.app.testing import ztapi
 from zope.component import (
     ComponentLookupError,
     getMultiAdapter,
@@ -185,7 +184,10 @@ from lp.testing._webservice import (
     oauth_access_token_for,
     )
 from lp.testing.dbuser import switch_dbuser
-from lp.testing.fixture import CaptureOops
+from lp.testing.fixture import (
+    CaptureOops,
+    ZopeEventHandlerFixture,
+    )
 from lp.testing.karma import KarmaRecorder
 from lp.testing.mail_helpers import pop_notifications
 
@@ -390,6 +392,7 @@ class RequestTimelineCollector:
         self._active = False
         self.count = None
         self.queries = None
+        self._event_fixture = None
 
     def register(self):
         """Start counting queries.
@@ -398,7 +401,9 @@ class RequestTimelineCollector:
 
         After each web request the count and queries attributes are updated.
         """
-        ztapi.subscribe((IEndRequestEvent, ), None, self)
+        self._event_fixture = ZopeEventHandlerFixture(
+            self, (IEndRequestEvent, ))
+        self._event_fixture.setUp()
         self._active = True
 
     def __enter__(self):
@@ -412,6 +417,9 @@ class RequestTimelineCollector:
 
     def unregister(self):
         self._active = False
+        if self._event_fixture is not None:
+            self._event_fixture.cleanUp()
+            self._event_fixture = None
 
     def __exit__(self, exc_type, exc_value, traceback):
         self.unregister()