[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()