def make_query(quote_params=QUOTE_PARAMS, **kw): query = list() for name, param in sorted(kw.items()): if param is None: continue if isinstance(param, compat.STR_TYPE): param = [param] if type(param) in compat.NUMBER_TYPES: param = [str(param)] quote = name in quote_params for p in param: p = safe_encode(p) if compat.IS_PY2 else p query.append('{}={}'.format(name, compat.quote(p) if quote else p)) query = '&'.join(query) if query: return '?{}'.format(query)
def make_url(request, path=None, node=None, resource=None, query=None): # if path=[] in signature, path gets aggregated in recursive calls ??? # happens on icon lookup in navtree. # ^^^ that is because the [] (a list, mutable) is generated at compile # time. mutable values should not be in function signatures to avoid this. if path is None: path = [] else: path = copy.copy(path) if node is not None: path = node_path(node) if resource is not None: path.append(resource) path = [compat.quote(safe_encode(it)) for it in path] url = '{}/{}'.format(request.application_url, '/'.join(path)) if not query: return url return '{}{}'.format(url, query)
def test_copysupport(self): # Copysupport Attributes model = CopySupportNode() model['child'] = CopySupportNode() request = self.layer.new_request() with self.layer.authenticated('manager'): rendered = render_tile(model, request, 'contents') expected = 'class="selectable copysupportitem"' self.assertTrue(rendered.find(expected) > -1) with self.layer.authenticated('manager'): request = self.layer.new_request() cut_url = compat.quote(make_url(request, node=model['child'])) request.cookies['cone.app.copysupport.cut'] = cut_url rendered = render_tile(model, request, 'contents') expected = 'class="selectable copysupportitem copysupport_cut"' self.assertTrue(rendered.find(expected) > -1)
def test_CameFromNext(self): # Plumbing behavior to hook up redirection after successful form # processing with self.layer.hook_tile_reg(): @tile(name='camefromnextform') @plumbing(CameFromNext) class CameFromNextForm(Form): def prepare(self): form = factory( u'form', name='camefromnextform', props={'action': self.nodeurl}) form['next'] = factory( 'submit', props={ 'action': 'next', 'expression': True, 'next': self.next, 'label': 'Next', }) self.form = form # Check behavior config defaults self.assertTrue(CameFromNextForm.default_came_from is None) self.assertTrue(CameFromNextForm.write_history_on_next is False) # Create a test model and login root = BaseNode() model = root['child'] = BaseNode() # Check whether ``came_from`` is rendered on form as proxy field with self.layer.authenticated('manager'): request = self.layer.new_request() came_from = compat.quote('http://example.com/some/path?foo=bar') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.checkOutput(""" ...<input id="input-camefromnextform-came_from" name="came_from" type="hidden" value="http%3A//example.com/some/path%3Ffoo%3Dbar" />... """, res) # No ``came_from`` on request, no ``default_came_from``, no ajax request with self.layer.authenticated('manager'): request = self.layer.new_request() request.params['action.camefromnextform.next'] = '1' res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/child' ) # No ``came_from`` on request, ``default_came_from`` set to ``parent``, # no ajax request with self.layer.authenticated('manager'): CameFromNextForm.default_came_from = 'parent' res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/' ) # No ``came_from`` on request, ``default_came_from`` set to URL, no # ajax request with self.layer.authenticated('manager'): came_from = compat.quote('http://example.com/foo/bar?baz=1') CameFromNextForm.default_came_from = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/foo/bar?baz=1' ) # No ``came_from`` on request, ``default_came_from`` set to wrong # domain, no ajax request with self.layer.authenticated('manager'): CameFromNextForm.default_came_from = 'http://other.com' res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/child' ) # ``came_from`` set to empty value on request, overrules # ``default_came_from``, no ajax request with self.layer.authenticated('manager'): CameFromNextForm.default_came_from = 'parent' request.params['came_from'] = '' res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/child' ) # ``came_from`` set to ``parent`` on request, overrules # ``default_came_from``, no ajax request with self.layer.authenticated('manager'): CameFromNextForm.default_came_from = None request.params['came_from'] = 'parent' res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/' ) # ``came_from`` set to URL on request, overrules ``default_came_from``, # no ajax request with self.layer.authenticated('manager'): came_from = compat.quote('http://example.com/default') CameFromNextForm.default_came_from = came_from came_from = compat.quote('http://example.com/other') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.assertEqual( request.environ['redirect'].location, 'http://example.com/other' ) # Reset ``default_came_from`` CameFromNextForm.default_came_from = None # ``came_from`` set to empty value on request, ajax request, no ajax # path continuation with self.layer.authenticated('manager'): request = self.layer.new_request() request.params['ajax'] = '1' request.params['action.camefromnextform.next'] = '1' request.params['came_from'] = '' res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 1) continuation = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(continuation, AjaxEvent)) self.assertEqual( (continuation.target, continuation.name, continuation.selector), ('http://example.com/child', 'contextchanged', '#layout') ) # ``came_from`` set to ``parent`` on request, ajax request, no ajax # path continuation with self.layer.authenticated('manager'): request.params['came_from'] = 'parent' res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 1) continuation = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(continuation, AjaxEvent)) self.assertEqual( (continuation.target, continuation.name, continuation.selector), ('http://example.com/', 'contextchanged', '#layout') ) # ``came_from`` set to URL on request, ajax request, no ajax path # continuation with self.layer.authenticated('manager'): came_from = compat.quote('http://example.com/some/path?foo=bar') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 1) continuation = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(continuation, AjaxEvent)) self.assertEqual( (continuation.target, continuation.name, continuation.selector), ('http://example.com/some/path?foo=bar', 'contextchanged', '#layout') ) # ``came_from`` set to wrong domain on request, ajax request, no ajax # path continuation with self.layer.authenticated('manager'): came_from = compat.quote('http://other.com') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 1) continuation = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(continuation, AjaxEvent)) self.assertEqual( (continuation.target, continuation.name, continuation.selector), ('http://example.com/child', 'contextchanged', '#layout') ) # ``came_from`` set to empty value on request, ajax request, setting # browser history configured with self.layer.authenticated('manager'): CameFromNextForm.write_history_on_next = True request = self.layer.new_request() request.params['ajax'] = '1' request.params['action.camefromnextform.next'] = '1' request.params['came_from'] = '' res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 2) path = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(path, AjaxPath)) self.assertEqual( (path.path, path.target, path.event), (u'child', 'http://example.com/child', 'contextchanged:#layout') ) event = request.environ['cone.app.continuation'][1] self.assertTrue(isinstance(event, AjaxEvent)) self.assertEqual( (event.target, continuation.name, continuation.selector), ('http://example.com/child', 'contextchanged', '#layout') ) # ``came_from`` set to ``parent`` on request, ajax request, setting # browser history configured with self.layer.authenticated('manager'): request.params['came_from'] = 'parent' res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 2) path = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(path, AjaxPath)) self.assertEqual( (path.path, path.target, path.event), ('', 'http://example.com/', 'contextchanged:#layout') ) event = request.environ['cone.app.continuation'][1] self.assertTrue(isinstance(event, AjaxEvent)) self.assertEqual( (event.target, continuation.name, continuation.selector), ('http://example.com/', 'contextchanged', '#layout') ) # ``came_from`` set to URL on request, ajax request, setting browser # history configured with self.layer.authenticated('manager'): came_from = compat.quote('http://example.com/some/path') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 2) path = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(path, AjaxPath)) self.assertEqual( (path.path, path.target, path.event), ('/some/path', 'http://example.com/some/path', 'contextchanged:#layout') ) event = request.environ['cone.app.continuation'][1] self.assertTrue(isinstance(event, AjaxEvent)) self.assertEqual( (event.target, continuation.name, continuation.selector), ('http://example.com/some/path', 'contextchanged', '#layout') ) # ``came_from`` set to to wrong on request, ajax request, setting # browser history configured with self.layer.authenticated('manager'): came_from = compat.quote('http://other.com') request.params['came_from'] = came_from res = render_tile(model, request, 'camefromnextform') self.assertTrue(len(request.environ['cone.app.continuation']) == 2) path = request.environ['cone.app.continuation'][0] self.assertTrue(isinstance(path, AjaxPath)) self.assertEqual( (path.path, path.target, path.event), (u'child', 'http://example.com/child', 'contextchanged:#layout') ) event = request.environ['cone.app.continuation'][1] self.assertTrue(isinstance(event, AjaxEvent)) self.assertEqual( (event.target, continuation.name, continuation.selector), ('http://example.com/child', 'contextchanged', '#layout') ) # Reset ``write_history_on_next`` CameFromNextForm.write_history_on_next = False
def test_editing(self): @node_info( name='mynode', title='My Node') class MyNode(BaseNode): pass # Create and register an ``editform`` named form tile with self.layer.hook_tile_reg(): @tile(name='editform', interface=MyNode) @plumbing(ContentEditForm) class MyEditForm(Form): def prepare(self): form = factory( u'form', name='editform', props={ 'action': self.nodeurl }) form['title'] = factory( 'field:label:text', value=self.model.attrs.title, props={ 'label': 'Title', }) form['update'] = factory( 'submit', props={ 'action': 'update', 'expression': True, 'handler': self.update, 'next': self.next, 'label': 'Update', }) self.form = form def update(self, widget, data): fetch = self.request.params.get self.model.attrs.title = fetch('editform.title') # Dummy model root = MyNode() child = root['somechild'] = MyNode() child.attrs.title = 'My Node' # Render form with value from model with self.layer.authenticated('editor'): request = self.layer.new_request() res = render_tile(root['somechild'], request, 'edit') self.checkOutput(""" ...<span class="label label-primary">Edit: My Node</span>... <form action="http://example.com/somechild"... """, res) # Render with submitted data. Default next URL of EditForm is the # edited node with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' res = render_tile(root['somechild'], request, 'edit') self.assertEqual( request.environ['redirect'].location, 'http://example.com/somechild' ) # Check next URL with ``parent`` as ``came_from`` value with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' request.params['came_from'] = 'parent' res = render_tile(root['somechild'], request, 'edit') self.assertEqual( request.environ['redirect'].location, 'http://example.com/' ) # Check next URL with URL as ``came_from`` value with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' came_from = compat.quote('http://example.com/other/node/in/tree') request.params['came_from'] = came_from res = render_tile(root['somechild'], request, 'edit') self.assertEqual( request.environ['redirect'].location, 'http://example.com/other/node/in/tree' ) # Render with ajax flag with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' request.params['ajax'] = '1' res = render_tile(root['somechild'], request, 'edit') self.assertTrue(isinstance( request.environ['cone.app.continuation'][0], AjaxEvent )) # URL computing is the same as if ``HTTPFound`` instance is returned. # In Ajax case, the URL is used as ajax target self.assertEqual( request.environ['cone.app.continuation'][0].target, 'http://example.com/somechild' ) with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' came_from = compat.quote('http://example.com/other/node/in/tree') request.params['came_from'] = came_from request.params['ajax'] = '1' res = render_tile(root['somechild'], request, 'edit') self.assertEqual( request.environ['cone.app.continuation'][0].target, 'http://example.com/other/node/in/tree' ) # Check the updated node self.assertEqual(root['somechild'].attrs.title, 'Changed title') # Edit view with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' root.attrs.title = 'Foo' res = edit(root, request) self.assertTrue(isinstance(res, HTTPFound)) with self.layer.authenticated('editor'): request = self.layer.new_request() request.params['action.editform.update'] = '1' request.params['editform.title'] = 'Changed title' request.params['ajax'] = '1' res = str(edit(root, request)) self.assertTrue(res.find('parent.bdajax.render_ajax_form') != -1)
def test_adding(self): # Provide a node interface needed for different node style binding to # test form class ITestAddingNode(Interface): pass # Create dummy node @node_info( name='mynode', title='My Node', description='This is My node.', addables=['mynode']) # self containment @implementer(ITestAddingNode) class MyNode(BaseNode): pass # Create another dummy node inheriting from AdapterNode @node_info( name='myadapternode', title='My Adapter Node', description='This is My adapter node.', addables=['myadapternode']) # self containment @implementer(ITestAddingNode) class MyAdapterNode(AdapterNode): pass # Create and register an ``addform`` named form tile with self.layer.hook_tile_reg(): @tile(name='addform', interface=ITestAddingNode) @plumbing(ContentAddForm) class MyAddForm(Form): def prepare(self): form = factory( u'form', name='addform', props={ 'action': self.nodeurl }) form['id'] = factory( 'field:label:text', props={ 'label': 'Id', }) form['title'] = factory( 'field:label:text', props={ 'label': 'Title', }) form['add'] = factory( 'submit', props={ 'action': 'add', 'expression': True, 'handler': self.add, 'next': self.next, 'label': 'Add', }) self.form = form def add(self, widget, data): fetch = self.request.params.get child = MyNode() child.attrs.title = fetch('addform.title') self.model.parent[fetch('addform.id')] = child self.model = child # Create dummy container root = MyNode() # Render without factory with self.layer.authenticated('manager'): request = self.layer.new_request() self.assertEqual( render_tile(root, request, 'add'), u'unknown_factory' ) # Render with valid factory with self.layer.authenticated('manager'): request.params['factory'] = 'mynode' result = render_tile(root, request, 'add') self.assertTrue(result.find(u'<form action="http://example.com"') != -1) # Render with valid factory on adapter node with self.layer.authenticated('manager'): adapterroot = MyAdapterNode(None, None, None) request.params['factory'] = 'myadapternode' result = render_tile(adapterroot, request, 'add') self.assertTrue(result.find(u'<form action="http://example.com"') != -1) # Render with submitted data with self.layer.authenticated('manager'): request = self.layer.current_request request.params['factory'] = 'mynode' request.params['action.addform.add'] = '1' request.params['addform.id'] = 'somechild' request.params['addform.title'] = 'Some Child' render_tile(root, request, 'add') self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) self.checkOutput(""" <class '...MyNode'>: None <class '...MyNode'>: somechild """, root.treerepr()) self.assertEqual( request.environ['redirect'].location, 'http://example.com/somechild' ) del request.environ['redirect'] # Render with 'came_from' set with self.layer.authenticated('manager'): request.params['came_from'] = 'parent' render_tile(root, request, 'add') self.assertEqual( request.environ['redirect'].location, 'http://example.com/' ) del request.environ['redirect'] with self.layer.authenticated('manager'): came_from = compat.quote('http://example.com/foo/bar?baz=1') request.params['came_from'] = came_from render_tile(root, request, 'add') self.assertEqual( request.environ['redirect'].location, 'http://example.com/foo/bar?baz=1' ) # Render with ajax flag with self.layer.authenticated('manager'): request.params['ajax'] = '1' render_tile(root, request, 'add') self.assertTrue(isinstance( request.environ['cone.app.continuation'][0], AjaxEvent )) # Check the modified model self.assertEqual(root.keys(), ['somechild']) self.assertEqual(root['somechild'].attrs.title, 'Some Child') # Add view with self.layer.authenticated('manager'): request = self.layer.new_request() request.params['factory'] = 'mynode' request.params['action.addform.add'] = '1' request.params['addform.id'] = 'somechild' request.params['addform.title'] = 'Some Child' res = add(root, request) self.assertTrue(isinstance(res, HTTPFound)) with self.layer.authenticated('manager'): request.params['ajax'] = '1' res = str(add(root, request)) self.assertTrue(res.find('parent.bdajax.render_ajax_form') != -1)
def test_copysupport(self): @node_info( name='copy_support_node_a', title='CopySupportNodeA', addables=['copy_support_node_a', 'copy_support_node_b']) class CopySupportNodeA(CopySupportNode): pass @node_info( name='copy_support_node_b', title='CopySupportNodeB', addables=['copy_support_node_b']) class CopySupportNodeB(CopySupportNode): pass root = CopySupportNodeA() source = root['source'] = CopySupportNodeA() source['a_child'] = CopySupportNodeA() source['b_child'] = CopySupportNodeB() target = root['target'] = CopySupportNodeB() request = self.layer.new_request() copy_url = compat.quote(make_url(request, node=source['a_child'])) request.cookies['cone.app.copysupport.copy'] = copy_url paste_tile = PasteAction(None, 'render', '') paste_tile(target, request) self.checkOutput(""" Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Violation. 'CopySupportNodeB' is not allowed to contain 'CopySupportNodeA' """, request.environ['cone.app.continuation'][0].payload) copy_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.copy'] = copy_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) target.messages = [] self.checkOutput(""" cone.app.copysupport.copy=; Max-Age=0; Path=/; expires=... """, request.response.headers['Set-Cookie']) self.assertTrue(isinstance( request.environ['cone.app.continuation'][0], AjaxMessage )) self.assertTrue(isinstance( request.environ['cone.app.continuation'][1], AjaxAction )) self.assertTrue(isinstance( request.environ['cone.app.continuation'][2], AjaxEvent )) self.checkOutput(""" <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child """, root.treerepr()) paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) target.messages = [] self.checkOutput(""" <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 """, root.treerepr()) cut_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.cookies['cone.app.copysupport.copy'] paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) self.assertEqual(source.messages, ['Called: source']) target.messages = [] source.messages = [] self.checkOutput(""" cone.app.copysupport.cut=; Max-Age=0; Path=/; expires=... """, request.response.headers['Set-Cookie']) self.checkOutput(""" <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) cut_url = compat.quote(make_url(request, node=source['a_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.checkOutput(""" <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) self.checkOutput(""" Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Violation. 'CopySupportNodeB' is not allowed to contain 'CopySupportNodeA' """, request.environ['cone.app.continuation'][0].payload) cut_url = compat.quote(make_url(request, node=source)) del request.environ['cone.app.continuation'] request.cookies['cone.app.copysupport.cut'] = cut_url paste_tile(root['source']['a_child'], request) self.checkOutput(""" Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste cut object to child of it: source """, request.environ['cone.app.continuation'][0].payload) cut_url = '::'.join([ compat.quote(make_url(request, node=target['b_child'])), compat.quote(make_url(request, node=target['b_child-1'])), ]) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(source, request) self.assertEqual(source.messages, ['Called: source']) self.assertEqual(target.messages, ['Called: target']) source.messages = [] target.messages = [] self.checkOutput(""" <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) root['unknown_source'] = BaseNode() root['unknown_target'] = BaseNode() cut_url = compat.quote(make_url(request, node=root['unknown_source'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.checkOutput(""" Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste 'unknown_source'. Unknown source """, request.environ['cone.app.continuation'][0].payload) cut_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(root['unknown_target'], request) self.checkOutput(""" Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste to 'unknown_target'. Unknown target """, request.environ['cone.app.continuation'][0].payload) del request.cookies['cone.app.copysupport.cut'] del request.environ['cone.app.continuation'] paste_tile(root['unknown_target'], request) self.assertEqual( request.environ['cone.app.continuation'][0].payload, u'Nothing to paste' )
def test_copysupport(self): @node_info(name='copy_support_node_a', title='CopySupportNodeA', addables=['copy_support_node_a', 'copy_support_node_b']) class CopySupportNodeA(CopySupportNode): pass @node_info(name='copy_support_node_b', title='CopySupportNodeB', addables=['copy_support_node_b']) class CopySupportNodeB(CopySupportNode): pass root = CopySupportNodeA() source = root['source'] = CopySupportNodeA() source['a_child'] = CopySupportNodeA() source['b_child'] = CopySupportNodeB() target = root['target'] = CopySupportNodeB() request = self.layer.new_request() copy_url = compat.quote(make_url(request, node=source['a_child'])) request.cookies['cone.app.copysupport.copy'] = copy_url paste_tile = PasteAction(None, 'render', '') paste_tile(target, request) self.checkOutput( """ Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Violation. 'CopySupportNodeB' is not allowed to contain 'CopySupportNodeA' """, request.environ['cone.app.continuation'][0].payload) copy_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.copy'] = copy_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) target.messages = [] self.checkOutput( """ cone.app.copysupport.copy=; Max-Age=0; Path=/; expires=... """, request.response.headers['Set-Cookie']) self.assertTrue( isinstance(request.environ['cone.app.continuation'][0], AjaxMessage)) self.assertTrue( isinstance(request.environ['cone.app.continuation'][1], AjaxEvent)) self.assertEqual(request.environ['cone.app.continuation'][1].target, 'http://example.com/target?contenttile=listing') self.checkOutput( """ <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child """, root.treerepr()) target.properties.action_paste_tile = 'custom' del request.environ['cone.app.continuation'] paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) target.messages = [] self.assertEqual(request.environ['cone.app.continuation'][1].target, 'http://example.com/target?contenttile=custom') self.checkOutput( """ <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 """, root.treerepr()) cut_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.cookies['cone.app.copysupport.copy'] del request.environ['cone.app.continuation'] paste_tile(target, request) self.assertEqual(target.messages, ['Called: target']) self.assertEqual(source.messages, ['Called: source']) target.messages = [] source.messages = [] self.checkOutput( """ cone.app.copysupport.cut=; Max-Age=0; Path=/; expires=... """, request.response.headers['Set-Cookie']) self.checkOutput( """ <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) cut_url = compat.quote(make_url(request, node=source['a_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.checkOutput( """ <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) self.checkOutput( """ Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Violation. 'CopySupportNodeB' is not allowed to contain 'CopySupportNodeA' """, request.environ['cone.app.continuation'][0].payload) cut_url = compat.quote(make_url(request, node=source)) del request.environ['cone.app.continuation'] request.cookies['cone.app.copysupport.cut'] = cut_url paste_tile(root['source']['a_child'], request) self.checkOutput( """ Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste cut object to child of it: source """, request.environ['cone.app.continuation'][0].payload) cut_url = '::'.join([ compat.quote(make_url(request, node=target['b_child'])), compat.quote(make_url(request, node=target['b_child-1'])), ]) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(source, request) self.assertEqual(source.messages, ['Called: source']) self.assertEqual(target.messages, ['Called: target']) source.messages = [] target.messages = [] self.checkOutput( """ <class '...CopySupportNodeA'>: None <class '...CopySupportNodeA'>: source <class '...CopySupportNodeA'>: a_child <class '...CopySupportNodeB'>: b_child <class '...CopySupportNodeB'>: b_child-1 <class '...CopySupportNodeB'>: target <class '...CopySupportNodeB'>: b_child-2 """, root.treerepr()) root['unknown_source'] = BaseNode() root['unknown_target'] = BaseNode() cut_url = compat.quote(make_url(request, node=root['unknown_source'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(target, request) self.checkOutput( """ Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste 'unknown_source'. Unknown source """, request.environ['cone.app.continuation'][0].payload) cut_url = compat.quote(make_url(request, node=source['b_child'])) request.cookies['cone.app.copysupport.cut'] = cut_url del request.environ['cone.app.continuation'] paste_tile(root['unknown_target'], request) self.checkOutput( """ Pasted 0 items<br /><strong>Pasting of 1 items failed</strong><br />Cannot paste to 'unknown_target'. Unknown target """, request.environ['cone.app.continuation'][0].payload) del request.cookies['cone.app.copysupport.cut'] del request.environ['cone.app.continuation'] paste_tile(root['unknown_target'], request) self.assertEqual(request.environ['cone.app.continuation'][0].payload, u'Nothing to paste')