Commit 78a25721 authored by Stefan H. Holek's avatar Stefan H. Holek

Update ZopeTestCase to match latest standalone release (0.9.6).

Note that doctest support is not done yet!
parent 2ec8632c
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
# getPortal() returns a usable portal object to the setup code. # getPortal() returns a usable portal object to the setup code.
# #
# $Id: PortalTestCase.py,v 1.29 2004/09/09 18:48:59 shh42 Exp $ # $Id: PortalTestCase.py,v 1.38 2005/02/09 12:42:40 shh42 Exp $
import base import base
import types import interfaces
import utils
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
...@@ -30,32 +31,14 @@ from ZopeTestCase import user_password ...@@ -30,32 +31,14 @@ from ZopeTestCase import user_password
class PortalTestCase(base.TestCase): class PortalTestCase(base.TestCase):
'''Base test case for testing CMF-style portals '''Base test case for testing CMF-style portals'''
__implements__ = (IPortalTestCase, ISimpleSecurity, IExtensibleSecurity) __implements__ = (interfaces.IPortalTestCase,
interfaces.IPortalSecurity,
See doc/IZopeTestCase.py for more. base.TestCase.__implements__)
'''
_configure_portal = 1 _configure_portal = 1
def getPortal(self):
'''Returns the portal object to the setup code.
Will typically be overridden by subclasses
to return the object serving as the "portal".
Note: This method should not be called by tests!
'''
return self.app[portal_name]
def createMemberarea(self, member_id):
'''Creates a memberarea for the specified member.
Subclasses may override to provide a customized
or more lightweight version of the memberarea.
'''
pm = self.portal.portal_membership
pm.createMemberarea(member_id)
def setUp(self): def setUp(self):
'''Sets up the fixture. Do not override, '''Sets up the fixture. Do not override,
use the hooks instead. use the hooks instead.
...@@ -63,7 +46,7 @@ class PortalTestCase(base.TestCase): ...@@ -63,7 +46,7 @@ class PortalTestCase(base.TestCase):
try: try:
self.beforeSetUp() self.beforeSetUp()
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self._portal()
self._setup() self._setup()
self._refreshSkinData() self._refreshSkinData()
self.afterSetUp() self.afterSetUp()
...@@ -71,6 +54,10 @@ class PortalTestCase(base.TestCase): ...@@ -71,6 +54,10 @@ class PortalTestCase(base.TestCase):
self._clear() self._clear()
raise raise
def _portal(self):
'''Returns the portal object for a test.'''
return self.getPortal()
def _setup(self): def _setup(self):
'''Configures the portal. Framework authors may '''Configures the portal. Framework authors may
override. override.
...@@ -104,30 +91,37 @@ class PortalTestCase(base.TestCase): ...@@ -104,30 +91,37 @@ class PortalTestCase(base.TestCase):
if hasattr(self.portal, 'setupCurrentSkin'): if hasattr(self.portal, 'setupCurrentSkin'):
self.portal.setupCurrentSkin() self.portal.setupCurrentSkin()
# Security interfaces # Portal interface
def getPortal(self):
'''Returns the portal object to the setup code.
Will typically be overridden by subclasses
to return the object serving as the "portal".
Note: This method should not be called by tests!
'''
return self.app[portal_name]
def createMemberarea(self, name):
'''Creates a memberarea for the specified user.
Subclasses may override to provide a customized
or more lightweight version of the memberarea.
'''
pm = self.portal.portal_membership
pm.createMemberarea(name)
# Security interface
def setRoles(self, roles, name=user_name): def setRoles(self, roles, name=user_name):
'''Changes the user's roles.''' '''Changes the user's roles.'''
self.assertEqual(type(roles), types.ListType)
uf = self.portal.acl_users uf = self.portal.acl_users
uf.userFolderEditUser(name, None, roles, []) uf.userFolderEditUser(name, None, utils.makelist(roles), [])
if name == getSecurityManager().getUser().getId(): if name == getSecurityManager().getUser().getId():
self.login(name) self.login(name)
def getRoles(self, name=user_name):
'''Returns the user's roles.'''
uf = self.portal.acl_users
return uf.getUserById(name).getRoles()
def setPermissions(self, permissions, role='Member'): def setPermissions(self, permissions, role='Member'):
'''Changes the permissions assigned to role.''' '''Changes the permissions assigned to role.'''
self.assertEqual(type(permissions), types.ListType) self.portal.manage_role(role, utils.makelist(permissions))
self.portal.manage_role(role, permissions)
def getPermissions(self, role='Member'):
'''Returns the permissions assigned to role.'''
perms = self.portal.permissionsOfRole(role)
return [p['name'] for p in perms if p['selected']]
def login(self, name=user_name): def login(self, name=user_name):
'''Logs in.''' '''Logs in.'''
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
import os, sys, time import os, sys, time
# Allow code to tell it is run by the test framework
os.environ['ZOPETESTCASE'] = '1'
# Increase performance on MP hardware # Increase performance on MP hardware
sys.setcheckinterval(2500) sys.setcheckinterval(2500)
......
...@@ -11,10 +11,12 @@ ...@@ -11,10 +11,12 @@
# and 'View' permissions given to his role. # and 'View' permissions given to his role.
# #
# $Id: ZopeTestCase.py,v 1.21 2004/09/04 18:01:08 shh42 Exp $ # $Id: ZopeTestCase.py,v 1.29 2005/02/09 12:42:40 shh42 Exp $
import base import base
import types import functional
import interfaces
import utils
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from AccessControl.SecurityManagement import newSecurityManager from AccessControl.SecurityManagement import newSecurityManager
...@@ -30,12 +32,10 @@ standard_permissions = [access_contents_information, view] ...@@ -30,12 +32,10 @@ standard_permissions = [access_contents_information, view]
class ZopeTestCase(base.TestCase): class ZopeTestCase(base.TestCase):
'''Base test case for Zope testing '''Base test case for Zope testing'''
__implements__ = (IZopeTestCase, ISimpleSecurity, IExtensibleSecurity) __implements__ = (interfaces.IZopeSecurity,
base.TestCase.__implements__)
See doc/IZopeTestCase.py for more
'''
_setup_fixture = 1 _setup_fixture = 1
...@@ -75,30 +75,18 @@ class ZopeTestCase(base.TestCase): ...@@ -75,30 +75,18 @@ class ZopeTestCase(base.TestCase):
pass pass
base.TestCase._clear(self, call_close_hook) base.TestCase._clear(self, call_close_hook)
# Security interfaces # Security interface
def setRoles(self, roles, name=user_name): def setRoles(self, roles, name=user_name):
'''Changes the user's roles.''' '''Changes the user's roles.'''
self.assertEqual(type(roles), types.ListType)
uf = self.folder.acl_users uf = self.folder.acl_users
uf.userFolderEditUser(name, None, roles, []) uf.userFolderEditUser(name, None, utils.makelist(roles), [])
if name == getSecurityManager().getUser().getId(): if name == getSecurityManager().getUser().getId():
self.login(name) self.login(name)
def getRoles(self, name=user_name):
'''Returns the user's roles.'''
uf = self.folder.acl_users
return uf.getUserById(name).getRoles()
def setPermissions(self, permissions, role=user_role): def setPermissions(self, permissions, role=user_role):
'''Changes the user's permissions.''' '''Changes the user's permissions.'''
self.assertEqual(type(permissions), types.ListType) self.folder.manage_role(role, utils.makelist(permissions))
self.folder.manage_role(role, permissions)
def getPermissions(self, role=user_role):
'''Returns the user's permissions.'''
perms = self.folder.permissionsOfRole(role)
return [p['name'] for p in perms if p['selected']]
def login(self, name=user_name): def login(self, name=user_name):
'''Logs in.''' '''Logs in.'''
...@@ -124,6 +112,13 @@ class ZopeTestCase(base.TestCase): ...@@ -124,6 +112,13 @@ class ZopeTestCase(base.TestCase):
self.logout() self.logout()
class FunctionalTestCase(functional.Functional, ZopeTestCase):
'''Base class for functional Zope tests'''
__implements__ = (functional.Functional.__implements__,
ZopeTestCase.__implements__)
# b/w compatibility names # b/w compatibility names
_folder_name = folder_name _folder_name = folder_name
_user_name = user_name _user_name = user_name
......
# #
# Names exported by the ZopeTestCase module # Names exported by the ZopeTestCase package
# #
# $Id: __init__.py,v 1.13 2004/08/19 15:52:55 shh42 Exp $ # $Id: __init__.py,v 1.25 2005/02/22 14:59:16 shh42 Exp $
import ZopeLite as Zope2 import ZopeLite as Zope2
import utils import utils
from ZopeLite import installProduct
from ZopeLite import hasProduct from ZopeLite import hasProduct
from ZopeLite import installProduct
from ZopeLite import _print from ZopeLite import _print
from base import TestCase
from base import app
from base import close
from ZopeTestCase import folder_name from ZopeTestCase import folder_name
from ZopeTestCase import user_name from ZopeTestCase import user_name
from ZopeTestCase import user_password from ZopeTestCase import user_password
from ZopeTestCase import user_role from ZopeTestCase import user_role
from ZopeTestCase import standard_permissions from ZopeTestCase import standard_permissions
from ZopeTestCase import ZopeTestCase from ZopeTestCase import ZopeTestCase
from ZopeTestCase import FunctionalTestCase
from PortalTestCase import portal_name from PortalTestCase import portal_name
from PortalTestCase import PortalTestCase from PortalTestCase import PortalTestCase
from base import TestCase
from base import app
from base import close
from profiler import Profiled from profiler import Profiled
from sandbox import Sandboxed from sandbox import Sandboxed
from functional import Functional from functional import Functional
from warnhook import WarningsHook
from unittest import main from unittest import main
# Convenience class for functional unit testing # TODO
class FunctionalTestCase(Functional, ZopeTestCase): #from doctest import ZopeDocFileSuite
pass #from doctest import FunctionalDocFileSuite
# b/w compatibility names # b/w compatibility names
_folder_name = folder_name _folder_name = folder_name
......
...@@ -10,6 +10,7 @@ import unittest ...@@ -10,6 +10,7 @@ import unittest
import transaction import transaction
import profiler import profiler
import utils import utils
import interfaces
from AccessControl.SecurityManagement import noSecurityManager from AccessControl.SecurityManagement import noSecurityManager
...@@ -35,12 +36,11 @@ def closeConnections(): ...@@ -35,12 +36,11 @@ def closeConnections():
class TestCase(profiler.Profiled, unittest.TestCase): class TestCase(profiler.Profiled, unittest.TestCase):
'''Base test case for Zope testing '''Base test case for Zope testing
__implements__ = (IZopeTestCase,)
See doc/IZopeTestCase.py for more
''' '''
__implements__ = (interfaces.IZopeTestCase,
profiler.Profiled.__implements__)
def afterSetUp(self): def afterSetUp(self):
'''Called after setUp() has completed. This is '''Called after setUp() has completed. This is
far and away the most useful hook. far and away the most useful hook.
...@@ -107,6 +107,7 @@ class TestCase(profiler.Profiled, unittest.TestCase): ...@@ -107,6 +107,7 @@ class TestCase(profiler.Profiled, unittest.TestCase):
'''Sets up the fixture. Framework authors may '''Sets up the fixture. Framework authors may
override. override.
''' '''
pass
def _clear(self, call_close_hook=0): def _clear(self, call_close_hook=0):
'''Clears the fixture.''' '''Clears the fixture.'''
......
...@@ -41,18 +41,22 @@ Module Testing.ZopeTestCase ...@@ -41,18 +41,22 @@ Module Testing.ZopeTestCase
Classes Classes
TestCase
ZopeTestCase ZopeTestCase
FunctionalTestCase
PortalTestCase PortalTestCase
TestCase
Profiled Profiled
Sandboxed Sandboxed
Functional Functional
WarningsHook
Modules Modules
ZopeLite as Zope ZopeLite as Zope
...@@ -87,7 +91,7 @@ Module ZopeLite ...@@ -87,7 +91,7 @@ Module ZopeLite
Module base Module base
Bare-bones base test case for Zope testing Basic infrastructure for Zope testing
Functions Functions
...@@ -103,9 +107,12 @@ Module base ...@@ -103,9 +107,12 @@ Module base
Class TestCase Class TestCase
Bare-bones base test case for Zope testing Base test case for Zope testing
(derived from unittest.TestCase) (derived from unittest.TestCase)
__implements__ = (IZopeTestCase,
Profiled.__implements__)
Methods Methods
afterSetUp() afterSetUp()
...@@ -139,30 +146,45 @@ Module ZopeTestCase ...@@ -139,30 +146,45 @@ Module ZopeTestCase
Classes Classes
ZopeTestCase ZopeTestCase
FunctionalTestCase
Class ZopeTestCase Class ZopeTestCase
Base test case for Zope testing Base test case for Zope testing
(derived from base.TestCase) (derived from base.TestCase)
__implements__ = (IZopeSecurity,
TestCase.__implements__)
Methods Methods
setRoles(roles, name=user_name) setRoles(roles, name=user_name)
getRoles(name=user_name)
setPermissions(permissions, role=user_role) setPermissions(permissions, role=user_role)
getPermissions(role=user_role)
login(name=user_name) login(name=user_name)
logout() logout()
Class FunctionalTestCase
Base class for functional unit tests
(derived from ZopeTestCase)
__implements__ = (Functional.__implements__,
ZopeTestCase.__implements__)
Methods
*See base classes*
Module PortalTestCase Module PortalTestCase
Test case and fixture for testing CMF-based applications Test case and fixture for testing CMF-based applications
...@@ -179,13 +201,17 @@ Module PortalTestCase ...@@ -179,13 +201,17 @@ Module PortalTestCase
PortalTestCase PortalTestCase
Class PortalTestCase Class PortalTestCase
Base test case for CMF testing Base test case for CMF testing
(derived from base.TestCase) (derived from base.TestCase)
__implements__ = (IPortalTestCase,
IPortalSecurity,
TestCase.__implements__)
Methods Methods
getPortal() getPortal()
...@@ -194,12 +220,8 @@ Class PortalTestCase ...@@ -194,12 +220,8 @@ Class PortalTestCase
setRoles(roles, name=user_name) setRoles(roles, name=user_name)
getRoles(name=user_name)
setPermissions(permissions, role='Member') setPermissions(permissions, role='Member')
getPermissions(role='Member')
login(name=user_name) login(name=user_name)
logout() logout()
...@@ -228,6 +250,8 @@ Class Profiled ...@@ -228,6 +250,8 @@ Class Profiled
Profiling support mix-in for xTestCases Profiling support mix-in for xTestCases
__implements__ = (IProfiled,)
Methods Methods
runcall(func, *args, **kw) runcall(func, *args, **kw)
...@@ -268,9 +292,39 @@ Class Functional ...@@ -268,9 +292,39 @@ Class Functional
Functional testing mix-in for xTestCases Functional testing mix-in for xTestCases
__implements__ = (IFunctional,)
Methods Methods
publish(path, basic=None, env=None, extra=None, request_method='GET') publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None)
Module warnhook
Support for capturing Python warning messages
Classes
WarningsHook
Class WarningsHook
Facility to capture warnings generated by Python
Attributes
warnings
Methods
install()
uninstall()
clear()
......
0.9.6
- Dropped support for Zope 2.5 as it lacks the setSecurityManager() API.
- Moved interfaces from doc section to interfaces.py module.
- Test classes now assert their interfaces.
- Refactored security interfaces to IZopeSecurity and IPortalSecurity.
- Added a class diagram to the doc section.
- setRoles() and setPermissions() no longer insist on ListType arguments
but now accept lists, tuples, and strings.
- getRoles() and getPermissions() are no longer part of the security API
because of YAGNI.
- Added getHeader() and getCookie() accessors to the response wrapper
used in functional tests.
- publish() now accepts an optional 'stdin' argument, allowing to pass
the input stream for POST and PUT requests.
- runalltests.py now supports a '-R' (recursive) command line option.
0.9.4 (not released)
- Backported functional doc tests from Zope 3.
- Included a copy of doctest.py from Zope 3 (which is copied from
Python2.4 CVS). It will be removed when we start requiring Python2.4.
- Added dochttp.py script from Zope 3, which is used to convert
tcpwatch.py output to functional doc tests.
- Added warnhook.py from ZODB. It is used to capture the output of
warnings.warn() calls.
- Added missing 'user_password' constant.
- Many thanks to Sidnei da Silva!
0.9.2 0.9.2
- Introduced new base.TestCase class which contains the bare- - Introduced new base.TestCase class which contains the bare-
bones framework code and serves as baseclass for ZTC and PTC. bones framework code and serves as baseclass for ZTC and PTC.
...@@ -26,7 +53,7 @@ ...@@ -26,7 +53,7 @@
- ZopeLite now loads silently if it does not control the import process. - ZopeLite now loads silently if it does not control the import process.
0.8.6 0.8.6
- Revised and amended much of the existing documentation. - Revised and amended much of the existing documentation.
- Added an API reference (skeleton), API.stx. - Added an API reference (skeleton), API.stx.
- Documented what's going on when tests are run in TIMELINES.txt. - Documented what's going on when tests are run in TIMELINES.txt.
- Fixed issues with testZODBCompat.py and Zope < 2.6. - Fixed issues with testZODBCompat.py and Zope < 2.6.
...@@ -35,15 +62,15 @@ ...@@ -35,15 +62,15 @@
0.8.4 0.8.4
- framework.py now flushes stdout to not mess up the output in batch mode. - framework.py now flushes stdout to not mess up the output in batch mode.
- framework.py no longer adds os.pardir to the sys.path. Thanks to - framework.py no longer adds os.pardir to the sys.path. Thanks to
Yoshinori Okuji. Yoshinori Okuji.
- Made sure user objects are not inadvertently wrapped twice by login(). - Made sure user objects are not inadvertently wrapped twice by login().
- Made sure "renegade" transactions are aborted if something goes wrong - Made sure "renegade" transactions are aborted if something goes wrong
during the setup phase. during the setup phase.
- initialize_cache() is no longer called for Zope 2.7. - initialize_cache() is no longer called for Zope 2.7.
0.8.2 0.8.2
- Removed the leading underscores from all constant names. They proved - Removed the leading underscores from all constant names. They proved
non-private in "real life" anyway. The old names are still available non-private in "real life" anyway. The old names are still available
for backward compatibility, but are deprecated. for backward compatibility, but are deprecated.
- Removed NO_PRODUCT_LOAD for reasons of obscureness and YAGNI. - Removed NO_PRODUCT_LOAD for reasons of obscureness and YAGNI.
...@@ -62,7 +89,7 @@ ...@@ -62,7 +89,7 @@
role-mapping assumes it can append to it. :-/ role-mapping assumes it can append to it. :-/
0.7.0 0.7.0
- Fixed a bug that caused setRoles() to only work with the - Fixed a bug that caused setRoles() to only work with the
default user folder. Refactored the fixture code in the process. default user folder. Refactored the fixture code in the process.
- Reworked the connection registry and wrote tests for it. - Reworked the connection registry and wrote tests for it.
- Made afterClear() largely redundant because it turned out to be just that. - Made afterClear() largely redundant because it turned out to be just that.
...@@ -77,13 +104,13 @@ ...@@ -77,13 +104,13 @@
- Added IZopeTestCase and IZopeTestCaseFX interfaces. - Added IZopeTestCase and IZopeTestCaseFX interfaces.
0.6.2 0.6.2
- The effects of setting INSTANCE_HOME have been changed to something - The effects of setting INSTANCE_HOME have been changed to something
less surprising. Please see ENVIRONMENT.txt for details. less surprising. Please see ENVIRONMENT.txt for details.
- Now uses the environment variable ZEO_INSTANCE_HOME to enable ZEO - Now uses the environment variable ZEO_INSTANCE_HOME to enable ZEO
support. support.
0.6.0 0.6.0
- Use a module-level database connection registry to avoid freezing - Use a module-level database connection registry to avoid freezing
after too many errors. after too many errors.
- All tests are now transactional by default. - All tests are now transactional by default.
- Added beforeSetUp() and beforeClose() hooks to the ZopeTestCase class. - Added beforeSetUp() and beforeClose() hooks to the ZopeTestCase class.
...@@ -99,7 +126,7 @@ ...@@ -99,7 +126,7 @@
- Hardening in the face of incomplete Zope installations. - Hardening in the face of incomplete Zope installations.
0.5.2 0.5.2
- Delete ZEO_CLIENT environment variable to enforce a temporary client - Delete ZEO_CLIENT environment variable to enforce a temporary client
cache. Repair Zope 2.4 Testing package issue in the process. cache. Repair Zope 2.4 Testing package issue in the process.
- Provide NO_PRODUCT_LOAD environment variable for completeness. - Provide NO_PRODUCT_LOAD environment variable for completeness.
- Added hasProduct() method to allow testing for product availability. - Added hasProduct() method to allow testing for product availability.
......
...@@ -7,7 +7,7 @@ Functional Testing Readme ...@@ -7,7 +7,7 @@ Functional Testing Readme
Deriving from the 'Functional' mix-in (and an xTestCase) adds a Deriving from the 'Functional' mix-in (and an xTestCase) adds a
'publish' method to your test case class. Tests can call 'publish' method to your test case class. Tests can call
'self.publish(path, basic=None, env=None, extra=None, request_method='GET')', 'self.publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None)',
passing a path and, optionally, basic-auth info and form data. passing a path and, optionally, basic-auth info and form data.
The path may contain a query string. The path may contain a query string.
......
...@@ -204,7 +204,7 @@ Writing Tests ...@@ -204,7 +204,7 @@ Writing Tests
- The ZopeTestCase class is defined in file 'ZopeTestCase.py'. - The ZopeTestCase class is defined in file 'ZopeTestCase.py'.
- The interfaces implemented by this class are documented in 'doc/IZopeTestCase.py'. - The interfaces implemented by this class are documented in 'interfaces.py'.
- All names exported by the ZopeTestCase package are listed in '__init__.py'. - All names exported by the ZopeTestCase package are listed in '__init__.py'.
......
<style type="text/css"> <!-- li { margin: 1em } --> </style>
Installation Instructions for ZopeTestCase
Requires Python 2.1 and Zope 2.5 or higher
1. Extract the tarball into the 'lib/python/Testing'
directory of your Zope installation.
2. Cd into the ZopeTestCase directory and execute
'python runalltests.py' to test the package and to
make sure all modules get compiled.
You must use the same Python that is running your
Zope here. On Windows this may for example be::
"C:\Program Files\Zope\bin\python.exe" runalltests.py
3. See the HOWTO for the big picture, the README for
getting started with your own tests.
Visit the "ZopeTestCaseWiki":http://zope.org/Members/shh/ZopeTestCaseWiki
for additional documentation.
...@@ -85,7 +85,7 @@ Read the Source ...@@ -85,7 +85,7 @@ Read the Source
As always, I recommend to look at the source code of both As always, I recommend to look at the source code of both
'ZopeTestCase.py' and 'PortalTestCase.py' for all the details you may need. 'ZopeTestCase.py' and 'PortalTestCase.py' for all the details you may need.
Interface documentation can be found in 'doc/IZopeTestCase.py'. Interface documentation can be found in 'interfaces.py'.
The test framework shipping with Plone 2.0 is a good example of how the The test framework shipping with Plone 2.0 is a good example of how the
PortalTestCase class can be put to use. PortalTestCase class can be put to use.
......
...@@ -33,16 +33,10 @@ Security API ...@@ -33,16 +33,10 @@ Security API
- **'self.setRoles(roles, name=user_name)'** allows to change the roles assigned to a user. - **'self.setRoles(roles, name=user_name)'** allows to change the roles assigned to a user.
If the 'name' argument is omitted, changes the roles of the default user. If the 'name' argument is omitted, changes the roles of the default user.
- **'self.getRoles(name=user_name)'** returns the roles assigned to a user. If the name argument is
omitted, returns the roles assigned to the default user.
- **'self.setPermissions(permissions, role=user_role)'** allows to change the permissions - **'self.setPermissions(permissions, role=user_role)'** allows to change the permissions
assigned to a role. If the 'role' argument is omitted, changes the permissions of the assigned to a role. If the 'role' argument is omitted, changes the permissions of the
default role. default role.
- **'self.getPermissions(role=user_role)'** return the permissions assigned to a role. If the role
argument is omitted, returns the permissions assigned to the default role.
- **'self.login(name=user_name)'** allows to log in as a specified user. - **'self.login(name=user_name)'** allows to log in as a specified user.
If the 'name' argument is omitted, logs in as the default user. If the 'name' argument is omitted, logs in as the default user.
...@@ -50,12 +44,12 @@ Security API ...@@ -50,12 +44,12 @@ Security API
Testing Security Testing Security
- **'ob.restrictedTraverse(attr)'** is a simple way to check whether the currently logged in user is - **'ob.restrictedTraverse("attr")'** is a simple way to check whether the currently logged in user is
allowed to access attribute 'attr' of object 'ob'. allowed to access attribute 'attr' of object 'ob'.
- **'getSecurityManager().validate(None, ob, attr, ob.attr)'** uses the security manager to do the same. - **'getSecurityManager().validate(None, ob, "attr", ob.attr)'** uses the security manager to do the same.
The convenience method 'getSecurityManager().validateValue(ob.attr)' will no longer work The convenience method 'getSecurityManager().validateValue(ob.attr)' will no longer work
in Zope 2.8 (from what I hear). in Zope 2.8.
Also see the 'testPythonScript.py' example test. Also see the 'testPythonScript.py' example test.
......
ZopeTestCase 0.9.2
(c) 2002-2004, Stefan H. Holek, stefan@epy.co.at
http://zope.org/Members/shh/ZopeTestCase
License: ZPL
Zope: 2.5-2.8
...@@ -8,29 +8,38 @@ ...@@ -8,29 +8,38 @@
import sys, re, base64 import sys, re, base64
import transaction import transaction
import sandbox import sandbox
import interfaces
class Functional(sandbox.Sandboxed): class Functional(sandbox.Sandboxed):
'''Derive from this class and an xTestCase to get functional '''Derive from this class and an xTestCase to get functional
testing support:: testing support::
class MyTest(Functional, ZopeTestCase): class MyTest(Functional, ZopeTestCase):
... ...
''' '''
def publish(self, path, basic=None, env=None, extra=None, request_method='GET'): __implements__ = (interfaces.IFunctional,)
'''Publishes the object at 'path' returning an enhanced response object.'''
def publish(self, path, basic=None, env=None, extra=None, request_method='GET', stdin=None):
'''Publishes the object at 'path' returning a response object.'''
from StringIO import StringIO from StringIO import StringIO
from ZPublisher.Response import Response from ZPublisher.Response import Response
from ZPublisher.Test import publish_module from ZPublisher.Test import publish_module
from AccessControl.SecurityManagement import getSecurityManager
from AccessControl.SecurityManagement import setSecurityManager
# Save current security manager
sm = getSecurityManager()
# Commit the sandbox for good measure # Commit the sandbox for good measure
transaction.commit() transaction.commit()
if env is None: if env is None:
env = {} env = {}
if extra is None: if extra is None:
extra = {} extra = {}
request = self.app.REQUEST request = self.app.REQUEST
...@@ -40,26 +49,32 @@ class Functional(sandbox.Sandboxed): ...@@ -40,26 +49,32 @@ class Functional(sandbox.Sandboxed):
env['REQUEST_METHOD'] = request_method env['REQUEST_METHOD'] = request_method
p = path.split('?') p = path.split('?')
if len(p) == 1: if len(p) == 1:
env['PATH_INFO'] = p[0] env['PATH_INFO'] = p[0]
elif len(p) == 2: elif len(p) == 2:
[env['PATH_INFO'], env['QUERY_STRING']] = p [env['PATH_INFO'], env['QUERY_STRING']] = p
else: else:
raise TypeError, '' raise TypeError, ''
if basic: if basic:
env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic) env['HTTP_AUTHORIZATION'] = "Basic %s" % base64.encodestring(basic)
if stdin is None:
stdin = sys.stdin
outstream = StringIO() outstream = StringIO()
response = Response(stdout=outstream, stderr=sys.stderr) response = Response(stdout=outstream, stderr=sys.stderr)
publish_module('Zope2', response=response, stdin=stdin, environ=env, extra=extra)
publish_module('Zope2', response=response, environ=env, extra=extra) # Restore security manager
setSecurityManager(sm)
return ResponseWrapper(response, outstream, path) return ResponseWrapper(response, outstream, path)
class ResponseWrapper: class ResponseWrapper:
'''Acts like a response object with some additional introspective methods.''' '''Decorates a response object with additional introspective methods.'''
_bodyre = re.compile('^$^\n(.*)', re.MULTILINE | re.DOTALL) _bodyre = re.compile('^$^\n(.*)', re.MULTILINE | re.DOTALL)
...@@ -68,6 +83,9 @@ class ResponseWrapper: ...@@ -68,6 +83,9 @@ class ResponseWrapper:
self._outstream = outstream self._outstream = outstream
self._path = path self._path = path
def __getattr__(self, name):
return getattr(self._response, name)
def getOutput(self): def getOutput(self):
'''Returns the complete output, headers and all.''' '''Returns the complete output, headers and all.'''
return self._outstream.getvalue() return self._outstream.getvalue()
...@@ -83,6 +101,11 @@ class ResponseWrapper: ...@@ -83,6 +101,11 @@ class ResponseWrapper:
'''Returns the path used by the request.''' '''Returns the path used by the request.'''
return self._path return self._path
def __getattr__(self, name): def getHeader(self, name):
return getattr(self._response, name) '''Returns the value of a response header.'''
return self.headers.get(name.lower())
def getCookie(self, name):
'''Returns a response cookie.'''
return self.cookies.get(name)
from Interface import Interface
# $Id: IZopeTestCase.py,v 1.14 2004/09/04 18:01:11 shh42 Exp $
# #
# ZopeTestCase.__implements__ = ( # ZopeTestCase interfaces
# IZopeTestCase, ISimpleSecurity, IExtensibleSecurity)
# #
# PortalTestCase.__implements__ = (
# IPortalTestCase, ISimpleSecurity, IExtensibleSecurity)
#
class ISimpleSecurity(Interface):
def setRoles(roles):
'''Changes the user's roles.'''
def getRoles():
'''Returns the user's roles.'''
def setPermissions(permissions):
'''Changes the user's permissions.'''
def getPermissions():
'''Returns the user's permissions.'''
def login():
'''Logs in.'''
def logout():
'''Logs out.'''
class IExtensibleSecurity(Interface):
def setRoles(roles, name):
'''Changes the roles assigned to a user.'''
def getRoles(name):
'''Returns the specified user's roles.'''
def setPermissions(permissions, role): # $Id: interfaces.py,v 1.5 2005/02/07 21:59:35 shh42 Exp $
'''Changes the permissions assigned to a role.'''
def getPermissions(role): try:
'''Returns the permissions assigned to a role.''' from Interface import Interface
except ImportError:
def login(name): # Old interface package
'''Logs in as the specified user.''' from Interface import Base as Interface
def logout():
'''Logs out.'''
class IZopeTestCase(Interface): class IZopeTestCase(Interface):
...@@ -86,6 +43,30 @@ class IZopeTestCase(Interface): ...@@ -86,6 +43,30 @@ class IZopeTestCase(Interface):
''' '''
class IZopeSecurity(Interface):
def setRoles(roles, name=None):
'''Changes the roles assigned to a user.
If the 'name' argument is omitted, changes the
roles of the default user.
'''
def setPermissions(permissions, role=None):
'''Changes the permissions assigned to a role.
If the 'role' argument is omitted, changes the
permissions assigned to the default role.
'''
def login(name=None):
'''Logs in as the specified user.
If the 'name' argument is omitted, logs in
as the default user.
'''
def logout():
'''Logs out.'''
class IPortalTestCase(IZopeTestCase): class IPortalTestCase(IZopeTestCase):
def getPortal(): def getPortal():
...@@ -96,13 +77,17 @@ class IPortalTestCase(IZopeTestCase): ...@@ -96,13 +77,17 @@ class IPortalTestCase(IZopeTestCase):
Note: This method should not be called by tests! Note: This method should not be called by tests!
''' '''
def createMemberarea(member_id): def createMemberarea(name):
'''Creates a memberarea for the specified member. '''Creates a memberarea for the specified user.
Subclasses may override to provide a customized Subclasses may override to provide a customized
or more lightweight version of the memberarea. or more lightweight version of the memberarea.
''' '''
class IPortalSecurity(IZopeSecurity):
'''This is currently the same as IZopeSecurity'''
class IProfiled(Interface): class IProfiled(Interface):
def runcall(func, *args, **kw): def runcall(func, *args, **kw):
...@@ -113,7 +98,7 @@ class IProfiled(Interface): ...@@ -113,7 +98,7 @@ class IProfiled(Interface):
class IFunctional(Interface): class IFunctional(Interface):
def publish(path, basic=None, env=None, extra=None, request_method='GET'): def publish(path, basic=None, env=None, extra=None, request_method='GET', stdin=None):
'''Publishes the object at 'path' returning an '''Publishes the object at 'path' returning an
extended response object. The path may contain extended response object. The path may contain
a query string. a query string.
......
...@@ -2,9 +2,10 @@ ...@@ -2,9 +2,10 @@
# Profiling support for ZTC # Profiling support for ZTC
# #
# $Id: profiler.py,v 1.2 2004/01/12 18:45:42 shh42 Exp $ # $Id: profiler.py,v 1.3 2005/01/01 14:02:44 shh42 Exp $
import os, sys import os, sys
import interfaces
from profile import Profile from profile import Profile
from pstats import Stats from pstats import Stats
...@@ -35,7 +36,7 @@ def print_stats(limit=limit, sort=sort, strip_dirs=strip_dirs): ...@@ -35,7 +36,7 @@ def print_stats(limit=limit, sort=sort, strip_dirs=strip_dirs):
def dump_stats(filename): def dump_stats(filename):
if _have_stats: if _have_stats:
_profile.dump_stats(filename) _profile.dump_stats(filename)
class Profiled: class Profiled:
'''Derive from this class and an xTestCase to get profiling support:: '''Derive from this class and an xTestCase to get profiling support::
...@@ -50,6 +51,8 @@ class Profiled: ...@@ -50,6 +51,8 @@ class Profiled:
Profiler statistics will be printed after the test results. Profiler statistics will be printed after the test results.
''' '''
__implements__ = (interfaces.IProfiled,)
def runcall(self, *args, **kw): def runcall(self, *args, **kw):
return apply(runcall, args, kw) return apply(runcall, args, kw)
......
# #
# Runs all tests in the current directory # Runs all tests in the current directory [and below]
# #
# Execute like: # Execute like:
# python runalltests.py # python runalltests.py [-R]
# #
# Alternatively use the testrunner: # Alternatively use the testrunner:
# python /path/to/Zope/utilities/testrunner.py -qa # python /path/to/Zope/bin/testrunner.py -qa
# #
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py')) execfile(os.path.join(sys.path[0], 'framework.py'))
import unittest import unittest, imp
TestRunner = unittest.TextTestRunner TestRunner = unittest.TextTestRunner
suite = unittest.TestSuite() suite = unittest.TestSuite()
tests = os.listdir(os.curdir) def visitor(recursive, dir, names):
tests = [n[:-3] for n in tests if n.startswith('test') and n.endswith('.py')] tests = [n[:-3] for n in names if n.startswith('test') and n.endswith('.py')]
for test in tests: for test in tests:
m = __import__(test) saved_syspath = sys.path[:]
if hasattr(m, 'test_suite'): sys.path.insert(0, dir)
suite.addTest(m.test_suite()) try:
fp, path, desc = imp.find_module(test, [dir])
m = imp.load_module(test, fp, path, desc)
if hasattr(m, 'test_suite'):
suite.addTest(m.test_suite())
finally:
fp.close()
sys.path[:] = saved_syspath
if not recursive:
names[:] = []
if __name__ == '__main__': if __name__ == '__main__':
os.path.walk(os.curdir, visitor, '-R' in sys.argv)
TestRunner().run(suite) TestRunner().run(suite)
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
# way of getting started. # way of getting started.
# #
# $Id: testBaseTestCase.py,v 1.2 2004/09/04 18:56:41 shh42 Exp $ # $Id: testBaseTestCase.py,v 1.7 2005/02/09 12:42:40 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -285,6 +285,43 @@ class TestRequestVariables(base.TestCase): ...@@ -285,6 +285,43 @@ class TestRequestVariables(base.TestCase):
self.failIfEqual(request.get('BASE2', ''), '') self.failIfEqual(request.get('BASE2', ''), '')
class TestListConverter(base.TestCase):
def testList0(self):
self.assertEqual(utils.makelist([]), [])
def testList1(self):
self.assertEqual(utils.makelist(['foo']), ['foo'])
def testList2(self):
self.assertEqual(utils.makelist(['foo', 'bar']), ['foo', 'bar'])
def testTuple0(self):
self.assertEqual(utils.makelist(()), [])
def testTuple1(self):
self.assertEqual(utils.makelist(('foo',)), ['foo'])
def testTuple2(self):
self.assertEqual(utils.makelist(('foo', 'bar')), ['foo', 'bar'])
def testString0(self):
self.assertEqual(utils.makelist(''), [])
def testString1(self):
self.assertEqual(utils.makelist('foo'), ['foo'])
def testString2(self):
self.assertEqual(utils.makelist('foo, bar'), ['foo, bar'])
def testInteger(self):
self.assertRaises(ValueError, utils.makelist, 0)
def testObject(self):
class dummy: pass
self.assertRaises(ValueError, utils.makelist, dummy())
def test_suite(): def test_suite():
from unittest import TestSuite, makeSuite from unittest import TestSuite, makeSuite
suite = TestSuite() suite = TestSuite()
...@@ -293,6 +330,7 @@ def test_suite(): ...@@ -293,6 +330,7 @@ def test_suite():
suite.addTest(makeSuite(TestTearDownRaises)) suite.addTest(makeSuite(TestTearDownRaises))
suite.addTest(makeSuite(TestConnectionRegistry)) suite.addTest(makeSuite(TestConnectionRegistry))
suite.addTest(makeSuite(TestRequestVariables)) suite.addTest(makeSuite(TestRequestVariables))
suite.addTest(makeSuite(TestListConverter))
return suite return suite
if __name__ == '__main__': if __name__ == '__main__':
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Example functional ZopeTestCase # Example functional ZopeTestCase
# #
# $Id: testFunctional.py,v 1.7 2004/09/04 18:01:08 shh42 Exp $ # $Id: testFunctional.py,v 1.16 2005/02/12 13:13:04 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -12,27 +12,57 @@ from Testing import ZopeTestCase ...@@ -12,27 +12,57 @@ from Testing import ZopeTestCase
ZopeTestCase.installProduct('PythonScripts') ZopeTestCase.installProduct('PythonScripts')
from Testing.ZopeTestCase import user_name
from Testing.ZopeTestCase import user_password
class TestFunctional(ZopeTestCase.Functional, ZopeTestCase.ZopeTestCase): from AccessControl import getSecurityManager
from AccessControl.Permissions import view
from AccessControl.Permissions import manage_properties
from AccessControl.Permissions import add_documents_images_and_files
from AccessControl.Permissions import change_dtml_documents
from StringIO import StringIO
from urllib import urlencode
class TestFunctional(ZopeTestCase.FunctionalTestCase):
def afterSetUp(self): def afterSetUp(self):
self.folder_path = '/%s' % self.folder.absolute_url(1) self.folder_path = '/'+self.folder.absolute_url(1)
self.basic_auth = '%s:%s' % (ZopeTestCase.user_name, ZopeTestCase.user_password) self.basic_auth = '%s:%s' % (user_name, user_password)
# A simple document
self.folder.addDTMLDocument('index_html', file='index')
self.folder.addDTMLMethod('index_html', file='foo') # A document accessible only to its owner
self.folder.addDTMLDocument('secret_html', file='secret')
self.folder.secret_html.manage_permission(view, ['Owner'])
dispatcher = self.folder.manage_addProduct['PythonScripts'] # A Python Script performing integer computation
dispatcher.manage_addPythonScript('script') self.folder.manage_addProduct['PythonScripts'].manage_addPythonScript('script')
self.folder.script.ZPythonScript_edit('a=0', 'return a+1') self.folder.script.ZPythonScript_edit(params='a=0', body='return a+1')
self.folder.manage_addFolder('object', '') # A method redirecting to the Zope root
self.folder.addDTMLMethod('change_title', redirect = '''<dtml-call "RESPONSE.redirect('%s')">''' % self.app.absolute_url()
file='''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">''') self.folder.addDTMLMethod('redirect', file=redirect)
# A method setting a cookie
set_cookie = '''<dtml-call "RESPONSE.setCookie('foo', 'Bar', path='/')">'''
self.folder.addDTMLMethod('set_cookie', file=set_cookie)
# A method changing the title property of an object
change_title = '''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">'''
self.folder.addDTMLMethod('change_title', file=change_title)
def testPublishFolder(self):
response = self.publish(self.folder_path)
self.assertEqual(response.getStatus(), 200)
self.assertEqual(response.getBody(), 'index')
def testPublishDocument(self): def testPublishDocument(self):
response = self.publish(self.folder_path+'/index_html') response = self.publish(self.folder_path+'/index_html')
self.assertEqual(response.getStatus(), 200) self.assertEqual(response.getStatus(), 200)
self.assertEqual(response.getBody(), 'foo') self.assertEqual(response.getBody(), 'index')
def testPublishScript(self): def testPublishScript(self):
response = self.publish(self.folder_path+'/script') response = self.publish(self.folder_path+'/script')
...@@ -49,24 +79,85 @@ class TestFunctional(ZopeTestCase.Functional, ZopeTestCase.ZopeTestCase): ...@@ -49,24 +79,85 @@ class TestFunctional(ZopeTestCase.Functional, ZopeTestCase.ZopeTestCase):
self.assertEqual(response.getStatus(), 500) self.assertEqual(response.getStatus(), 500)
def testUnauthorized(self): def testUnauthorized(self):
self.folder.index_html.manage_permission('View', ['Owner']) response = self.publish(self.folder_path+'/secret_html')
response = self.publish(self.folder_path+'/index_html')
self.assertEqual(response.getStatus(), 401) self.assertEqual(response.getStatus(), 401)
def testBasicAuthentication(self): def testBasicAuth(self):
self.folder.index_html.manage_permission('View', ['Owner']) response = self.publish(self.folder_path+'/secret_html', self.basic_auth)
response = self.publish(self.folder_path+'/index_html', self.assertEqual(response.getStatus(), 200)
self.basic_auth) self.assertEqual(response.getBody(), 'secret')
def testRedirect(self):
response = self.publish(self.folder_path+'/redirect')
self.assertEqual(response.getStatus(), 302)
self.assertEqual(response.getHeader('Location'), self.app.absolute_url())
def testCookie(self):
response = self.publish(self.folder_path+'/set_cookie')
self.assertEqual(response.getStatus(), 200) self.assertEqual(response.getStatus(), 200)
self.assertEqual(response.getBody(), 'foo') self.assertEqual(response.getCookie('foo').get('value'), 'Bar')
self.assertEqual(response.getCookie('foo').get('path'), '/')
def testModifyObject(self): def testChangeTitle(self):
from AccessControl.Permissions import manage_properties # Change the title of a document
self.setPermissions([manage_properties]) self.setPermissions([manage_properties])
response = self.publish(self.folder_path+'/object/change_title?title=Foo',
# Note that we must pass basic auth info
response = self.publish(self.folder_path+'/index_html/change_title?title=Foo',
self.basic_auth) self.basic_auth)
self.assertEqual(response.getStatus(), 200) self.assertEqual(response.getStatus(), 200)
self.assertEqual(self.folder.object.title_or_id(), 'Foo') self.assertEqual(self.folder.index_html.title_or_id(), 'Foo')
def testPOST(self):
# Change the title in a POST request
self.setPermissions([manage_properties])
form = {'title': 'Foo'}
post_data = StringIO(urlencode(form))
response = self.publish(self.folder_path+'/index_html/change_title',
request_method='POST', stdin=post_data,
basic=self.basic_auth)
self.assertEqual(response.getStatus(), 200)
self.assertEqual(self.folder.index_html.title_or_id(), 'Foo')
def testPUTExisting(self):
# FTP new data into an existing object
self.setPermissions([change_dtml_documents])
put_data = StringIO('foo')
response = self.publish(self.folder_path+'/index_html',
request_method='PUT', stdin=put_data,
basic=self.basic_auth)
self.assertEqual(response.getStatus(), 204)
self.assertEqual(self.folder.index_html(), 'foo')
def testPUTNew(self):
# Create a new object via FTP or WebDAV
self.setPermissions([add_documents_images_and_files])
put_data = StringIO('foo')
response = self.publish(self.folder_path+'/new_document',
env={'CONTENT_TYPE': 'text/html'},
request_method='PUT', stdin=put_data,
basic=self.basic_auth)
self.assertEqual(response.getStatus(), 201)
self.failUnless('new_document' in self.folder.objectIds())
self.assertEqual(self.folder.new_document.meta_type, 'DTML Document')
self.assertEqual(self.folder.new_document(), 'foo')
def testSecurityContext(self):
# The authenticated user should not change as a result of publish
self.assertEqual(getSecurityManager().getUser().getId(), user_name)
self.folder.acl_users.userFolderAddUser('barney', 'secret', [], [])
response = self.publish(self.folder_path, basic='barney:secret')
self.assertEqual(getSecurityManager().getUser().getId(), user_name)
def test_suite(): def test_suite():
......
#
# Interface tests
#
# $Id: testInterfaces.py,v 1.3 2005/01/01 20:38:16 shh42 Exp $
import os, sys
if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py'))
from Testing import ZopeTestCase
from Testing.ZopeTestCase.interfaces import *
try:
from Interface.Verify import verifyObject
have_verify = 1
except ImportError:
print 'testInterfaces.py: The tests in this module require Zope >= 2.6'
have_verify = 0
class TestBaseTestCase(ZopeTestCase.TestCase):
_setup_fixture = 0
def testIProfiled(self):
self.failUnless(verifyObject(IProfiled, self))
def testIZopeTestCase(self):
self.failUnless(verifyObject(IZopeTestCase, self))
class TestZopeTestCase(ZopeTestCase.ZopeTestCase):
_setup_fixture = 0
def testIProfiled(self):
self.failUnless(verifyObject(IProfiled, self))
def testIZopeTestCase(self):
self.failUnless(verifyObject(IZopeTestCase, self))
def testIZopeSecurity(self):
self.failUnless(verifyObject(IZopeSecurity, self))
class TestFunctionalTestCase(ZopeTestCase.FunctionalTestCase):
_setup_fixture = 0
def testIFunctional(self):
self.failUnless(verifyObject(IFunctional, self))
def testIProfiled(self):
self.failUnless(verifyObject(IProfiled, self))
def testIZopeTestCase(self):
self.failUnless(verifyObject(IZopeTestCase, self))
def testIZopeSecurity(self):
self.failUnless(verifyObject(IZopeSecurity, self))
class TestPortalTestCase(ZopeTestCase.PortalTestCase):
_configure_portal = 0
def getPortal(self):
return None
def testIProfiled(self):
self.failUnless(verifyObject(IProfiled, self))
def testIZopeTestCase(self):
self.failUnless(verifyObject(IZopeTestCase, self))
def testIZopeSecurity(self):
self.failUnless(verifyObject(IZopeSecurity, self))
def testIPortalTestCase(self):
self.failUnless(verifyObject(IPortalTestCase, self))
def testIPortalSecurity(self):
self.failUnless(verifyObject(IPortalSecurity, self))
def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()
if have_verify:
suite.addTest(makeSuite(TestBaseTestCase))
suite.addTest(makeSuite(TestZopeTestCase))
suite.addTest(makeSuite(TestFunctionalTestCase))
suite.addTest(makeSuite(TestPortalTestCase))
return suite
if __name__ == '__main__':
framework()
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
# way of getting started. # way of getting started.
# #
# $Id: testPortalTestCase.py,v 1.24 2004/09/09 18:48:59 shh42 Exp $ # $Id: testPortalTestCase.py,v 1.30 2005/01/30 14:22:48 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -20,7 +20,8 @@ from Testing import ZopeTestCase ...@@ -20,7 +20,8 @@ from Testing import ZopeTestCase
from Acquisition import aq_base from Acquisition import aq_base
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from types import ListType from types import ListType
from transaction import begin
import transaction
portal_name = 'dummy_1_' portal_name = 'dummy_1_'
user_name = ZopeTestCase.user_name user_name = ZopeTestCase.user_name
...@@ -33,28 +34,28 @@ def hasattr_(ob, attr): ...@@ -33,28 +34,28 @@ def hasattr_(ob, attr):
# Dummy Portal # Dummy Portal
from OFS.SimpleItem import SimpleItem from OFS.SimpleItem import SimpleItem
from OFS.Folder import Folder from OFS.Folder import Folder
class DummyMembershipTool(SimpleItem):
id = 'portal_membership'
def createMemberarea(self, member_id):
portal = self.aq_inner.aq_parent
portal.Members.manage_addFolder(member_id)
def getHomeFolder(self, member_id):
portal = self.aq_inner.aq_parent
return portal.Members[member_id]
class DummyPortal(Folder): class DummyPortal(Folder):
_v_skindata = None _v_skindata = None
def __init__(self, id): def __init__(self, id):
self.id = id self.id = id
self._addRole('Member') self._addRole('Member')
self._setObject('portal_membership', DummyMembershipTool()) self._setObject('portal_membership', DummyMembershipTool())
self.manage_addFolder('Members') self.manage_addFolder('Members')
def setupCurrentSkin(self): def setupCurrentSkin(self):
if self._v_skindata is None: if self._v_skindata is None:
self._v_skindata = 'refreshed' self._v_skindata = 'refreshed'
class DummyMembershipTool(SimpleItem):
id = 'portal_membership'
def createMemberarea(self, member_id):
portal = self.aq_inner.aq_parent
portal.Members.manage_addFolder(member_id)
def getHomeFolder(self, member_id):
portal = self.aq_inner.aq_parent
return portal.Members[member_id]
class TestPortalTestCase(ZopeTestCase.PortalTestCase): class TestPortalTestCase(ZopeTestCase.PortalTestCase):
'''Incrementally exercise the PortalTestCase API.''' '''Incrementally exercise the PortalTestCase API.'''
...@@ -63,6 +64,7 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase): ...@@ -63,6 +64,7 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase):
_tearDown = ZopeTestCase.PortalTestCase.tearDown _tearDown = ZopeTestCase.PortalTestCase.tearDown
def getPortal(self): def getPortal(self):
# Must make sure we return a portal object
self.app._setObject(portal_name, DummyPortal(portal_name)) self.app._setObject(portal_name, DummyPortal(portal_name))
return self.app[portal_name] return self.app[portal_name]
...@@ -71,7 +73,7 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase): ...@@ -71,7 +73,7 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase):
# with an empty fixture. # with an empty fixture.
self._called = [] self._called = []
# Implicitly aborts previous transaction # Implicitly aborts previous transaction
begin() transaction.begin()
def beforeSetUp(self): def beforeSetUp(self):
self._called.append('beforeSetUp') self._called.append('beforeSetUp')
...@@ -176,32 +178,33 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase): ...@@ -176,32 +178,33 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase):
acl_user = self.portal.acl_users.getUserById('user_2') acl_user = self.portal.acl_users.getUserById('user_2')
self.assertRolesOfUser(test_roles, acl_user) self.assertRolesOfUser(test_roles, acl_user)
def test_setRolesAssertsArgumentType(self): def test_setRoles_4(self):
# setRoles should fail if 'roles' argument is not a list # Roles should be set from a tuple
self.assertRaises(self.failureException, self.setRoles, 'foo')
self.assertRaises(self.failureException, self.setRoles, ('foo',))
def test_getRoles(self):
# Should return roles of user
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
self._setupUserFolder() self._setupUserFolder()
self._setupUser() self._setupUser()
self.assertEqual(self.getRoles(), ('Member', 'Authenticated')) test_roles = ['Manager', 'Member']
self.setRoles(tuple(test_roles))
acl_user = self.portal.acl_users.getUserById(user_name)
self.assertRolesOfUser(test_roles, acl_user)
def test_getRoles_2(self): def test_setRoles_5(self):
# Should return roles of specified user # Roles should be set from a string
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
self._setupUserFolder() self._setupUserFolder()
self.portal.acl_users.userFolderAddUser('user_2', 'secret', ['Manager'], []) self._setupUser()
self.assertEqual(self.getRoles('user_2'), ('Manager', 'Authenticated')) test_roles = ['Manager']
self.setRoles('Manager')
acl_user = self.portal.acl_users.getUserById(user_name)
self.assertRolesOfUser(test_roles, acl_user)
def test_setPermissions(self): def test_setPermissions(self):
# Permissions should be set for user # Permissions should be set for user
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
test_perms = ['Add Folders'] test_perms = ['Add Folders', 'Delete objects']
self.setPermissions(test_perms) self.setPermissions(test_perms)
self.assertPermissionsOfRole(test_perms, 'Member') self.assertPermissionsOfRole(test_perms, 'Member')
...@@ -210,32 +213,26 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase): ...@@ -210,32 +213,26 @@ class TestPortalTestCase(ZopeTestCase.PortalTestCase):
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
self.portal._addRole('role_2') self.portal._addRole('role_2')
test_perms = ['Add Folders'] test_perms = ['Add Folders', 'Delete objects']
self.assertPermissionsOfRole([], 'role_2') self.assertPermissionsOfRole([], 'role_2')
self.setPermissions(test_perms, 'role_2') self.setPermissions(test_perms, 'role_2')
self.assertPermissionsOfRole(test_perms, 'role_2') self.assertPermissionsOfRole(test_perms, 'role_2')
def test_setPermissionsAssertsArgumentType(self): def test_setPermissions_3(self):
# setPermissions should fail if 'permissions' argument is not a list # Permissions should be set from a tuple
self.assertRaises(self.failureException, self.setPermissions, 'foo')
self.assertRaises(self.failureException, self.setPermissions, ('foo',))
def test_getPermissions(self):
# Should return permissions of user
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
test_perms = ['Add Folders'] test_perms = ['Add Folders', 'Delete objects']
self.setPermissions(test_perms) self.setPermissions(tuple(test_perms))
self.assertEqual(self.getPermissions(), test_perms) self.assertPermissionsOfRole(test_perms, 'Member')
def test_getPermissions_2(self): def test_setPermissions_4(self):
# Should return permissions of specified role # Permissions should be set from a string
self.app = self._app() self.app = self._app()
self.portal = self.getPortal() self.portal = self.getPortal()
test_perms = ['Add Folders'] test_perms = ['Add Folders']
self.portal._addRole('role_2') self.setPermissions('Add Folders')
self.setPermissions(test_perms, 'role_2') self.assertPermissionsOfRole(test_perms, 'Member')
self.assertEqual(self.getPermissions('role_2'), test_perms)
def test_login(self): def test_login(self):
# User should be able to log in # User should be able to log in
...@@ -471,19 +468,19 @@ class HookTest(ZopeTestCase.PortalTestCase): ...@@ -471,19 +468,19 @@ class HookTest(ZopeTestCase.PortalTestCase):
def setUp(self): def setUp(self):
self._called = [] self._called = []
ZopeTestCase.PortalTestCase.setUp(self) ZopeTestCase.PortalTestCase.setUp(self)
def beforeSetUp(self): def beforeSetUp(self):
self._called.append('beforeSetUp') self._called.append('beforeSetUp')
ZopeTestCase.PortalTestCase.beforeSetUp(self) ZopeTestCase.PortalTestCase.beforeSetUp(self)
def _setup(self): def _setup(self):
self._called.append('_setup') self._called.append('_setup')
ZopeTestCase.PortalTestCase._setup(self) ZopeTestCase.PortalTestCase._setup(self)
def afterClear(self): def afterClear(self):
self._called.append('afterClear') self._called.append('afterClear')
ZopeTestCase.PortalTestCase.afterClear(self) ZopeTestCase.PortalTestCase.afterClear(self)
def assertHooks(self, sequence): def assertHooks(self, sequence):
self.assertEqual(self._called, sequence) self.assertEqual(self._called, sequence)
...@@ -504,11 +501,11 @@ class TestSetUpRaises(HookTest): ...@@ -504,11 +501,11 @@ class TestSetUpRaises(HookTest):
# Connection has been closed # Connection has been closed
from Testing.ZopeTestCase import base from Testing.ZopeTestCase import base
self.assertEqual(len(base._connections), 0) self.assertEqual(len(base._connections), 0)
def _setup(self): def _setup(self):
HookTest._setup(self) HookTest._setup(self)
raise self.Error raise self.Error
def testTrigger(self): def testTrigger(self):
pass pass
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
# Handy for debugging and tracing your tests. # Handy for debugging and tracing your tests.
# #
# $Id: testShoppingCart.py,v 1.10 2004/04/09 12:38:37 shh42 Exp $ # $Id: testShoppingCart.py,v 1.11 2005/02/23 17:14:56 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -24,93 +24,83 @@ examples_path = os.path.join(SOFTWARE_HOME, '..', '..', 'import', 'Examples.zexp ...@@ -24,93 +24,83 @@ examples_path = os.path.join(SOFTWARE_HOME, '..', '..', 'import', 'Examples.zexp
examples_path = os.path.abspath(examples_path) examples_path = os.path.abspath(examples_path)
if not ZopeTestCase.hasProduct('TemporaryFolder'): # Open ZODB connection
app = ZopeTestCase.app()
print 'testShoppingCart.py: The tests in this module require Zope >= 2.5' # Set up sessioning objects
ZopeTestCase.utils.setupCoreSessions(app)
elif not os.path.isfile(examples_path): # Set up example applications
if not hasattr(app, 'Examples'):
ZopeTestCase.utils.importObjectFromFile(app, examples_path)
print "testShoppingCart.py: Cannot find file '%s'" % examples_path # Close ZODB connection
ZopeTestCase.close(app)
else:
# Open ZODB connection class DummyOrder:
app = ZopeTestCase.app() '''Construct an order we can add to the cart'''
__allow_access_to_unprotected_subobjects__ = 1
# Set up sessioning objects def __init__(self, id, quantity):
ZopeTestCase.utils.setupCoreSessions(app) self.id = id
self.quantity = quantity
# Set up example applications
if not hasattr(app, 'Examples'):
ZopeTestCase.utils.importObjectFromFile(app, examples_path)
# Close ZODB connection class TestShoppingCart(ZopeTestCase.ZopeTestCase):
ZopeTestCase.close(app) '''Test the ShoppingCart example application'''
_setup_fixture = 0 # No default fixture
class DummyOrder: def afterSetUp(self):
'''Construct an order we can add to the cart''' self.cart = self.app.Examples.ShoppingCart
__allow_access_to_unprotected_subobjects__ = 1 # Put SESSION object into REQUEST
request = self.app.REQUEST
sdm = self.app.session_data_manager
request.set('SESSION', sdm.getSessionData())
self.session = request.SESSION
def __init__(self, id, quantity): def testSession(self):
self.id = id # Session should work
self.quantity = quantity self.session.set('boring', 'boring')
self.assertEqual(self.session.get('boring'), 'boring')
def testCartIsEmpty(self):
# Cart should be empty
self.assertEqual(len(self.cart.currentItems()), 0)
class TestShoppingCart(ZopeTestCase.ZopeTestCase): def testAddItems(self):
'''Test the ShoppingCart example application''' # Adding to the cart should work
self.cart.addItems([DummyOrder('510-115', 1),])
self.assertEqual(len(self.cart.currentItems()), 1)
_setup_fixture = 0 # No default fixture def testDeleteItems(self):
# Deleting from the cart should work
self.cart.addItems([DummyOrder('510-115', 1),])
self.cart.deleteItems(['510-115'])
self.assertEqual(len(self.cart.currentItems()), 0)
def afterSetUp(self): def testAddQuantity(self):
self.cart = self.app.Examples.ShoppingCart # Adding to quantity should work
# Put SESSION object into REQUEST self.cart.addItems([DummyOrder('510-115', 1),])
request = self.app.REQUEST self.cart.addItems([DummyOrder('510-115', 2),])
sdm = self.app.session_data_manager self.cart.addItems([DummyOrder('510-115', 3),])
request.set('SESSION', sdm.getSessionData()) self.assertEqual(self.cart.currentItems()[0]['quantity'], 6)
self.session = request.SESSION
def testSession(self): def testGetTotal(self):
# Session should work # Totals should be computed correctly
self.session.set('boring', 'boring') self.cart.addItems([DummyOrder('510-115', 1),])
self.assertEqual(self.session.get('boring'), 'boring') self.cart.addItems([DummyOrder('510-122', 2),])
self.cart.addItems([DummyOrder('510-007', 2),])
self.assertEqual(self.cart.getTotal(), 149.95)
def testCartIsEmpty(self):
# Cart should be empty
self.assertEqual(len(self.cart.currentItems()), 0)
def testAddItems(self): def test_suite():
# Adding to the cart should work from unittest import TestSuite, makeSuite
self.cart.addItems([DummyOrder('510-115', 1),]) suite = TestSuite()
self.assertEqual(len(self.cart.currentItems()), 1) suite.addTest(makeSuite(TestShoppingCart))
return suite
def testDeleteItems(self): if __name__ == '__main__':
# Deleting from the cart should work framework()
self.cart.addItems([DummyOrder('510-115', 1),])
self.cart.deleteItems(['510-115'])
self.assertEqual(len(self.cart.currentItems()), 0)
def testAddQuantity(self):
# Adding to quantity should work
self.cart.addItems([DummyOrder('510-115', 1),])
self.cart.addItems([DummyOrder('510-115', 2),])
self.cart.addItems([DummyOrder('510-115', 3),])
self.assertEqual(self.cart.currentItems()[0]['quantity'], 6)
def testGetTotal(self):
# Totals should be computed correctly
self.cart.addItems([DummyOrder('510-115', 1),])
self.cart.addItems([DummyOrder('510-122', 2),])
self.cart.addItems([DummyOrder('510-007', 2),])
self.assertEqual(self.cart.getTotal(), 149.95)
def test_suite():
from unittest import TestSuite, makeSuite
suite = TestSuite()
suite.addTest(makeSuite(TestShoppingCart))
return suite
if __name__ == '__main__':
framework()
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# example instead. # example instead.
# #
# $Id: testWebserver.py,v 1.15 2004/09/04 18:01:08 shh42 Exp $ # $Id: testWebserver.py,v 1.16 2005/02/12 13:11:10 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -54,23 +54,22 @@ class TestWebserver(ZopeTestCase.ZopeTestCase): ...@@ -54,23 +54,22 @@ class TestWebserver(ZopeTestCase.ZopeTestCase):
def afterSetUp(self): def afterSetUp(self):
uf = self.folder.acl_users uf = self.folder.acl_users
uf.userFolderAddUser('manager', 'secret', ['Manager'], []) uf.userFolderAddUser('manager', 'secret', ['Manager'], [])
manager = uf.getUserById('manager').__of__(uf)
self.folder.addDTMLMethod('index_html', file='index_html called') # A simple document
self.folder.addDTMLMethod('secret_html', file='secret_html called') self.folder.addDTMLDocument('index_html', file='index_html called')
self.folder.manage_addFolder('object', '')
# A document only accessible to manager
self.folder.addDTMLDocument('secret_html', file='secret_html called')
for p in ZopeTestCase.standard_permissions: for p in ZopeTestCase.standard_permissions:
self.folder.secret_html.manage_permission(p, ['Manager'], acquire=0) self.folder.secret_html.manage_permission(p, ['Manager'])
self.folder.addDTMLMethod('object_ids', file='<dtml-var objectIds>') # A method to change the title property of an object
self.folder.addDTMLMethod('user_ids', file='<dtml-var "acl_users.getUserNames()">')
self.folder.addDTMLMethod('change_title', self.folder.addDTMLMethod('change_title',
file='''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">''' file='''<dtml-call "manage_changeProperties(title=REQUEST.get('title'))">'''
'''<dtml-var title_or_id>''') '''<dtml-var title_or_id>''')
self.folder.object_ids.changeOwnership(manager) manager = uf.getUserById('manager').__of__(uf)
self.folder.user_ids.changeOwnership(manager)
self.folder.change_title.changeOwnership(manager) self.folder.change_title.changeOwnership(manager)
# Commit so the ZServer threads can see the changes # Commit so the ZServer threads can see the changes
...@@ -142,15 +141,15 @@ class TestWebserver(ZopeTestCase.ZopeTestCase): ...@@ -142,15 +141,15 @@ class TestWebserver(ZopeTestCase.ZopeTestCase):
# Test a script that modifies the ZODB # Test a script that modifies the ZODB
self.setRoles(['Manager']) self.setRoles(['Manager'])
self.app.REQUEST.set('title', 'Foo') self.app.REQUEST.set('title', 'Foo')
page = self.folder.object.change_title(self.folder.object, page = self.folder.index_html.change_title(self.folder.index_html,
self.app.REQUEST) self.app.REQUEST)
self.assertEqual(page, 'Foo') self.assertEqual(page, 'Foo')
self.assertEqual(self.folder.object.title, 'Foo') self.assertEqual(self.folder.index_html.title, 'Foo')
def testURLModifyObject(self): def testURLModifyObject(self):
# Test a transaction that actually commits something # Test a transaction that actually commits something
urllib._urlopener = ManagementOpener() urllib._urlopener = ManagementOpener()
page = urllib.urlopen(folder_url+'/object/change_title?title=Foo').read() page = urllib.urlopen(folder_url+'/index_html/change_title?title=Foo').read()
self.assertEqual(page, 'Foo') self.assertEqual(page, 'Foo')
def testAbsoluteURL(self): def testAbsoluteURL(self):
...@@ -169,10 +168,10 @@ class TestSandboxedWebserver(ZopeTestCase.Sandboxed, TestWebserver): ...@@ -169,10 +168,10 @@ class TestSandboxedWebserver(ZopeTestCase.Sandboxed, TestWebserver):
def testConnectionIsShared(self): def testConnectionIsShared(self):
# Due to sandboxing the ZServer thread operates on the # Due to sandboxing the ZServer thread operates on the
# same connection as the main thread, allowing us to # same connection as the main thread, allowing us to
# see changes made to 'object' right away. # see changes made to 'index_html' right away.
urllib._urlopener = ManagementOpener() urllib._urlopener = ManagementOpener()
urllib.urlopen(folder_url+'/object/change_title?title=Foo') urllib.urlopen(folder_url+'/index_html/change_title?title=Foo')
self.assertEqual(self.folder.object.title, 'Foo') self.assertEqual(self.folder.index_html.title, 'Foo')
def testCanCommit(self): def testCanCommit(self):
# Additionally, it allows us to commit transactions without # Additionally, it allows us to commit transactions without
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
# way of getting started. # way of getting started.
# #
# $Id: testZopeTestCase.py,v 1.21 2004/09/04 18:01:08 shh42 Exp $ # $Id: testZopeTestCase.py,v 1.25 2005/01/30 14:22:48 shh42 Exp $
import os, sys import os, sys
if __name__ == '__main__': if __name__ == '__main__':
...@@ -20,7 +20,8 @@ from Testing import ZopeTestCase ...@@ -20,7 +20,8 @@ from Testing import ZopeTestCase
from Acquisition import aq_base from Acquisition import aq_base
from AccessControl import getSecurityManager from AccessControl import getSecurityManager
from types import ListType from types import ListType
from transaction import begin
import transaction
folder_name = ZopeTestCase.folder_name folder_name = ZopeTestCase.folder_name
user_name = ZopeTestCase.user_name user_name = ZopeTestCase.user_name
...@@ -43,7 +44,7 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase): ...@@ -43,7 +44,7 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase):
# with an empty fixture. # with an empty fixture.
self._called = [] self._called = []
# Implicitly aborts previous transaction # Implicitly aborts previous transaction
begin() transaction.begin()
def beforeSetUp(self): def beforeSetUp(self):
self._called.append('beforeSetUp') self._called.append('beforeSetUp')
...@@ -121,32 +122,33 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase): ...@@ -121,32 +122,33 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase):
acl_user = self.folder.acl_users.getUserById('user_2') acl_user = self.folder.acl_users.getUserById('user_2')
self.assertRolesOfUser(test_roles, acl_user) self.assertRolesOfUser(test_roles, acl_user)
def test_setRolesAssertsArgumentType(self): def test_setRoles_4(self):
# setRoles should fail if 'roles' argument is not a list # Roles should be set from a tuple
self.assertRaises(self.failureException, self.setRoles, 'foo')
self.assertRaises(self.failureException, self.setRoles, ('foo',))
def test_getRoles(self):
# Should return roles of user
self.app = self._app() self.app = self._app()
self._setupFolder() self._setupFolder()
self._setupUserFolder() self._setupUserFolder()
self._setupUser() self._setupUser()
self.assertEqual(self.getRoles(), (user_role, 'Authenticated')) test_roles = ['Manager', user_role]
self.setRoles(tuple(test_roles))
acl_user = self.folder.acl_users.getUserById(user_name)
self.assertRolesOfUser(test_roles, acl_user)
def test_getRoles_2(self): def test_setRoles_5(self):
# Should return roles of specified user # Roles should be set from a string
self.app = self._app() self.app = self._app()
self._setupFolder() self._setupFolder()
self._setupUserFolder() self._setupUserFolder()
self.folder.acl_users.userFolderAddUser('user_2', 'secret', ['Manager'], []) self._setupUser()
self.assertEqual(self.getRoles('user_2'), ('Manager', 'Authenticated')) test_roles = ['Manager']
self.setRoles('Manager')
acl_user = self.folder.acl_users.getUserById(user_name)
self.assertRolesOfUser(test_roles, acl_user)
def test_setPermissions(self): def test_setPermissions(self):
# Permissions should be set for user # Permissions should be set for user
self.app = self._app() self.app = self._app()
self._setupFolder() self._setupFolder()
test_perms = ['Add Folders'] test_perms = ['Add Folders', 'Delete objects']
self.assertPermissionsOfRole(standard_permissions, user_role) self.assertPermissionsOfRole(standard_permissions, user_role)
self.setPermissions(test_perms) self.setPermissions(test_perms)
self.assertPermissionsOfRole(test_perms, user_role) self.assertPermissionsOfRole(test_perms, user_role)
...@@ -160,25 +162,23 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase): ...@@ -160,25 +162,23 @@ class TestZopeTestCase(ZopeTestCase.ZopeTestCase):
self.setPermissions(standard_permissions, 'role_2') self.setPermissions(standard_permissions, 'role_2')
self.assertPermissionsOfRole(standard_permissions, 'role_2') self.assertPermissionsOfRole(standard_permissions, 'role_2')
def test_setPermissionsAssertsArgumentType(self): def test_setPermissions_3(self):
# setPermissions should fail if 'permissions' argument is not a list # Permissions should be set from a tuple
self.assertRaises(self.failureException, self.setPermissions, 'foo')
self.assertRaises(self.failureException, self.setPermissions, ('foo',))
def test_getPermissions(self):
# Should return permissions of user
self.app = self._app() self.app = self._app()
self._setupFolder() self._setupFolder()
self.assertEqual(self.getPermissions(), standard_permissions) test_perms = ['Add Folders', 'Delete objects']
self.assertPermissionsOfRole(standard_permissions, user_role)
self.setPermissions(tuple(test_perms))
self.assertPermissionsOfRole(test_perms, user_role)
def test_getPermissions_2(self): def test_setPermissions_4(self):
# Should return permissions of specified role # Permissions should be set from a comma separated string
self.app = self._app() self.app = self._app()
self._setupFolder() self._setupFolder()
test_perms = ['Add Folders'] test_perms = ['Add Folders']
self.folder._addRole('role_2') self.assertPermissionsOfRole(standard_permissions, user_role)
self.setPermissions(test_perms, 'role_2') self.setPermissions('Add Folders')
self.assertEqual(self.getPermissions('role_2'), test_perms) self.assertPermissionsOfRole(test_perms, user_role)
def test_login(self): def test_login(self):
# User should be able to log in # User should be able to log in
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# module level to add functionality to the test environment. # module level to add functionality to the test environment.
# #
# $Id: utils.py,v 1.16 2004/08/19 13:59:41 shh42 Exp $ # $Id: utils.py,v 1.21 2005/02/11 09:00:21 shh42 Exp $
def setupCoreSessions(app=None): def setupCoreSessions(app=None):
...@@ -137,6 +137,19 @@ def appcall(function, *args, **kw): ...@@ -137,6 +137,19 @@ def appcall(function, *args, **kw):
close(app) close(app)
def makelist(arg):
'''Turns arg into a list. Where arg may be
list, tuple, or string.
'''
if type(arg) == type([]):
return arg
if type(arg) == type(()):
return list(arg)
if type(arg) == type(''):
return filter(None, [arg])
raise ValueError('Argument must be list, tuple, or string')
class ConnectionRegistry: class ConnectionRegistry:
'''ZODB connection registry''' '''ZODB connection registry'''
...@@ -164,3 +177,13 @@ class ConnectionRegistry: ...@@ -164,3 +177,13 @@ class ConnectionRegistry:
def contains(self, conn): def contains(self, conn):
return conn in self._conns return conn in self._conns
__all__ = [
'setupCoreSessions',
'setupSiteErrorLog',
'setupZGlobals',
'startZServer',
'importObjectFromFile',
'appcall',
]
##############################################################################
#
# Copyright (c) 2004 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import warnings
class WarningsHook:
"""Hook to capture warnings generated by Python.
The function warnings.showwarning() is designed to be hooked by
application code, allowing the application to customize the way it
handles warnings.
This hook captures the unformatted warning information and stored
it in a list. A test can inspect this list after the test is over.
Issues:
The warnings module has lots of delicate internal state. If
a warning has been reported once, it won't be reported again. It
may be necessary to extend this class with a mechanism for
modifying the internal state so that we can be guaranteed a
warning will be reported.
If Python is run with a warnings filter, e.g. python -Werror,
then a test that is trying to inspect a particular warning will
fail. Perhaps this class can be extended to install more-specific
filters the test to work anyway.
"""
def __init__(self):
self.original = None
self.warnings = []
def install(self):
self.original = warnings.showwarning
warnings.showwarning = self.showwarning
def uninstall(self):
assert self.original is not None
warnings.showwarning = self.original
self.original = None
def showwarning(self, message, category, filename, lineno):
self.warnings.append((str(message), category, filename, lineno))
def clear(self):
self.warnings = []
#
# ZopeTestCase public interface
#
# $Id: __init__.py,v 1.1 2005/02/25 11:01:07 shh42 Exp $
__version__ = '0.9.6'
import Testing.ZopeTestCase
__path__.extend(Testing.ZopeTestCase.__path__)
from Testing.ZopeTestCase import *
from Testing.ZopeTestCase.utils import *
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment