def test_ActionDelete(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() ActionContext(model, request, 'content') action = ActionDelete() self.assertEqual(action(model, request), u'') model.properties.action_delete = True self.assertEqual(action(model, request), u'') with self.layer.authenticated('editor'): self.assertEqual(action(model, request), u'') with self.layer.authenticated('manager'): rendered = action(model, request) self.checkOutput( """ ...<a id="toolbaraction-delete" href="#" ajax:bind="click" ajax:target="http://example.com/root/model" ajax:action="delete:NONE:NONE" ajax:confirm="Do you really want to delete this Item?" ><span class="ion-trash-a"></span > Delete</a>... """, rendered) model.properties.default_content_tile = 'othertile' self.assertEqual(action(model, request), u'')
def test_personaltools(self): root = BaseNode() request = self.layer.new_request() # Unauthorized res = render_tile(root, request, 'personaltools') self.assertFalse(res.find('id="personaltools"') != -1) # Authorized with self.layer.authenticated('max'): res = render_tile(root, request, 'personaltools') self.assertTrue(res.find('id="personaltools"') != -1) self.assertTrue(res.find('href="http://example.com/logout"') != -1) self.assertFalse(res.find('href="http://example.com/settings"') != -1) # No settings link if empty settings root['settings'] = BaseNode() with self.layer.authenticated('max'): res = render_tile(root, request, 'personaltools') self.assertFalse(res.find('href="http://example.com/settings"') != -1) # Settings link if settings container contains children root['settings']['mysettings'] = BaseNode() with self.layer.authenticated('max'): res = render_tile(root, request, 'personaltools') self.assertTrue(res.find('href="http://example.com/settings"') != -1)
def test_forbidden(self): # Forbidden tile root = get_root() model = root['model'] = BaseNode() request = self.layer.new_request() self.checkOutput(""" \n\n <div>\n <h1>Unauthorized</h1>\n <p>You are not allowed to access this resource.</p>\n </div>\n\n\n """, render_tile(model, request, 'unauthorized')) del root['model'] # Forbidden view root = get_root() model = root['model'] = BaseNode() request = self.layer.new_request() request.context = model res = forbidden_view(request).text self.assertTrue(res.find('id="input-loginform-login"') > -1) with self.layer.authenticated('admin'): request = self.layer.new_request() request.context = model res = forbidden_view(request).text self.assertTrue(res.find('<h1>Unauthorized</h1>') > -1) del root['model']
def test_ActionSharing(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() action = ActionSharing() self.assertFalse(IPrincipalACL.providedBy(model)) self.assertEqual(action(model, request), u'') sharingmodel = parent['sharingmodel'] = SharingNode() self.assertTrue(IPrincipalACL.providedBy(sharingmodel)) self.assertEqual(action(sharingmodel, request), u'') with self.layer.authenticated('editor'): rule = request.has_permission('manage_permissions', sharingmodel) self.assertTrue(isinstance(rule, ACLDenied)) self.assertEqual(action(sharingmodel, request), u'') with self.layer.authenticated('manager'): rule = request.has_permission('manage_permissions', sharingmodel) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = action(sharingmodel, request) self.checkOutput( """ ...<a id="toolbaraction-share" href="http://example.com/root/sharingmodel/sharing" ajax:bind="click" ajax:target="http://example.com/root/sharingmodel" ajax:action="sharing:#content:inner" ajax:path="href" ><span class="glyphicon glyphicon-share"></span > Sharing</a>... """, rendered)
def __delitem__(self, key): todelete = self[key] if hasattr(self, '_todelete'): self._todelete.append(todelete) else: self._todelete = [todelete] BaseNode.__delitem__(self, key)
def test_ActionRemoveReference(self): model = BaseNode() request = self.layer.new_request() request.params['referencable'] = 'ref_node' request.params['selected'] = '' request.params['root'] = '/' action = ActionRemoveReference() self.assertEqual(action(model, request), u'') with self.layer.authenticated('manager'): self.assertEqual(action(model, request), u'') model = RefNode(name='model') rendered = action(model, request) expected = 'class="removereference disabled"' self.assertTrue(rendered.find(expected) > -1) expected = 'title="Remove reference"' self.assertTrue(rendered.find(expected) > -1) expected = '<span class="ion-minus-round">' self.assertTrue(rendered.find(expected) > -1) expected = '<span class="reftitle" style="display:none;">model</span>' self.assertTrue(rendered.find(expected) > -1) request.params['selected'] = str(model.uuid) rendered = action(model, request) expected = 'class="removereference"' self.assertTrue(rendered.find(expected) > -1) action = ActionRemoveReference() action.model = BaseNode(name='model') action.request = self.layer.new_request() self.assertFalse(action.enabled)
def test_ActionState(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() action = ActionState() self.assertFalse(IWorkflowState.providedBy(model)) self.assertEqual(action(model, request), u'') wfmodel = parent['wfmodel'] = WorkflowNode() self.assertTrue(IWorkflowState.providedBy(wfmodel)) self.assertEqual(action(wfmodel, request), u'') with self.layer.authenticated('editor'): rule = request.has_permission('change_state', wfmodel) self.assertTrue(isinstance(rule, ACLDenied)) self.assertEqual(action(wfmodel, request), u'') with self.layer.authenticated('manager'): rule = request.has_permission('change_state', wfmodel) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = action(wfmodel, request) self.checkOutput( """ ...<li class="dropdown">... <a href="#" ajax:bind="click" ajax:target="http://example.com/root/wfmodel?do_transition=initial_2_final" ajax:action="wf_dropdown:NONE:NONE">initial_2_final</a>... """, rendered)
def test_ActionEdit(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() ActionContext(model, request, 'listing') action = ActionEdit() self.assertEqual(action(model, request), u'') model.properties.action_edit = True self.assertEqual(action(model, request), u'') with self.layer.authenticated('viewer'): self.assertEqual(action(model, request), u'') with self.layer.authenticated('editor'): rendered = action(model, request) self.checkOutput( """ ...<a id="toolbaraction-edit" href="http://example.com/root/model/edit" ajax:bind="click" ajax:target="http://example.com/root/model" ajax:action="edit:#content:inner" ajax:path="href" ><span class="glyphicon glyphicon-pencil"></span > Edit</a>... """, rendered)
def test_ContextMenuDropdown(self): cmd = ContextMenuDropdown(title='Dropdown') def add_action(): cmd['invalid'] = Action() err = self.expectError(ValueError, add_action) expected = ('Only ``LinkAction`` deriving objects can be added ' 'to ``ContextMenuDropdown`` instances.') self.assertEqual(str(err), expected) class MyLinkAction(LinkAction): id = 'myaction' icon = 'myicon' text = 'My Action' href = 'http://example.com' cmd = ContextMenuDropdown(title='Dropdown') cmd.model = BaseNode() cmd.request = self.layer.new_request() cmd['link'] = MyLinkAction() self.assertTrue(cmd.display) cmd['link'].display = False self.assertFalse(cmd.display) cmd = ContextMenuDropdown(title='Dropdown') cmd['link'] = MyLinkAction() model = BaseNode() request = self.layer.new_request() res = cmd(model, request) self.assertTrue(res.find('<li class="dropdown">') > -1)
def test_ViewLink(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() ActionContext(model, request, 'content') action = ViewLink() self.assertEqual(action(model, request), u'') model.properties.action_view = True self.assertEqual(action(model, request), u'') with self.layer.authenticated('viewer'): rendered = action(model, request) self.checkOutput( """ ...<a id="toolbaraction-view" href="http://example.com/root/model" class="selected" ajax:bind="click" ajax:target="http://example.com/root/model" ajax:action="content:#content:inner" ajax:path="href" > model</a>... """, rendered)
def test_not_found(self): # Not Found tile root = get_root() model = root['model'] = BaseNode() request = self.layer.new_request() self.checkOutput(""" \n\n <div>\n <h1>Not Found</h1>\n <p>The requested resource cannot be found.</p>\n </div>\n\n\n """, render_tile(model, request, 'not_found')) del root['model'] # Not Found view root = get_root() model = root['model'] = BaseNode() request = self.layer.new_request() request.context = model res = not_found_view(request).text self.assertTrue(res.find('<h1>Not Found</h1>') > -1) with self.layer.authenticated('admin'): request = self.layer.new_request() request.context = model res = not_found_view(request).text self.assertTrue(res.find('<h1>Not Found</h1>') > -1) del root['model']
def test_choose_name(self): container = BaseNode() container['a'] = BaseNode() self.assertEqual(choose_name(container, 'a'), 'a-1') container['a-1'] = BaseNode() self.assertEqual(choose_name(container, 'a'), 'a-2') container['b-1'] = BaseNode() self.assertEqual(choose_name(container, 'b'), 'b')
def __init__(self, name=None, _app_path=None): """``_app_path`` defines an alternative path for app root and is for testing purposes only """ BaseNode.__init__(self, name) path = os.path.join(_app_path or APP_PATH, 'etc', 'ldap.xml') self._config = XMLProperties(path) self.invalidate()
def test_ActionUp(self): parent = BaseNode(name='root') model = parent['model'] = BaseNode() request = self.layer.new_request() action = ActionUp() self.assertEqual(action(model, request), u'') model.properties.action_up = True self.assertEqual(action(model, request), u'') with self.layer.authenticated('viewer'): rendered = action(model, request) self.checkOutput( """ ...<a id="toolbaraction-up" href="http://example.com/root" ajax:bind="click" ajax:target="http://example.com/root?contenttile=listing" ajax:event="contextchanged:#layout" ajax:path="href" ><span class="glyphicon glyphicon-arrow-up"></span > One level up</a>... """, rendered) model.properties.action_up_tile = 'otherparentcontent' rendered = action(model, request) self.checkOutput( """ ...<a id="toolbaraction-up" href="http://example.com/root" ajax:bind="click" ajax:target="http://example.com/root?contenttile=otherparentcontent" ajax:event="contextchanged:#layout" ajax:path="href" ><span class="glyphicon glyphicon-arrow-up"></span > One level up</a>... """, rendered) default = model['default'] = BaseNode() default.properties.action_up = True model.properties.default_child = 'default' rendered = action(default, request) self.checkOutput( """ ...<a id="toolbaraction-up" href="http://example.com/root" ajax:bind="click" ajax:target="http://example.com/root?contenttile=listing" ajax:event="contextchanged:#layout" ajax:path="href" ><span class="glyphicon glyphicon-arrow-up"></span > One level up</a>... """, rendered)
def test_ReferenceBrowserModelMixin(self): model = BaseNode() a = model['a'] = BaseNode() aa = model['a']['a'] = BaseNode() b = model['b'] = BaseNode() ref_model_mixin = ReferenceBrowserModelMixin() ref_model_mixin.model = model request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '/' self.assertEqual(ref_model_mixin.referencable_root, model) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '' self.assertEqual(ref_model_mixin.referencable_root, model) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '/a' self.assertEqual(ref_model_mixin.referencable_root, a) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '/a/a' self.assertEqual(ref_model_mixin.referencable_root, aa) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = 'b' self.assertEqual(ref_model_mixin.referencable_root, b) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = 'c' self.expectError(KeyError, lambda: ref_model_mixin.referencable_root) ref_model_mixin.model = aa request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = 'a/a' self.assertEqual(ref_model_mixin.referencebrowser_model, aa) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = 'a' self.assertEqual(ref_model_mixin.referencebrowser_model, aa) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '' self.assertEqual(ref_model_mixin.referencebrowser_model, aa) ref_model_mixin.model = b request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = '' self.assertEqual(ref_model_mixin.referencebrowser_model, b) request = ref_model_mixin.request = self.layer.new_request() request.params['root'] = 'a' self.assertEqual(ref_model_mixin.referencebrowser_model, a)
def test_layout_config_tile(self): # B/C from layout attribute tile = LayoutConfigTile() tile.model = LayoutConfigNode() tile.request = self.layer.new_request() config = tile.config self.assertIsInstance(config, LayoutConfig) # B/C from layout adapter request = self.layer.new_request() request.registry.registerAdapter(default_layout) model = BaseNode() config = request.registry.queryAdapter(model, ILayoutConfig, default=None) self.assertIsInstance(config, LayoutConfig) tile = LayoutConfigTile() tile.model = model tile.request = request config = tile.config self.assertIsInstance(config, LayoutConfig) request.registry.unregisterAdapter(default_layout) config = request.registry.queryAdapter(model, ILayoutConfig, default=None) self.assertEqual(config, None) # from layout_config tile = LayoutConfigTile() tile.model = BaseNode() tile.request = self.layer.new_request() config = tile.config self.assertIsInstance(config, DefaultLayoutConfig) # default child class ChildNode(BaseNode): pass @layout_config(ChildNode) class ChildNodeLayout(LayoutConfig): pass model = BaseNode() model['child'] = ChildNode() model.properties.default_child = 'child' tile = LayoutConfigTile() tile.model = model tile.request = self.layer.new_request() config = tile.config self.assertIsInstance(config, ChildNodeLayout) del layout_config._registry[ChildNode]
def test_PrincipalIdFieldFactory(self): class PrincipalAddForm(Tile): action_resource = 'add' class PrincipalEditForm(Tile): action_resource = 'edit' factory = PrincipalIdFieldFactory(PrincipalExistsExtractor) # principal add form form = PrincipalAddForm() form.model = BaseNode() form.request = self.layer.new_request() widget = factory(form, 'Principal ID', UNSET) self.assertEqual(widget.blueprints, [ 'field', '*ascii', '*exists', 'label', 'error', 'text' ]) self.assertEqual(widget.getter, UNSET) self.assertEqual(widget.properties, { 'label': 'Principal ID', 'required': 'no_field_value_defined', 'ascii': True }) self.assertEqual( widget.custom['ascii']['extractors'], [ascii_extractor] ) self.assertTrue(isinstance( widget.custom['exists']['extractors'][0], PrincipalExistsExtractor )) self.assertEqual(widget.mode, 'edit') # principal edit form form = PrincipalEditForm() form.model = BaseNode() form.request = self.layer.new_request() widget = factory(form, 'Principal ID', 'pid') self.assertEqual(widget.getter, 'pid') self.assertEqual(widget.properties, { 'label': 'Principal ID', 'required': 'no_field_value_defined', 'ascii': True }) self.assertEqual( widget.custom['ascii']['extractors'], [ascii_extractor] ) self.assertTrue(isinstance( widget.custom['exists']['extractors'][0], PrincipalExistsExtractor )) self.assertEqual(widget.mode, 'display')
def test_make_url(self): root = BaseNode() root['child'] = BaseNode() request = self.layer.new_request() self.assertEqual(make_url(request), 'http://example.com/') self.assertEqual(make_url(request, path=['1', '2', '3']), 'http://example.com/1/2/3') self.assertEqual(make_url(request, node=root['child']), 'http://example.com/child') self.assertEqual(make_url(request, node=root['child'], resource='foo'), 'http://example.com/child/foo') self.assertEqual( make_url(request, node=root['child'], resource='foo', query='&a=1'), 'http://example.com/child/foo&a=1')
def test_ActionAdd(self): info = NodeInfo() info.title = 'Addable' info.addables = ['addable'] register_node_info('addable', info) action = ActionAdd() addmodel = BaseNode() request = self.layer.new_request() ActionContext(addmodel, request, 'listing') self.assertEqual(action(addmodel, request), u'') with self.layer.authenticated('viewer'): rule = request.has_permission('add', addmodel) self.assertTrue(isinstance(rule, ACLDenied)) self.assertEqual(action(addmodel, request), u'') with self.layer.authenticated('editor'): rule = request.has_permission('add', addmodel) self.assertTrue(isinstance(rule, ACLAllowed)) self.assertEqual(action(addmodel, request), u'') addmodel.node_info_name = 'addable' self.assertTrue(addmodel.nodeinfo is info) rendered = action(addmodel, request) self.checkOutput( """ ...<li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <span>Add</span> <span class="caret"></span> </a> <ul class="dropdown-menu" role="addmenu"> <li> <a href="http://example.com/add?factory=addable" ajax:bind="click" ajax:target="http://example.com/?factory=addable" ajax:action="add:#content:inner" ajax:path="href"> <span class="glyphicon glyphicon-asterisk"></span> Addable </a> </li> </ul> </li>... """, rendered)
def test_filtered_children(self): root = BaseNode() child_1 = root['1'] = BaseNode() md_1 = child_1.metadata md_1.title = 'Child 1' md_1.creator = 'max' child_2 = root['2'] = BaseNode() md_2 = child_2.metadata md_2.title = 'Child 2' md_2.creator = 'sepp' tmpl = 'cone.app:browser/templates/table.pt' contents = ContentsTile(tmpl, None, 'contents') contents.model = root contents.request = self.layer.new_request() res = contents.filtered_children self.assertEqual(res, []) contents.request = self.layer.new_request() with self.layer.authenticated('max'): res = contents.filtered_children self.assertEqual(len(res), 2) request = contents.request = self.layer.new_request() request.params['term'] = 'sepp' with self.layer.authenticated('max'): res = contents.filtered_children self.assertEqual(len(res), 1) request = contents.request = self.layer.new_request() request.params['term'] = 'Child 1' with self.layer.authenticated('max'): res = contents.filtered_children self.assertEqual(len(res), 1) request = contents.request = self.layer.new_request() request.params['term'] = 'hild' with self.layer.authenticated('max'): res = contents.filtered_children self.assertEqual(len(res), 2) request = contents.request = self.layer.new_request() request.params['term'] = 'foo' with self.layer.authenticated('max'): res = contents.filtered_children self.assertEqual(len(res), 0)
def test_YAMLForm(self): with self.layer.hook_tile_reg(): @tile(name='yamlsubscriptionform') @plumbing(YAMLForm) class YAMLSubscriptionForm(Form): action_resource = 'yamlsubscriptionform' form_template = 'cone.app.testing:dummy_form.yaml' model = BaseNode() model.__name__ = 'dummymodel' request = self.layer.new_request() with self.layer.authenticated('max'): rendered = render_tile(model, request, 'yamlsubscriptionform') expected = ( 'action="http://example.com/dummymodel/yamlsubscriptionform"' ) self.assertTrue(rendered.find(expected) > -1) # Instead of ``form_template`` attribute, ``form_template_path`` can be # used for backward compatibility with self.layer.hook_tile_reg(): @tile(name='yamlsubscriptionform2') class YAMLSubscriptionForm2(YAMLSubscriptionForm): action_resource = 'yamlsubscriptionform2' form_template = None form_template_path = 'cone.app.testing:dummy_form.yaml' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'yamlsubscriptionform2') expected = ( 'action="http://example.com/dummymodel/yamlsubscriptionform2"' ) self.assertTrue(rendered.find(expected) > -1) # form flavor add renders form action URL on parent root = BaseNode(name='root') model = root['child'] = BaseNode() YAMLSubscriptionForm.form_flavor = 'add' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'yamlsubscriptionform') expected = ( 'action="http://example.com/root/yamlsubscriptionform"' ) self.assertTrue(rendered.find(expected) > -1)
def test_TableBatch(self): model = BaseNode() request = self.layer.new_request() table = DummyTable('cone.app:browser/templates/table.pt', None, 'table') table.request = request batch = TableBatch(table) batch.model = model batch.request = request self.assertEqual(batch.vocab, [{ 'current': True, 'visible': True, 'url': 'http://example.com/?b_page=0&size=10', 'page': '1' }, { 'current': False, 'visible': True, 'url': 'http://example.com/?b_page=1&size=10', 'page': '2' }, { 'current': False, 'visible': True, 'url': 'http://example.com/?b_page=2&size=10', 'page': '3' }])
def test_GroupExistsExtractor(self): root = get_root() groups = root['groups'] add_model = BaseNode(parent=groups) extractor = GroupExistsExtractor(add_model) widget = factory( '*exists:text', name='group_id', custom={'exists': {'extractors': [extractor]}} ) # test already exists request = {'group_id': 'group_exists'} data = widget.extract(request=request) self.assertTrue(data.has_errors) self.assertEqual( data.errors, [ExtractionError('group_already_exists')] ) # test not already exists request = {'group_id': 'new_group_id'} data = widget.extract(request=request) self.assertFalse(data.has_errors) self.assertEqual(data.extracted, 'new_group_id')
def test_ActionContext(self): model = BaseNode() request = self.layer.new_request() ac = ActionContext(model, request, 'tile') self.assertTrue(request.environ['action_context'] is ac) self.assertTrue(get_action_context(request) is ac) self.assertEqual(ac.scope, 'tile') request.params['bdajax.action'] = 'ajaxaction' self.assertEqual(ac.scope, 'ajaxaction') request.params['bdajax.action'] = 'layout' self.assertEqual(ac.scope, 'content') request.params['contenttile'] = 'contenttile' self.assertEqual(ac.scope, 'contenttile') class PropNode(BaseNode): properties = None node = PropNode() node.properties = Properties() node.properties.default_child = 'a' node['a'] = PropNode() node['a'].properties = Properties() node['a'].properties.default_content_tile = 'default' request = self.layer.new_request() ac = ActionContext(node, request, 'content') self.assertEqual(ac.scope, 'default')
def test_contextmenu(self): with self.layer.authenticated('manager'): parent = BaseNode('root') model = parent['model'] = SharingNode() model.properties.action_up = True model.properties.action_view = True model.properties.action_list = True model.properties.action_edit = True model.properties.action_delete = True # XXX: model.properties.action_delete_children = True request = self.layer.new_request() ActionContext(model, request, 'content') rendered = render_tile(model, request, 'contextmenu') self.assertTrue(rendered.find('toolbaraction-up') > -1) self.assertTrue(rendered.find('toolbaraction-view') > -1) self.assertTrue(rendered.find('toolbaraction-list') > -1) self.assertTrue(rendered.find('toolbaraction-edit') > -1) self.assertTrue(rendered.find('toolbaraction-delete') > -1) self.assertTrue(rendered.find('toolbaraction-share') > -1) model = CopySupportNode() ActionContext(model, request, 'listing') rendered = render_tile(model, request, 'contextmenu') self.assertTrue(rendered.find('toolbaraction-cut') > -1) self.assertTrue(rendered.find('toolbaraction-copy') > -1) self.assertTrue(rendered.find('toolbaraction-paste') > -1)
def test_col_defs(self): model = BaseNode() request = self.layer.new_request() table = DummyTable('cone.app:browser/templates/table.pt', None, 'table') # In order to get row_data rendered inside table, column definitions # must be defined self.assertEqual(table.col_defs, []) res = table(model, request) self.assertFalse(res.find('Col 1 Value') > -1) self.assertFalse(res.find('Col 2 Value') > -1) table.col_defs = [{ 'id': 'col_1', 'title': 'Col 1', 'sort_key': 'col_1', 'sort_title': 'Sort by col 1', 'content': 'string' }, { 'id': 'col_2', 'title': 'Col 2', 'sort_key': 'col_2', 'sort_title': 'Sort by col 2', 'content': 'string' }] res = table(model, request) self.assertTrue(res.find('Col 1 Value') > -1) self.assertTrue(res.find('Col 2 Value') > -1)
def test_creation_metadata(self): # Creation metadata node = BaseNode() with self.layer.authenticated('editor'): self.assertFalse('creator' in node.attrs) self.assertFalse('created' in node.attrs) self.assertFalse('modified' in node.attrs) add_creation_metadata(self.layer.new_request(), node.attrs) self.assertTrue('creator' in node.attrs) self.assertTrue('created' in node.attrs) self.assertTrue('modified' in node.attrs) self.assertEqual(node.attrs['creator'], 'editor') created = node.attrs['created'] modified = node.attrs['modified'] self.assertTrue(isinstance(created, datetime)) self.assertTrue(isinstance(modified, datetime)) self.assertTrue(created == modified) update_creation_metadata(self.layer.new_request(), node.attrs) self.assertTrue(isinstance(node.attrs['created'], datetime)) self.assertTrue(isinstance(node.attrs['modified'], datetime)) self.assertTrue(created == node.attrs['created']) self.assertFalse(created == node.attrs['modified'])
def test_ContentForm(self): @plumbing(ContentForm) class MyForm(Form): def prepare(self): form = factory( u'form', name='myform', props={ 'action': self.nodeurl }) self.form = form model = BaseNode() request = self.layer.new_request() content_form = MyForm() content_form.model = model content_form.request = request self.assertTrue(content_form.show_heading) self.assertTrue(content_form.show_contextmenu) # content_form.form_heading is supposed to be overwritten self.assertEqual(content_form.form_heading, 'content_form_heading') with self.layer.authenticated('max'): res = content_form.rendered_contextmenu self.assertTrue(res.find('<div id="contextmenu"') > -1) with self.layer.authenticated('max'): res = content_form(model, request) expected = '<div class="panel-heading content-heading">' self.assertTrue(res.find(expected) > -1)
def test_referencebrowser(self): model = BaseNode() model['a'] = RefNode() request = self.layer.new_request() request.params['referencable'] = 'ref_node' request.params['selected'] = '' request.params['root'] = '/' # Case unauthorized err = self.expectError(HTTPForbidden, render_tile, model, request, 'referencebrowser') self.checkOutput( """ Unauthorized: tile <cone.app.browser.referencebrowser.ReferenceBrowser object at ...> failed permission check """, str(err)) # Case authorized with self.layer.authenticated('max'): res = render_tile(model, request, 'referencebrowser') self.assertTrue(res.find('<div class="referencebrowser">') > -1) self.assertTrue(res.find('<div id="referencebrowser_pathbar"') > -1) self.assertTrue(res.find('<div id="referencebrowser"') > -1)
def test_byline(self): # Byline renders ``model.metadata.creator``, ``model.metadata.created`` # and ``model.metadata.modified`` dt = datetime(2011, 3, 14) root = BaseNode() root.metadata.created = dt root.metadata.modified = dt root.metadata.creator = 'max' request = self.layer.new_request() # Unauthenticated res = render_tile(root, request, 'byline') self.assertEqual(res, u'') # Authenticated with self.layer.authenticated('max'): res = render_tile(root, request, 'byline') self.checkOutput(""" <p class="byline"> <span>Created by</span>: <strong>max</strong>, <span>on</span> <strong>14.03.2011 00:00</strong>. <span>Last modified</span>: <strong>14.03.2011 00:00</strong> </p> """, res)
def test_render_main_template(self): # To change the default layout, change the main template self.checkOutput('...', cone.app.cfg.main_template) main = 'cone.app.testing:dummy_main.pt' cone.app.cfg.main_template = main # An unprotected tile named 'content' registered for all sorts of node with self.layer.hook_tile_reg(): @tile(name='content', permission='login') class ContentTile(Tile): def render(self): return '<div>Content</div>' model = BaseNode() request = self.layer.new_request() # Render main template. The function accepts an optional ``contenttile`` # argument. if omitted, reserved name 'content' is used res = render_main_template(model, request) self.checkOutput( """ <!DOCTYPE html...<div>Content</div>...</html> """, res.text) with self.layer.hook_tile_reg(): @tile(name='othername', permission='login') class OtherContentTile(ContentTile): def render(self): return '<div>Content</div>' res = render_main_template(model, request, contenttile='othername') self.checkOutput( """ <!DOCTYPE html...<div>Content</div>...</html> """, res.text) # Switch back to default main template main = 'cone.app.browser:templates/main.pt' cone.app.cfg.main_template = main # Non authenticated users only gets unprotected content tile, no # controls like navtree, mainmenu, etc res = render_main_template(model, request, contenttile='othername') self.assertFalse(res.text.find('id="mainmenu"') > -1) self.assertFalse(res.text.find('id="navtree"') > -1) self.assertFalse(res.text.find('id="personaltools"') > -1) self.assertTrue(res.text.find('<div>Content</div>') > -1) # Authenticate non privileged with self.layer.authenticated('max'): res = render_main_template(model, request, contenttile='othername') # All tiles protected by 'view' permission are now available to the user self.assertTrue(res.text.find('id="mainmenu"') > -1) self.assertTrue(res.text.find('id="navtree"') > -1) self.assertTrue(res.text.find('id="personaltools"') > -1)
def __getitem__(self, key): try: return BaseNode.__getitem__(self, key) except KeyError: if not key in self.iterkeys(): raise KeyError(key) repositorypath = os.path.join(self.dbpath, key) repo = RepositoryAdapter(Repository(repositorypath), key, self) self[key] = repo return repo
def __getitem__(self, name): # XXX: temporary hack until paster/webob/pyramid handle urllib # quoted slashes in path components name = unquote_slash(name) try: return BaseNode.__getitem__(self, name) except KeyError: if not name in self.iterkeys(): raise KeyError(name) group = Group(self.ldap_groups[name], name, self) self[name] = group return group
def __getitem__(self, name): # XXX: temporary hack until paster/webob/pyramid handle urllib # quoted slashes in path components name = unquote_slash(name) try: return BaseNode.__getitem__(self, name) except KeyError: try: model = self.backend[name] except AttributeError: raise KeyError(name) user = User(model, name, self) self[name] = user return user
def __init__(self, name=None): BaseNode.__init__(self, name) path = os.path.join(APP_PATH, 'etc', 'amqp.cfg') self._config = ConfigProperties(path)
def test_Form(self): formtile = Form(None, None, 'plainform') err = self.expectError( NotImplementedError, formtile.prepare ) expected = '``prepare`` function must be provided by deriving object.' self.assertEqual(str(err), expected) subscriptions = [] with self.layer.hook_tile_reg(): @tile(name='subscriptionform') class SubscriptionForm(Form): ajax = False show = False # test flags next_as_redirect = True continuation_as_list = False def prepare(self): form = factory( u'form', name='subscriptionform', props={ 'action': self.nodeurl, 'class': 'foo', 'class_add': 'bar' }) form['email'] = factory( 'field:label:error:text', props={ 'required': 'No email given', 'label': 'E-Mail', }) form['subscribe'] = factory( 'submit', props={ 'action': 'subscribe', 'expression': True, 'handler': self.subscribe, 'next': self.next, 'label': 'Subscribe', }) self.form = form def subscribe(self, widget, data): # Do subscription here subscriptions.append('subscribe on "%s"' % self.model.name) def next(self, request): url = 'http://example.com' if self.ajax_request: # return as single value, gets list on request.environ cont = AjaxAction(url, 'content', 'inner', '#content') if self.continuation_as_list: return [cont] else: return cont if self.next_as_redirect: return HTTPFound(url) # return anything else to be rendered return '<div>success!</div>' model = BaseNode() model.__name__ = 'dummymodel' request = self.layer.new_request() # Render form. ``form.show`` returns false, render empty string with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, u'') # Set show to True SubscriptionForm.show = True # Render form. no action is triggered and no input is given with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') expected = 'class="bar foo"' self.assertTrue(rendered.find(expected) != -1) expected = 'action="http://example.com/dummymodel"' self.assertTrue(rendered.find(expected) != -1) expected = 'id="form-subscriptionform"' self.assertTrue(rendered.find(expected) != -1) expected = 'name="subscriptionform.email"' self.assertTrue(rendered.find(expected) != -1) expected = 'name="action.subscriptionform.subscribe"' self.assertTrue(rendered.find(expected) != -1) # Trigger subscribe action and set empty email value. Results in a form # with error message since email is required request = self.layer.new_request() request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') expected = 'No email given' self.assertTrue(rendered.find(expected) != -1) # Trigger subscribe action and set valid email value. Now the action # handler and next handler are triggered request = self.layer.new_request() request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] # The form was rendered as non ajax form, so we expect an HTTPFound # instance on request self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) # Even if we commit as ajax form, it is treaten as normal form since # ajax flag is set to False (defaults to True) request = self.layer.new_request() request.params['ajax'] = '1' request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) # We can return markup insted of HTTPFound if we want to render inplace # instead of redirection SubscriptionForm.next_as_redirect = False request = self.layer.new_request() request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '<div>success!</div>') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] self.assertFalse('redirect' in request.environ) SubscriptionForm.next_as_redirect = True # Try with ajax True. SubscriptionForm.ajax = True request = self.layer.new_request() request.params['ajax'] = '1' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') expected = 'class="ajax bar foo"' self.assertTrue(rendered.find(expected) != -1) # If submitted without ajax flag on request, still get HTTPFound request = self.layer.new_request() request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] self.assertTrue(isinstance(request.environ['redirect'], HTTPFound)) # Submit with ajax flag request = self.layer.new_request() request.params['ajax'] = '1' request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] self.assertTrue(isinstance( request.environ['cone.app.continuation'][0], AjaxAction )) # Ajax continuation may be returned as list SubscriptionForm.continuation_as_list = True request = self.layer.new_request() request.params['ajax'] = '1' request.params['action.subscriptionform.subscribe'] = '1' request.params['subscriptionform.email'] = '*****@*****.**' with self.layer.authenticated('max'): rendered = render_tile(model, request, 'subscriptionform') self.assertEqual(rendered, '') self.assertEqual(subscriptions, ['subscribe on "dummymodel"']) subscriptions = [] self.assertTrue(isinstance( request.environ['cone.app.continuation'][0], AjaxAction ))
def test_ProtectedAttributesForm(self): # ProtectedAttributesForm plumbing behavior with self.layer.hook_tile_reg(): @tile(name='protectedattributesform') @plumbing(ProtectedAttributesForm) class MyProtectedAttributesForm(Form): attribute_permissions = { 'protectedfield': ('manage', 'edit') } def prepare(self): form = factory( u'form', name='protectedattributesform', props={ 'action': self.nodeurl, }) form['protectedfield'] = factory( u'field:label:text', value=u'Protectedfield', mode=self.mode_for('protectedfield') ) self.form = form model = BaseNode() model.__name__ = 'dummymodel' request = self.layer.new_request() with self.layer.authenticated('viewer'): rule = request.has_permission('edit', model) self.assertTrue(isinstance(rule, ACLDenied)) rendered = render_tile(model, request, 'protectedattributesform') self.checkOutput(""" <form action="http://example.com/dummymodel" class="ajax" enctype="multipart/form-data" id="form-protectedattributesform" method="post" novalidate="novalidate"></form> """, rendered) with self.layer.authenticated('editor'): rule = request.has_permission('edit', model) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = render_tile(model, request, 'protectedattributesform') self.checkOutput(""" <form ...<div class="display-text" id="display-protectedattributesform-protectedfield">Protectedfield</div></div></form> """, rendered) with self.layer.authenticated('manager'): rule = request.has_permission('manage', model) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = render_tile(model, request, 'protectedattributesform') self.checkOutput(""" <form ...<input class="text" id="input-protectedattributesform-protectedfield" name="protectedattributesform.protectedfield" type="text" value="Protectedfield" /></div></form> """, rendered) # Test default attribute permissions MyProtectedAttributesForm.attribute_permissions = dict() self.assertEqual( MyProtectedAttributesForm.attribute_default_permissions, ('edit', 'view') ) with self.layer.authenticated('viewer'): rule = request.has_permission('view', model) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = render_tile(model, request, 'protectedattributesform') self.checkOutput(""" <form ...<div class="display-text" id="display-protectedattributesform-protectedfield">Protectedfield</div></div></form> """, rendered) with self.layer.authenticated('editor'): rule = request.has_permission('edit', model) self.assertTrue(isinstance(rule, ACLAllowed)) rendered = render_tile(model, request, 'protectedattributesform') self.checkOutput(""" <form ...<input class="text" id="input-protectedattributesform-protectedfield" name="protectedattributesform.protectedfield" type="text" value="Protectedfield" /></div></form> """, rendered)