def test_workflow_guarded_transitions(self): spec = Specification(title='Workflow', initial_status_title='Private') spec.role_mapping['employee'] = 'Editor' spec.role_mapping['boss'] = 'Reviewer' private = spec.states['Private'] = Status('Private', [ ('employee', 'publish'), ('boss', 'publish')]) published = spec.states['Published'] = Status('Published', [ ('boss', 'retract')]) spec.transitions.append(Transition('publish', private, published)) spec.transitions.append(Transition('retract', published, private)) spec.validate() result = StringIO() WorkflowGenerator()('wf', spec).write(result) expected = workflowxml.WORKFLOW % { 'id': 'wf', 'title': 'Workflow', 'description': '', 'initial_status': 'wf--STATUS--private'} % ''.join(( workflowxml.STATUS % { 'title': 'Private', 'id': 'wf--STATUS--private', } % workflowxml.EXIT_TRANSITION % ( 'wf--TRANSITION--publish--private_published'), workflowxml.STATUS % { 'title': 'Published', 'id': 'wf--STATUS--published', } % workflowxml.EXIT_TRANSITION % ( 'wf--TRANSITION--retract--published_private'), workflowxml.TRANSITION % { 'id': 'wf--TRANSITION--publish--private_published', 'title': 'publish', 'target_state': 'wf--STATUS--published', 'guards': workflowxml.GUARDS % ''.join(( workflowxml.GUARD_ROLE % 'Editor', workflowxml.GUARD_ROLE % 'Reviewer', ))}, workflowxml.TRANSITION % { 'id': 'wf--TRANSITION--retract--published_private', 'title': 'retract', 'target_state': 'wf--STATUS--private', 'guards': workflowxml.GUARDS % ( workflowxml.GUARD_ROLE % 'Reviewer', )}, )) self.assert_definition_xmls(expected, result.getvalue())
def test_augmenting_missing_src_status(self): obj = Transition('foo', src_status_title='Bar', dest_status_title='Baz') states = {'Baz': Status('Baz', [])} with self.assertRaises(ValueError) as cm: obj.augment_states(states) self.assertEquals('No such src_status "Bar" (foo).', str(cm.exception))
def test_augmenting_states(self): obj = Transition('foo', src_status_title='Bar', dest_status_title='Baz') states = {'Bar': Status('Bar', []), 'Baz': Status('Baz', [])} obj.augment_states(states) self.assertEquals(obj.src_status, states['Bar']) self.assertEquals(obj.dest_status, states['Baz'])
def test_workflow_with_custom_transition_url(self): spec = Specification( title='WF', initial_status_title='Foo', custom_transition_url='%%(content_url)s/custom_wf_action' '?workflow_action=%(transition)s') foo = spec.states['Foo'] = Status('Foo', []) bar = spec.states['Bar'] = Status('Bar', []) spec.transitions.append(Transition('b\xc3\xa4rize', foo, bar)) spec.transitions.append(Transition('f\xc3\xbcize', bar, foo)) spec.validate() result = StringIO() WorkflowGenerator()('workflow', spec).write(result) expected = workflowxml.WORKFLOW % { 'id': 'workflow', 'title': 'WF', 'description': '', 'initial_status': 'workflow--STATUS--foo'} % ''.join(( workflowxml.STATUS % { 'title': 'Bar', 'id': 'workflow--STATUS--bar', } % (workflowxml.EXIT_TRANSITION % 'workflow--TRANSITION--fuize--bar_foo'), workflowxml.STATUS % { 'title': 'Foo', 'id': 'workflow--STATUS--foo', } % (workflowxml.EXIT_TRANSITION % 'workflow--TRANSITION--barize--foo_bar'), workflowxml.TRANSITION_WITH_CUSTOM_URL % { 'id': 'workflow--TRANSITION--barize--foo_bar', 'title': 'b\xc3\xa4rize', 'target_state': 'workflow--STATUS--bar', 'guards': workflowxml.GUARDS_DISABLED, 'url_viewname': 'custom_wf_action'}, workflowxml.TRANSITION_WITH_CUSTOM_URL % { 'id': 'workflow--TRANSITION--fuize--bar_foo', 'title': 'f\xc3\xbcize', 'target_state': 'workflow--STATUS--foo', 'guards': workflowxml.GUARDS_DISABLED, 'url_viewname': 'custom_wf_action'}, )) self.assert_xml(expected, result.getvalue())
def test_workflow_with_unkown_action_raises(self): self.register_permissions(**{ 'cmf.ModifyPortalContent': 'Modify portal content', 'zope2.View': 'View', 'zope2.AccessContentsInformation': \ 'Access contents information'}) self.map_permissions(['View', 'Access contents information'], 'view') self.map_permissions(['Modify portal content'], 'edit') spec = Specification(title='Workflow', initial_status_title='Foo') spec.role_mapping['writer'] = 'Editor' spec.role_mapping['admin'] = 'Administrator' foo = spec.states['Foo'] = Status('Foo', [ ('writer', 'view'), ('writer', 'edit'), ('writer', 'publish'), ('admin', 'view'), ('admin', 'publish'), ('admin', 'bar')]) spec.transitions.append(Transition('publish', foo, foo)) spec.validate() generator = WorkflowGenerator() with self.assertRaises(Exception) as cm: generator('example-workflow', spec) self.assertEquals('Action "bar" is neither action group nor transition.', str(cm.exception))
def test_allow_only_supported_transition_options(self): with self.assertRaises(ValueError) as cm: Transition('foo', src_status_title='Bar', dest_status_title='Baz', guard_expression='context/allowed') self.assertEquals("Unkown transition options: ('guard_expression',). " "Supported options are: ('guard-expression',)", str(cm.exception))
def _convert_transition_line(self, line): xpr = re.compile(r'([^\(]*?) ?\(([^=]*?) ?=> ?([^\(]*)\)') match = xpr.match(line) if not match: raise ParsingError( 'Transition line has an invalid format: "%s"' % line) title, src_status_title, dest_status_title = match.groups() return Transition(title=title, src_status_title=src_status_title, dest_status_title=dest_status_title)
def test_get_translations(self): spec = Specification(title='Workflow', initial_status_title='Private') spec.role_mapping['employee'] = 'Editor' spec.role_mapping['boss'] = 'Reviewer' spec.role_descriptions['employee'] = 'A regular company employee.' private = spec.states['Private'] = Status('Private', [ ('employee', 'publish'), ('boss', 'publish')]) published = spec.states['Published'] = Status('Published', [ ('boss', 'retract')]) spec.transitions.append(Transition('publish', private, published)) spec.transitions.append(Transition('retract', published, private)) spec.validate() result = WorkflowGenerator().get_translations('wf', spec) self.maxDiff = None self.assertEquals( {'Private': 'Private', 'Published': 'Published', 'publish': 'publish', 'retract': 'retract', 'wf--STATUS--private': 'Private', 'wf--STATUS--published': 'Published', 'wf--TRANSITION--publish--private_published': 'publish', 'wf--TRANSITION--retract--published_private': 'retract', 'wf--ROLE--Editor': 'employee', 'wf--ROLE--Reviewer': 'boss', 'wf--ROLE-DESCRIPTION--Editor': 'A regular company employee.', }, result, 'Translations are wrong')
def test_dest_status_object_or_title_required(self): with self.assertRaises(ValueError) as cm: Transition('foo', src_status_title='Bar') self.assertEquals('dest_status or dest_status_title required.', str(cm.exception))
def test_string_repr(self): private = Status('Private', []) public = Status('Public', []) obj = Transition('publish', private, public) self.assertEquals(unicode(obj), u'<Transition "publish" ["Private" => "Public"]>')
def test_inherited_roles(self): self.register_permissions(**{ 'cmf.ModifyPortalContent': 'Modify portal content', 'zope2.View': 'View', 'zope2.AccessContentsInformation': \ 'Access contents information', 'cmf.ManagePortal': 'Manage portal'}) self.map_permissions(['View', 'Access contents information'], 'view') self.map_permissions(['Modify portal content'], 'edit') spec = Specification( title='Workflow', initial_status_title='Foo', # general inheritance role_inheritance=[('chief', 'admin')]) spec.role_mapping['writer'] = 'Editor' spec.role_mapping['admin'] = 'Administrator' spec.role_mapping['chief'] = 'Manager' spec.role_mapping['reader'] = 'Reader' spec.states['Foo'] = foo = Status( 'Foo', [('writer', 'view'), ('writer', 'edit'), ('writer', 'publish')], # inheritance in status role_inheritance=[('admin', 'writer'), ('reader', 'chief')]) spec.states['Bar'] = bar = Status( 'Bar', [('admin', 'retract')]) spec.transitions.append(Transition('publish', foo, bar)) spec.transitions.append(Transition('retract', bar, foo)) spec.validate() result = StringIO() WorkflowGenerator()('example-workflow', spec).write(result) xml_permissions_declaration = ''.join(( workflowxml.PERMISSION % 'Access contents information', workflowxml.PERMISSION % 'Modify portal content', workflowxml.PERMISSION % 'View', )) xml_foo_defininition = workflowxml.STATUS % { 'title': 'Foo', 'id': 'example-workflow--STATUS--foo', } % ''.join(( workflowxml.EXIT_TRANSITION % ( 'example-workflow--TRANSITION--publish--foo_bar'), (workflowxml.PERMISSION_MAP % 'Access contents information') % ''.join(( workflowxml.PERMISSION_ROLE % 'Administrator', workflowxml.PERMISSION_ROLE % 'Editor', workflowxml.PERMISSION_ROLE % 'Manager', workflowxml.PERMISSION_ROLE % 'Reader')), (workflowxml.PERMISSION_MAP % 'Modify portal content') % ''.join(( workflowxml.PERMISSION_ROLE % 'Administrator', workflowxml.PERMISSION_ROLE % 'Editor', workflowxml.PERMISSION_ROLE % 'Manager', workflowxml.PERMISSION_ROLE % 'Reader')), (workflowxml.PERMISSION_MAP % 'View') % ''.join(( workflowxml.PERMISSION_ROLE % 'Administrator', workflowxml.PERMISSION_ROLE % 'Editor', workflowxml.PERMISSION_ROLE % 'Manager', workflowxml.PERMISSION_ROLE % 'Reader')), )) xml_bar_defininition = workflowxml.STATUS % { 'title': 'Bar', 'id': 'example-workflow--STATUS--bar', } % ''.join(( workflowxml.EXIT_TRANSITION % ( 'example-workflow--TRANSITION--retract--bar_foo'), workflowxml.EMPTY_PERMISSION_MAP % ( 'Access contents information'), workflowxml.EMPTY_PERMISSION_MAP % 'Modify portal content', workflowxml.EMPTY_PERMISSION_MAP % 'View', )) xml_publish_transition = workflowxml.TRANSITION % { 'id': 'example-workflow--TRANSITION--publish--foo_bar', 'title': 'publish', 'target_state': 'example-workflow--STATUS--bar', 'guards': workflowxml.GUARDS % ''.join(( workflowxml.GUARD_ROLE % 'Administrator', workflowxml.GUARD_ROLE % 'Editor', workflowxml.GUARD_ROLE % 'Manager', workflowxml.GUARD_ROLE % 'Reader', ))} xml_retract_transition = workflowxml.TRANSITION % { 'id': 'example-workflow--TRANSITION--retract--bar_foo', 'title': 'retract', 'target_state': 'example-workflow--STATUS--foo', 'guards': workflowxml.GUARDS % ''.join(( workflowxml.GUARD_ROLE % 'Administrator', workflowxml.GUARD_ROLE % 'Manager', ))} expected = workflowxml.WORKFLOW % { 'id': 'example-workflow', 'title': 'Workflow', 'description': '', 'initial_status': 'example-workflow--STATUS--foo'} % ''.join(( xml_permissions_declaration, xml_bar_defininition, xml_foo_defininition, xml_publish_transition, xml_retract_transition)) self.assert_xml(expected, result.getvalue())