[Zope3-checkins] CVS: Zope3/src/zope/app/component/tests - test_wrapper_hooks.py:1.1.2.1
Marius Gedminas
mgedmin@codeworks.lt
Wed, 14 May 2003 06:40:27 -0400
Update of /cvs-repository/Zope3/src/zope/app/component/tests
In directory cvs.zope.org:/tmp/cvs-serv2352/src/zope/app/component/tests
Added Files:
Tag: stevea-decorators-branch
test_wrapper_hooks.py
Log Message:
Unit tests for ContextWrapper hook implementation.
=== Added File Zope3/src/zope/app/component/tests/test_wrapper_hooks.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (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.
#
##############################################################################
"""Unit tests for implementation of the ContextWrapper hook.
$Id: test_wrapper_hooks.py,v 1.1.2.1 2003/05/14 10:40:26 mgedmin Exp $
"""
import unittest
from zope.app.interfaces.component import IDecoratorSpec
from zope.interface import implements
from zope.security.proxy import Proxy, getObject, getChecker
from zope.proxy.context.wrapper import getobject, getcontext, getdict
from zope.proxy.context.decorator import Decorator
from zope.proxy.context.decorator import getmixinfactory, getnames
from zope.proxy.context.decorator import getmixincreate
from zope.security.checker import ProxyFactory, NamesChecker
from zope.exceptions import ForbiddenAttribute
from zope.security.checker import DecoratedChecker
__metaclass__ = type
class DecoratorSpecStub:
implements(IDecoratorSpec)
def __init__(self, mixinIsTrusted, mixinFactory, mixinInterfaceSpec,
names, permissionMap, setPermissionMap):
self.mixinIsTrusted = mixinIsTrusted
self.mixinFactory = mixinFactory
self.mixinInterfaceSpec = mixinInterfaceSpec
self.names = names
self.permissionMap = permissionMap
self.setPermissionMap = setPermissionMap
class SomeObject:
__Security_checker__ = NamesChecker(['foo'], 'perm1')
foo = 3
bar = 4
class Mixin:
x = 1
y = 2
def __init__(self, inner, outer):
self.inner = inner
self.outer = outer
class TestDecorate(unittest.TestCase):
def test_decorate(self):
from zope.app.component.hooks import decorate
mt = True
mf = Mixin
mis = ()
n = ('x', 'y')
spec = DecoratorSpecStub(mt, mf, mis, n, {}, {})
ob = SomeObject()
parent = object()
kw = {'foo': 1, 'bar': 42}
d = decorate(spec, ob, parent, kw)
self.assert_(type(d) is Decorator)
self.assert_(getobject(d) is ob)
self.assert_(getcontext(d) is parent)
self.assertEquals(getdict(d), kw)
self.assert_(getmixinfactory(d) is mf)
self.assertEquals(getnames(d), n)
self.assert_(getmixincreate(d).inner is ob)
spec.mixinIsTrusted = True
proxied_ob = ProxyFactory(ob)
d = decorate(spec, proxied_ob, parent, kw)
self.assert_(type(d) is Proxy)
unproxied_d = getObject(d)
self.assert_(type(unproxied_d) is Decorator)
self.assert_(getmixincreate(unproxied_d).inner is ob)
# when the mixin is untrusted but ob has no proxy, it is left unproxied
spec.mixinIsTrusted = False
d = decorate(spec, ob, parent, kw)
self.assert_(getmixincreate(d).inner is ob)
spec.mixinIsTrusted = False
proxied_ob = ProxyFactory(ob)
d = decorate(spec, proxied_ob, parent, kw)
self.assert_(type(d) is Proxy)
unproxied_d = getObject(d)
self.assert_(getmixincreate(unproxied_d).inner is proxied_ob)
def test_decoratePermissions(self):
from zope.app.component.hooks import decorate
ob = SomeObject()
parent = object()
kw = {}
mt = True
mf = Mixin
mis = ()
n = ('x', 'y')
spec = DecoratorSpecStub(mt, mf, mis, n, {}, {})
# permissions:
# 1) standard case (checker + permission map); permission map
# overrides the checker
# 2) if there is no checker (the original object is not proxied),
# no proxy should be added regardless of any permission map
# 3) if the permission map is empty, the checker should be left alone
# permission map is empty, so the same checker should be reused
proxied_ob = ProxyFactory(ob)
self.assert_(type(proxied_ob) is Proxy)
d = decorate(spec, proxied_ob, parent, kw)
self.assert_(type(d) is Proxy)
self.assert_(getChecker(d) is getChecker(proxied_ob))
# no proxy should be added when there wasn't one originally
spec.permissionMap = {'x': 'perm2'}
spec.setPermissionMap = {'x': 'perm3'}
d = decorate(spec, ob, parent, kw)
self.assert_(type(d) is not Proxy)
# checkers should be combined
spec.permissionMap = {'x': 'perm2'}
spec.setPermissionMap = {'x': 'perm3'}
d = decorate(spec, proxied_ob, parent, kw)
self.assert_(type(d) is Proxy)
c = getChecker(d)
# XXX this horrible piece of code relies on the implementation too much
self.assert_(type(c) is DecoratedChecker)
self.assert_(c._original_checker is getChecker(proxied_ob))
self.assert_(c._permission_func.__self__ is spec.permissionMap)
self.assert_(c._setattr_permission_func.__self__
is spec.setPermissionMap)
## c.check_getattr(ob, 'foo')
## self.assert_(self.policy.checkChecked(['perm1']))
## self.assertRaises(ForbiddenAttribute, c.check_getattr, ob, 'bar')
## self.assert_(self.policy.checkChecked([]))
## c.check_getattr(ob, 'x')
## self.assert_(self.policy.checkChecked(['perm2']))
## self.assertRaises(ForbiddenAttribute, c.check_getattr, ob, 'y')
## self.assert_(self.policy.checkChecked([]))
## # XXX: test overlap
# XXX: test interface spec
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestDecorate))
return suite
if __name__ == '__main__':
unittest.main()