# -*- coding: utf-8 -*- import unittest from pyramid.testing import cleanUp from pyramid.compat import text_, native_, text_type, url_quote, PY2 class TraversalPathTests(unittest.TestCase): def _callFUT(self, path): from pyramid.traversal import traversal_path return traversal_path(path) def test_utf8(self): la = b'La Pe\xc3\xb1a' encoded = url_quote(la) decoded = text_(la, 'utf-8') path = '/'.join([encoded, encoded]) result = self._callFUT(path) self.assertEqual(result, (decoded, decoded)) def test_utf16(self): from pyramid.exceptions import URLDecodeError la = text_(b'La Pe\xc3\xb1a', 'utf-8').encode('utf-16') encoded = url_quote(la) path = '/'.join([encoded, encoded]) self.assertRaises(URLDecodeError, self._callFUT, path) def test_unicode_highorder_chars(self): path = text_('/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') self.assertEqual( self._callFUT(path), (text_('\u6d41\u884c\u8d8b\u52bf', 'unicode_escape'),), ) def test_element_urllquoted(self): self.assertEqual( self._callFUT('/foo/space%20thing/bar'), (text_('foo'), text_('space thing'), text_('bar')), ) def test_unicode_undecodeable_to_ascii(self): path = text_(b'/La Pe\xc3\xb1a', 'utf-8') self.assertRaises(UnicodeEncodeError, self._callFUT, path) class TraversalPathInfoTests(unittest.TestCase): def _callFUT(self, path): from pyramid.traversal import traversal_path_info return traversal_path_info(path) def test_path_startswith_endswith(self): self.assertEqual(self._callFUT('/foo/'), (text_('foo'),)) def test_empty_elements(self): self.assertEqual(self._callFUT('foo///'), (text_('foo'),)) def test_onedot(self): self.assertEqual( self._callFUT('foo/./bar'), (text_('foo'), text_('bar')) ) def test_twodots(self): self.assertEqual(self._callFUT('foo/../bar'), (text_('bar'),)) def test_twodots_at_start(self): self.assertEqual(self._callFUT('../../bar'), (text_('bar'),)) def test_segments_are_unicode(self): result = self._callFUT('/foo/bar') self.assertEqual(type(result[0]), text_type) self.assertEqual(type(result[1]), text_type) def test_same_value_returned_if_cached(self): result1 = self._callFUT('/foo/bar') result2 = self._callFUT('/foo/bar') self.assertEqual(result1, (text_('foo'), text_('bar'))) self.assertEqual(result2, (text_('foo'), text_('bar'))) def test_unicode_simple(self): path = text_('/abc') self.assertEqual(self._callFUT(path), (text_('abc'),)) def test_highorder(self): la = b'La Pe\xc3\xb1a' latin1 = native_(la) result = self._callFUT(latin1) self.assertEqual(result, (text_(la, 'utf-8'),)) def test_highorder_undecodeable(self): from pyramid.exceptions import URLDecodeError la = text_(b'La Pe\xc3\xb1a', 'utf-8') notlatin1 = native_(la) self.assertRaises(URLDecodeError, self._callFUT, notlatin1) class ResourceTreeTraverserTests(unittest.TestCase): def setUp(self): cleanUp() def tearDown(self): cleanUp() def _getTargetClass(self): from pyramid.traversal import ResourceTreeTraverser return ResourceTreeTraverser def _makeOne(self, *arg, **kw): klass = self._getTargetClass() return klass(*arg, **kw) def _getEnviron(self, **kw): environ = {} environ.update(kw) return environ def test_class_conforms_to_ITraverser(self): from zope.interface.verify import verifyClass from pyramid.interfaces import ITraverser verifyClass(ITraverser, self._getTargetClass()) def test_instance_conforms_to_ITraverser(self): from zope.interface.verify import verifyObject from pyramid.interfaces import ITraverser context = DummyContext() verifyObject(ITraverser, self._makeOne(context)) def test_call_with_empty_pathinfo(self): policy = self._makeOne(None) environ = self._getEnviron() request = DummyRequest(environ, path_info='') result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_pathinfo_KeyError(self): policy = self._makeOne(None) environ = self._getEnviron() request = DummyRequest(environ, toraise=KeyError) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_pathinfo_highorder(self): path = text_(b'/Qu\xc3\xa9bec', 'utf-8') foo = DummyContext(None, path) root = DummyContext(foo, 'root') policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=path) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (path[1:],)) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) def test_call_pathel_with_no_getitem(self): policy = self._makeOne(None) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/foo/bar')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_emptypath_nosubpath(self): root = DummyContext() policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('')) result = policy(request) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_withpath_nosubpath(self): foo = DummyContext() root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/foo/bar')) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (text_('foo'),)) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_withconn_getitem_withpath_withsubpath(self): foo = DummyContext() root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') self.assertEqual(result['subpath'], ('baz', 'buz')) self.assertEqual(result['traversed'], (text_('foo'),)) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_explicit_viewname(self): foo = DummyContext() root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info=text_('/@@foo')) result = policy(request) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_vh_root(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar') baz = DummyContext(None, 'baz') bar = DummyContext(baz, 'bar') foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual( result['traversed'], (text_('foo'), text_('bar'), text_('baz')) ) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], bar) self.assertEqual( result['virtual_root_path'], (text_('foo'), text_('bar')) ) def test_call_with_vh_root2(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo') baz = DummyContext(None, 'baz') bar = DummyContext(baz, 'bar') foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual( result['traversed'], (text_('foo'), text_('bar'), text_('baz')) ) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], foo) self.assertEqual(result['virtual_root_path'], (text_('foo'),)) def test_call_with_vh_root3(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/') baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual( result['traversed'], (text_('foo'), text_('bar'), text_('baz')) ) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_vh_root4(self): environ = self._getEnviron(HTTP_X_VHM_ROOT='/foo/bar/baz') baz = DummyContext(None, 'baz') bar = DummyContext(baz, 'bar') foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info=text_('/')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual( result['traversed'], (text_('foo'), text_('bar'), text_('baz')) ) self.assertEqual(result['root'], root) self.assertEqual(result['virtual_root'], baz) self.assertEqual( result['virtual_root_path'], (text_('foo'), text_('bar'), text_('baz')), ) def test_call_with_vh_root_path_root(self): policy = self._makeOne(None) environ = self._getEnviron(HTTP_X_VHM_ROOT='/') request = DummyRequest(environ, path_info=text_('/')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], policy.root) self.assertEqual(result['virtual_root_path'], ()) def test_call_with_vh_root_highorder(self): path = text_(b'Qu\xc3\xa9bec', 'utf-8') bar = DummyContext(None, 'bar') foo = DummyContext(bar, path) root = DummyContext(foo, 'root') policy = self._makeOne(root) if PY2: vhm_root = b'/Qu\xc3\xa9bec' else: vhm_root = b'/Qu\xc3\xa9bec'.decode('latin-1') environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) request = DummyRequest(environ, path_info=text_('/bar')) result = policy(request) self.assertEqual(result['context'], bar) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (path, text_('bar'))) self.assertEqual(result['root'], policy.root) self.assertEqual(result['virtual_root'], foo) self.assertEqual(result['virtual_root_path'], (path,)) def test_path_info_raises_unicodedecodeerror(self): from pyramid.exceptions import URLDecodeError foo = DummyContext() root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5') request = DummyRequest(environ, toraise=toraise) request.matchdict = None self.assertRaises(URLDecodeError, policy, request) def test_withroute_nothingfancy(self): resource = DummyContext() traverser = self._makeOne(resource) request = DummyRequest({}) request.matchdict = {} result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_with_subpath_string(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'subpath': '/a/b/c'} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ('a', 'b', 'c')) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_with_subpath_tuple(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'subpath': ('a', 'b', 'c')} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ('a', 'b', 'c')) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_and_traverse_string(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'traverse': text_('foo/bar')} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_and_traverse_tuple(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'traverse': ('foo', 'bar')} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_and_traverse_empty(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'traverse': ''} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], resource) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], ()) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], resource) self.assertEqual(result['virtual_root_path'], ()) def test_withroute_and_traverse_and_vroot(self): abc = DummyContext() resource = DummyContext(next=abc) environ = self._getEnviron(HTTP_X_VHM_ROOT='/abc') request = DummyRequest(environ) traverser = self._makeOne(resource) matchdict = {'traverse': text_('/foo/bar')} request.matchdict = matchdict result = traverser(request) self.assertEqual(result['context'], abc) self.assertEqual(result['view_name'], 'foo') self.assertEqual(result['subpath'], ('bar',)) self.assertEqual(result['traversed'], ('abc', 'foo')) self.assertEqual(result['root'], resource) self.assertEqual(result['virtual_root'], abc) self.assertEqual(result['virtual_root_path'], ('abc',)) class FindInterfaceTests(unittest.TestCase): def _callFUT(self, context, iface): from pyramid.traversal import find_interface return find_interface(context, iface) def test_it_interface(self): baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) root.__parent__ = None root.__name__ = 'root' foo.__parent__ = root foo.__name__ = 'foo' bar.__parent__ = foo bar.__name__ = 'bar' baz.__parent__ = bar baz.__name__ = 'baz' from zope.interface import directlyProvides from zope.interface import Interface class IFoo(Interface): pass directlyProvides(root, IFoo) result = self._callFUT(baz, IFoo) self.assertEqual(result.__name__, 'root') def test_it_class(self): class DummyRoot(object): def __init__(self, child): self.child = child baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyRoot(foo) root.__parent__ = None root.__name__ = 'root' foo.__parent__ = root foo.__name__ = 'foo' bar.__parent__ = foo bar.__name__ = 'bar' baz.__parent__ = bar baz.__name__ = 'baz' result = self._callFUT(baz, DummyRoot) self.assertEqual(result.__name__, 'root') class FindRootTests(unittest.TestCase): def _callFUT(self, context): from pyramid.traversal import find_root return find_root(context) def test_it(self): dummy = DummyContext() baz = DummyContext() baz.__parent__ = dummy baz.__name__ = 'baz' dummy.__parent__ = None dummy.__name__ = None result = self._callFUT(baz) self.assertEqual(result, dummy) class FindResourceTests(unittest.TestCase): def _callFUT(self, context, name): from pyramid.traversal import find_resource return find_resource(context, name) def _registerTraverser(self, traverser): from pyramid.threadlocal import get_current_registry reg = get_current_registry() from pyramid.interfaces import ITraverser from zope.interface import Interface reg.registerAdapter(traverser, (Interface,), ITraverser) def test_list(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, ['']) self.assertEqual(result, resource) self.assertEqual(resource.request.environ['PATH_INFO'], '/') def test_generator(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) def foo(): yield '' result = self._callFUT(resource, foo()) self.assertEqual(result, resource) self.assertEqual(resource.request.environ['PATH_INFO'], '/') def test_self_string_found(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, '') self.assertEqual(result, resource) self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_self_tuple_found(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, ()) self.assertEqual(result, resource) self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_relative_string_found(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, 'baz') self.assertEqual(result, baz) self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_relative_tuple_found(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, ('baz',)) self.assertEqual(result, baz) self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_relative_string_notfound(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': 'bar'}) self._registerTraverser(traverser) self.assertRaises(KeyError, self._callFUT, resource, 'baz') self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_relative_tuple_notfound(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': 'bar'}) self._registerTraverser(traverser) self.assertRaises(KeyError, self._callFUT, resource, ('baz',)) self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_absolute_string_found(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, '/') self.assertEqual(result, root) self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_absolute_tuple_found(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(resource, ('',)) self.assertEqual(result, root) self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_absolute_string_notfound(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': 'fuz'}) self._registerTraverser(traverser) self.assertRaises(KeyError, self._callFUT, resource, '/') self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_absolute_tuple_notfound(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': 'fuz'}) self._registerTraverser(traverser) self.assertRaises(KeyError, self._callFUT, resource, ('',)) self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_absolute_unicode_found(self): # test for bug wiggy found in wild, traceback stack: # root = u'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF' # wiggy's code: section=find_resource(page, root) # find_resource L76: D = traverse(resource, path) # traverse L291: return traverser(request) # __call__ line 568: vpath_tuple = traversal_path(vpath) # lru_cached line 91: f(*arg) # traversal_path line 443: path.encode('ascii') # UnicodeEncodeError: 'ascii' codec can't encode characters in # position 1-12: ordinal not in range(128) # # solution: encode string to ascii in pyramid.traversal.traverse # before passing it along to webob as path_info from pyramid.traversal import ResourceTreeTraverser unprintable = DummyContext() root = DummyContext(unprintable) unprintable.__parent__ = root unprintable.__name__ = text_( b'/\xe6\xb5\x81\xe8\xa1\x8c\xe8\xb6\x8b\xe5\x8a\xbf', 'utf-8' ) root.__parent__ = None root.__name__ = None traverser = ResourceTreeTraverser self._registerTraverser(traverser) result = self._callFUT( root, text_(b'/%E6%B5%81%E8%A1%8C%E8%B6%8B%E5%8A%BF') ) self.assertEqual(result, unprintable) class ResourcePathTests(unittest.TestCase): def _callFUT(self, resource, *elements): from pyramid.traversal import resource_path return resource_path(resource, *elements) def test_it(self): baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) root.__parent__ = None root.__name__ = None foo.__parent__ = root foo.__name__ = 'foo ' bar.__parent__ = foo bar.__name__ = 'bar' baz.__parent__ = bar baz.__name__ = 'baz' result = self._callFUT(baz, 'this/theotherthing', 'that') self.assertEqual(result, '/foo%20/bar/baz/this%2Ftheotherthing/that') def test_root_default(self): root = DummyContext() root.__parent__ = None root.__name__ = None result = self._callFUT(root) self.assertEqual(result, '/') def test_root_default_emptystring(self): root = DummyContext() root.__parent__ = None root.__name__ = '' result = self._callFUT(root) self.assertEqual(result, '/') def test_root_object_nonnull_name_direct(self): root = DummyContext() root.__parent__ = None root.__name__ = 'flubadub' result = self._callFUT(root) self.assertEqual(result, 'flubadub') # insane case def test_root_object_nonnull_name_indirect(self): root = DummyContext() root.__parent__ = None root.__name__ = 'flubadub' other = DummyContext() other.__parent__ = root other.__name__ = 'barker' result = self._callFUT(other) self.assertEqual(result, 'flubadub/barker') # insane case def test_nonroot_default(self): root = DummyContext() root.__parent__ = None root.__name__ = None other = DummyContext() other.__parent__ = root other.__name__ = 'other' result = self._callFUT(other) self.assertEqual(result, '/other') def test_path_with_None_itermediate_names(self): root = DummyContext() root.__parent__ = None root.__name__ = None other = DummyContext() other.__parent__ = root other.__name__ = None other2 = DummyContext() other2.__parent__ = other other2.__name__ = 'other2' result = self._callFUT(other2) self.assertEqual(result, '//other2') class ResourcePathTupleTests(unittest.TestCase): def _callFUT(self, resource, *elements): from pyramid.traversal import resource_path_tuple return resource_path_tuple(resource, *elements) def test_it(self): baz = DummyContext() bar = DummyContext(baz) foo = DummyContext(bar) root = DummyContext(foo) root.__parent__ = None root.__name__ = None foo.__parent__ = root foo.__name__ = 'foo ' bar.__parent__ = foo bar.__name__ = 'bar' baz.__parent__ = bar baz.__name__ = 'baz' result = self._callFUT(baz, 'this/theotherthing', 'that') self.assertEqual( result, ('', 'foo ', 'bar', 'baz', 'this/theotherthing', 'that') ) def test_root_default(self): root = DummyContext() root.__parent__ = None root.__name__ = None result = self._callFUT(root) self.assertEqual(result, ('',)) def test_root_default_emptystring_name(self): root = DummyContext() root.__parent__ = None root.__name__ = '' other = DummyContext() other.__parent__ = root other.__name__ = 'other' result = self._callFUT(other) self.assertEqual(result, ('', 'other')) def test_nonroot_default(self): root = DummyContext() root.__parent__ = None root.__name__ = None other = DummyContext() other.__parent__ = root other.__name__ = 'other' result = self._callFUT(other) self.assertEqual(result, ('', 'other')) def test_path_with_None_itermediate_names(self): root = DummyContext() root.__parent__ = None root.__name__ = None other = DummyContext() other.__parent__ = root other.__name__ = None other2 = DummyContext() other2.__parent__ = other other2.__name__ = 'other2' result = self._callFUT(other2) self.assertEqual(result, ('', '', 'other2')) class QuotePathSegmentTests(unittest.TestCase): def _callFUT(self, s): from pyramid.traversal import quote_path_segment return quote_path_segment(s) def test_unicode(self): la = text_(b'/La Pe\xc3\xb1a', 'utf-8') result = self._callFUT(la) self.assertEqual(result, '%2FLa%20Pe%C3%B1a') def test_string(self): s = '/ hello!' result = self._callFUT(s) self.assertEqual(result, '%2F%20hello!') def test_int(self): s = 12345 result = self._callFUT(s) self.assertEqual(result, '12345') def test_long(self): from pyramid.compat import long import sys s = long(sys.maxsize + 1) result = self._callFUT(s) expected = str(s) self.assertEqual(result, expected) def test_other(self): class Foo(object): def __str__(self): return 'abc' s = Foo() result = self._callFUT(s) self.assertEqual(result, 'abc') class ResourceURLTests(unittest.TestCase): def _makeOne(self, context, url): return self._getTargetClass()(context, url) def _getTargetClass(self): from pyramid.traversal import ResourceURL return ResourceURL def test_instance_conforms_to_IResourceURL(self): from pyramid.interfaces import IResourceURL from zope.interface.verify import verifyObject context = DummyContext() request = DummyRequest() verifyObject(IResourceURL, self._makeOne(context, request)) def test_IResourceURL_attributes_with_vroot(self): from pyramid.interfaces import VH_ROOT_KEY root = DummyContext() root.__parent__ = None root.__name__ = None one = DummyContext() one.__parent__ = root one.__name__ = 'one' two = DummyContext() two.__parent__ = one two.__name__ = 'two' environ = {VH_ROOT_KEY: '/one'} request = DummyRequest(environ) context_url = self._makeOne(two, request) self.assertEqual(context_url.physical_path, '/one/two/') self.assertEqual(context_url.virtual_path, '/two/') self.assertEqual( context_url.physical_path_tuple, ('', 'one', 'two', '') ) self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) def test_IResourceURL_attributes_vroot_ends_with_slash(self): from pyramid.interfaces import VH_ROOT_KEY root = DummyContext() root.__parent__ = None root.__name__ = None one = DummyContext() one.__parent__ = root one.__name__ = 'one' two = DummyContext() two.__parent__ = one two.__name__ = 'two' environ = {VH_ROOT_KEY: '/one/'} request = DummyRequest(environ) context_url = self._makeOne(two, request) self.assertEqual(context_url.physical_path, '/one/two/') self.assertEqual(context_url.virtual_path, '/two/') self.assertEqual( context_url.physical_path_tuple, ('', 'one', 'two', '') ) self.assertEqual(context_url.virtual_path_tuple, ('', 'two', '')) def test_IResourceURL_attributes_no_vroot(self): root = DummyContext() root.__parent__ = None root.__name__ = None one = DummyContext() one.__parent__ = root one.__name__ = 'one' two = DummyContext() two.__parent__ = one two.__name__ = 'two' environ = {} request = DummyRequest(environ) context_url = self._makeOne(two, request) self.assertEqual(context_url.physical_path, '/one/two/') self.assertEqual(context_url.virtual_path, '/one/two/') self.assertEqual( context_url.physical_path_tuple, ('', 'one', 'two', '') ) self.assertEqual( context_url.virtual_path_tuple, ('', 'one', 'two', '') ) class TestVirtualRoot(unittest.TestCase): def setUp(self): cleanUp() def tearDown(self): cleanUp() def _callFUT(self, resource, request): from pyramid.traversal import virtual_root return virtual_root(resource, request) def _registerTraverser(self, traverser): from pyramid.threadlocal import get_current_registry reg = get_current_registry() from pyramid.interfaces import ITraverser from zope.interface import Interface reg.registerAdapter(traverser, (Interface,), ITraverser) def test_virtual_root_no_virtual_root_path(self): root = DummyContext() root.__name__ = None root.__parent__ = None one = DummyContext() one.__name__ = 'one' one.__parent__ = root request = DummyRequest() result = self._callFUT(one, request) self.assertEqual(result, root) def test_virtual_root_no_virtual_root_path_with_root_on_request(self): context = DummyContext() context.__parent__ = None request = DummyRequest() request.root = DummyContext() result = self._callFUT(context, request) self.assertEqual(result, request.root) def test_virtual_root_with_virtual_root_path(self): from pyramid.interfaces import VH_ROOT_KEY root = DummyContext() root.__parent__ = None context = DummyContext() context.__name__ = 'one' context.__parent__ = root traversed_to = DummyContext() environ = {VH_ROOT_KEY: '/one'} request = DummyRequest(environ) traverser = make_traverser({'context': traversed_to, 'view_name': ''}) self._registerTraverser(traverser) result = self._callFUT(context, request) self.assertEqual(result, traversed_to) self.assertEqual(root.request.environ['PATH_INFO'], '/one') def test_default(self): context = DummyContext() request = _makeRequest() request.environ['PATH_INFO'] = '/' result = self._callFUT(context, request) self.assertEqual(result, context) def test_default_no_registry_on_request(self): context = DummyContext() request = _makeRequest() del request.registry request.environ['PATH_INFO'] = '/' result = self._callFUT(context, request) self.assertEqual(result, context) class TraverseTests(unittest.TestCase): def setUp(self): cleanUp() def tearDown(self): cleanUp() def _callFUT(self, context, name): from pyramid.traversal import traverse return traverse(context, name) def _registerTraverser(self, traverser): from pyramid.threadlocal import get_current_registry reg = get_current_registry() from pyramid.interfaces import ITraverser from zope.interface import Interface reg.registerAdapter(traverser, (Interface,), ITraverser) def test_request_has_registry(self): from pyramid.threadlocal import get_current_registry resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ['']) self.assertEqual(resource.request.registry, get_current_registry()) def test_list(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ['']) self.assertEqual(resource.request.environ['PATH_INFO'], '/') def test_generator(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) def foo(): yield '' self._callFUT(resource, foo()) self.assertEqual(resource.request.environ['PATH_INFO'], '/') def test_self_string_found(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, '') self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_self_unicode_found(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, text_('')) self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_self_tuple_found(self): resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ()) self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_relative_string_found(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, 'baz') self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_relative_tuple_found(self): resource = DummyContext() baz = DummyContext() traverser = make_traverser({'context': baz, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ('baz',)) self.assertEqual(resource.request.environ['PATH_INFO'], 'baz') def test_absolute_string_found(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, '/') self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_absolute_tuple_found(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ('',)) self.assertEqual(root.wascontext, True) self.assertEqual(root.request.environ['PATH_INFO'], '/') def test_empty_sequence(self): root = DummyContext() resource = DummyContext() resource.__parent__ = root resource.__name__ = 'baz' traverser = make_traverser({'context': root, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, []) self.assertEqual(resource.wascontext, True) self.assertEqual(resource.request.environ['PATH_INFO'], '') def test_default_traverser(self): resource = DummyContext() result = self._callFUT(resource, '') self.assertEqual(result['view_name'], '') self.assertEqual(result['context'], resource) def test_requestfactory_overridden(self): from pyramid.interfaces import IRequestFactory from pyramid.request import Request from pyramid.threadlocal import get_current_registry reg = get_current_registry() class MyRequest(Request): pass reg.registerUtility(MyRequest, IRequestFactory) resource = DummyContext() traverser = make_traverser({'context': resource, 'view_name': ''}) self._registerTraverser(traverser) self._callFUT(resource, ['']) self.assertEqual(resource.request.__class__, MyRequest) class TestDefaultRootFactory(unittest.TestCase): def _getTargetClass(self): from pyramid.traversal import DefaultRootFactory return DefaultRootFactory def _makeOne(self, environ): return self._getTargetClass()(environ) def test_it(self): class DummyRequest(object): pass root = self._makeOne(DummyRequest()) self.assertEqual(root.__parent__, None) self.assertEqual(root.__name__, None) class Test__join_path_tuple(unittest.TestCase): def _callFUT(self, tup): from pyramid.traversal import _join_path_tuple return _join_path_tuple(tup) def test_empty_tuple(self): # tests "or '/'" case result = self._callFUT(()) self.assertEqual(result, '/') def test_nonempty_tuple(self): result = self._callFUT(('x',)) self.assertEqual(result, 'x') def test_segments_with_unsafes(self): safe_segments = tuple( u"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~!$&'()*+,;=:@" ) result = self._callFUT(safe_segments) self.assertEqual(result, u'/'.join(safe_segments)) unsafe_segments = tuple( chr(i) for i in range(0x20, 0x80) if not chr(i) in safe_segments ) + (u'あ',) result = self._callFUT(unsafe_segments) self.assertEqual( result, u'/'.join( ''.join( '%%%02X' % (ord(c) if isinstance(c, str) else c) for c in unsafe_segment.encode('utf-8') ) for unsafe_segment in unsafe_segments ), ) def make_traverser(result): class DummyTraverser(object): def __init__(self, context): self.context = context context.wascontext = True def __call__(self, request): self.context.request = request return result return DummyTraverser class DummyContext(object): __parent__ = None def __init__(self, next=None, name=None): self.next = next self.__name__ = name def __getitem__(self, name): if self.next is None: raise KeyError(name) return self.next def __repr__(self): return '' % ( self.__name__, id(self), ) class DummyRequest: application_url = ( 'http://example.com:5432' ) # app_url never ends with slash matchdict = None matched_route = None def __init__(self, environ=None, path_info=text_('/'), toraise=None): if environ is None: environ = {} self.environ = environ self._set_path_info(path_info) self.toraise = toraise def _get_path_info(self): if self.toraise: raise self.toraise return self._path_info def _set_path_info(self, v): self._path_info = v path_info = property(_get_path_info, _set_path_info) def _makeRequest(environ=None): from pyramid.registry import Registry request = DummyRequest() request.registry = Registry() return request