Skip to content

Commit

Permalink
100% coverage for testing.py
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Sep 12, 2017
1 parent 2aa89d3 commit 0c6752c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 48 deletions.
5 changes: 4 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@

- Fix the pure-Python proxy calling a wrapped ``__getattr__`` or
``__getattribute__`` more than once in situations where the C
implementation only called it one time (when it raised an AttributeError).
implementation only called it one time (when it raised an
AttributeError).

- Reach 100% test coverage and maintain it via automated checks.

4.1.1 (2017-05-17)
==================
Expand Down
8 changes: 2 additions & 6 deletions src/zope/security/management.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def newInteraction(*participations):
"""Start a new interaction."""
if queryInteraction() is not None:
raise ExistingInteraction("newInteraction called"
" while another interaction is active.")
" while another interaction is active.")
thread_local.interaction = getSecurityPolicy()(*participations)

def endInteraction():
Expand Down Expand Up @@ -134,13 +134,9 @@ def _clear():
global _defaultPolicy
_defaultPolicy = ParanoidSecurityPolicy

# XXX This code is used to support automated testing. However, it shouldn't be
# here and needs to be refactored. The empty addCleanUp-method is a temporary
# workaround to fix packages that depend on zope.security but don't have a
# need for zope.testing.
try:
from zope.testing.cleanup import addCleanUp
except ImportError: #pragma NO COVER
except ImportError: # pragma: no cover
pass
else:
addCleanUp(_clear)
Expand Down
45 changes: 21 additions & 24 deletions src/zope/security/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,28 @@
This module provides some helper/stub objects for setting up interactions.
"""
import sys
import contextlib
import re

from zope import interface, component

from zope.security import interfaces
from zope.security.permission import Permission
import contextlib
import zope.security.management
from zope.security._compat import PYTHON2 as PY2

from zope.testing import renormalizing

PY2 = sys.version_info[0] == 2

if PY2:
_u = unicode
rules = [(re.compile("b('.*?')"), r"\1"),
(re.compile('b(".*?")'), r"\1"),
]
output_checker = renormalizing.RENormalizing(rules)
else:
_u = str
rules = [(re.compile("u('.*?')"), r"\1"),
(re.compile('u(".*?")'), r"\1"),
]
output_checker = renormalizing.RENormalizing(rules)
_str_prefix = 'b' if PY2 else 'u'

rules = [
(re.compile(_str_prefix + "('.*?')"), r"\1"),
(re.compile(_str_prefix + '(".*?")'), r"\1"),
]
output_checker = renormalizing.RENormalizing(rules)

@interface.implementer(interfaces.IPrincipal)
class Principal:
class Principal(object):

def __init__(self, id, title=None, description='', groups=None):
self.id = id
Expand All @@ -53,7 +48,7 @@ def __init__(self, id, title=None, description='', groups=None):


@interface.implementer(interfaces.IParticipation)
class Participation:
class Participation(object):

def __init__(self, principal):
self.principal = principal
Expand All @@ -63,16 +58,18 @@ def __init__(self, principal):
def addCheckerPublic():
"""Add the CheckerPublic permission as 'zope.Public'"""

perm = Permission('zope.Public', 'Public',
"""Special permission used for resources that are always public
perm = Permission(
'zope.Public', 'Public',
"""Special permission used for resources that are always public
The public permission is effectively an optimization, sine
it allows security computation to be bypassed.
"""
)
The public permission is effectively an optimization, sine
it allows security computation to be bypassed.
"""
)
gsm = component.getGlobalSiteManager()
gsm.registerUtility(perm, interfaces.IPermission, perm.id)

return perm

def create_interaction(principal_id, **kw):
principal = Principal(principal_id, **kw)
Expand Down
6 changes: 6 additions & 0 deletions src/zope/security/tests/test_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,12 @@ def test__ge__(self):
proxy = self._makeOne(target, checker)
self.assertTrue(proxy >= 1)

def test__gt__(self):
target = 1
checker = object() # checker not consulted
proxy = self._makeOne(target, checker)
self.assertTrue(proxy > 0)

def test___hash___w_self(self):
target = object()
checker = object() # checker not consulted
Expand Down
48 changes: 32 additions & 16 deletions src/zope/security/tests/test_testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@
##############################################################################
import unittest

from zope.testing.cleanup import CleanUp

class InteractionHelperTest(unittest.TestCase):
from zope.security import testing

def tearDown(self):
from zope.security.management import endInteraction
endInteraction()
class TestTestingFunctions(CleanUp,
unittest.TestCase):

def test_create_interaction_should_return_principal(self):
from zope.security.management import getInteraction
from zope.security.testing import create_interaction
principal = create_interaction(

principal = testing.create_interaction(
'foo', groups=['bar'], description='desc')
ix = getInteraction()
participation = ix.participations[0]
Expand All @@ -34,25 +34,41 @@ def test_create_interaction_should_return_principal(self):
def test_usable_as_contextmanager(self):
from zope.security.management import getInteraction
from zope.security.management import queryInteraction
from zope.security.testing import interaction
with interaction('foo'):

with testing.interaction('foo'):
ix = getInteraction()
participation = ix.participations[0]
self.assertEqual('foo', participation.principal.id)
# Nesting doesn't change anything
with testing.interaction('baz'):
ix = getInteraction()
participation = ix.participations[0]
self.assertEqual('foo', participation.principal.id)

self.assertFalse(queryInteraction())

def test_contextmanager_ends_interaction_on_exception(self):
from zope.security.management import queryInteraction
from zope.security.testing import interaction
try:
with interaction('foo'):
raise RuntimeError()
except RuntimeError:
class MyError(Exception):
pass

with self.assertRaises(MyError):
with testing.interaction('foo'):
raise MyError()

self.assertFalse(queryInteraction())


def test_addCheckerPublic(self):
from zope import component
from zope.security.interfaces import IPermission

perm = testing.addCheckerPublic()
utility = component.getUtility(IPermission, name='zope.Public')
self.assertIs(perm, utility)




def test_suite():
return unittest.TestSuite((
unittest.makeSuite(InteractionHelperTest),
))
return unittest.defaultTestLoader.loadTestsFromName(__name__)
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ basepython =
commands =
coverage run -m zope.testrunner --test-path=src []
coverage run -a -m sphinx -b doctest -d {envdir}/.cache/doctrees docs {envdir}/.cache/doctest
coverage report --fail-under=92
coverage report --fail-under=100
deps =
{[testenv]deps}
coverage
Expand Down

0 comments on commit 0c6752c

Please sign in to comment.