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_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_get_states(self):
        spec = Specification(title='Workflow',
                             initial_status_title='Private')

        spec.states['Private'] = Status('Private', [])
        spec.states['Published'] = Status('Published', [])
        result = WorkflowGenerator().get_states('wf', spec)

        self.assertEquals(
            ['wf--STATUS--private',
             'wf--STATUS--published'],

            result,
            'Wrong state IDs in generator.get_states()')
    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_includes_general_inheritance(self):
        spec = Specification(title='My Workflow',
                             role_inheritance=[('admin', 'visitor')],
                             role_mapping=ROLE_MAPPING)
        status = Status('Private', [])

        self.assertEquals([('Manager', 'Anonymous')],
                          merge_role_inheritance(spec, status))
    def test_merges_general_and_status_inheritance(self):
        spec = Specification(title='My Workflow',
                             role_inheritance=[('admin', 'visitor')],
                             role_mapping=ROLE_MAPPING)
        status = Status('Private', [], role_inheritance=[('admin', 'writer')])

        self.assertItemsEqual([('Manager', 'Anonymous'),
                               ('Manager', 'Editor')],
                              merge_role_inheritance(spec, status))
    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))
Exemple #9
0
    def test_VALIDATION_visible_roles_must_be_in_role_mapping(self):
        obj = Specification('My Workflow',
                            initial_status_title='Private',
                            states={'Private': Status('Private', [])},
                            role_mapping={'editor-in-chief': 'Reviewer'},
                            visible_roles=['editor-in-chief', 'editor'])

        with self.assertRaises(ValueError) as cm:
            obj.validate()

        self.assertEquals('"editor" in visible roles is not in role mapping.',
                          str(cm.exception))
Exemple #10
0
    def test_VALIDATION_role_description_must_validate_to_role_mapping(self):
        spec = Specification('My Workflow',
                             initial_status_title='Private',
                             states={'Private': Status('Private', [])},
                             role_mapping={'editor-in-chief': 'Reviewer'},
                             role_descriptions={'editor': 'Text'})

        with self.assertRaises(ValueError) as cm:
            spec.validate()

        self.assertEquals('"editor" in role description is not in role mapping.',
                          str(cm.exception))
    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')
Exemple #12
0
    def _convert_status(self, match, value, specargs):
        title = match.groups()[0]

        statements = []
        role_inheritance = []
        worklist_viewers = []

        if value.strip():
            lines = map(str.strip, value.strip().split('\n'))
            for line in lines:
                type_, item = convert_statement(self.language, line)
                if type_ == PERMISSION_STATEMENT:
                    statements.append(item)
                elif type_ == ROLE_INHERITANCE_STATEMENT:
                    role_inheritance.append(item)
                elif type_ == WORKLIST_STATEMENT:
                    worklist_viewers.append(item)

        specargs['states'][title] = Status(title, statements, role_inheritance,
                                           worklist_viewers)
    def test_simple_workflow(self):
        spec = Specification(title='Example Workflow',
                             description='the Description',
                             initial_status_title='Foo')
        spec.states['Foo'] = Status('Foo', [])
        spec.validate()

        result = StringIO()
        WorkflowGenerator()('example-workflow', spec).write(result)

        expected = workflowxml.WORKFLOW % {
            'id': 'example-workflow',
            'title': 'Example Workflow',
            'description': 'the Description',
            'initial_status': 'example-workflow--STATUS--foo'} % (

            workflowxml.STATUS_STANDALONE % {
                'title': 'Foo',
                'id': 'example-workflow--STATUS--foo',
                })

        self.assert_xml(expected, result.getvalue())
    def test_worklists(self):
        spec = Specification(title='Workflow',
                             initial_status_title='Pending')
        spec.role_mapping['employee'] = 'Editor'
        spec.role_mapping['boss'] = 'Reviewer'

        spec.states['Pending'] = Status(
            'Pending', [],
            worklist_viewers=['employee', 'boss'])

        spec.validate()

        result = StringIO()
        WorkflowGenerator()('wf', spec).write(result)

        expected = workflowxml.WORKFLOW % {
            'id': 'wf',
            'title': 'Workflow',
            'description': '',
            'initial_status': 'wf--STATUS--pending'} % ''.join((

                workflowxml.STATUS_STANDALONE % {
                    'title': 'Pending',
                    'id': 'wf--STATUS--pending',
                    },

                workflowxml.WORKLIST % {
                    'id': 'wf--WORKLIST--pending',
                    'status_id': 'wf--STATUS--pending',
                    'status_title': 'Pending',
                    'guards': workflowxml.GUARDS % ''.join((
                            workflowxml.GUARD_ROLE % 'Editor',
                            workflowxml.GUARD_ROLE % 'Reviewer',
                            ))
                    },

                ))

        self.assert_definition_xmls(expected, result.getvalue())
    def test_multi_word_utf8_status_titles(self):
        status_title = 'Hello W\xc3\xb6rld'
        spec = Specification(title='W\xc3\xb6rkflow',
                             initial_status_title=status_title)
        spec.states[status_title] = Status(status_title, [])
        spec.validate()

        result = StringIO()
        WorkflowGenerator()('workflow', spec).write(result)

        expected = workflowxml.WORKFLOW % {
            'id': 'workflow',
            'title': 'W\xc3\xb6rkflow',
            'description': '',
            'initial_status': 'workflow--STATUS--hello-world'} % (

            workflowxml.STATUS_STANDALONE % {
                'title': status_title,
                'id': 'workflow--STATUS--hello-world',
                })

        self.assert_xml(expected, result.getvalue())
    def test_workflow_with_managed_permissions(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')
        self.map_permissions(['Manage portal'], 'manage')

        spec = Specification(title='Workflow',
                             initial_status_title='Foo')
        spec.role_mapping['writer'] = 'Editor'
        spec.role_mapping['admin'] = 'Administrator'

        spec.states['Foo'] = Status('Foo', [
                ('writer', 'view'),
                ('writer', 'edit'),
                ('admin', 'view'),
                ('admin', 'manage')])
        spec.validate()

        result = StringIO()
        WorkflowGenerator()('example-workflow', spec).write(result)


        xml_permissions_declaration = ''.join((
                workflowxml.PERMISSION % 'Access contents information',
                workflowxml.PERMISSION % 'Manage portal',
                workflowxml.PERMISSION % 'Modify portal content',
                workflowxml.PERMISSION % 'View',
                ))

        xml_status_defininition = workflowxml.STATUS % {
            'title': 'Foo',
            'id': 'example-workflow--STATUS--foo',
            } % ''.join((

                (workflowxml.PERMISSION_MAP %
                 'Access contents information') % ''.join((
                        workflowxml.PERMISSION_ROLE % 'Administrator',
                        workflowxml.PERMISSION_ROLE % 'Editor')),

                (workflowxml.PERMISSION_MAP % 'Manage portal') % (
                    workflowxml.PERMISSION_ROLE % 'Administrator'),

                (workflowxml.PERMISSION_MAP % 'Modify portal content') % (
                    workflowxml.PERMISSION_ROLE % 'Editor'),

                (workflowxml.PERMISSION_MAP % 'View') % ''.join((
                        workflowxml.PERMISSION_ROLE % 'Administrator',
                        workflowxml.PERMISSION_ROLE % 'Editor')),
                ))

        expected = workflowxml.WORKFLOW % {
            'id': 'example-workflow',
            'title': 'Workflow',
            'description': '',
            'initial_status': 'example-workflow--STATUS--foo'} % ''.join((
                xml_permissions_declaration,
                xml_status_defininition))

        self.assert_xml(expected, result.getvalue())
 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_string_repr(self):
     obj = Status('Private', [])
     self.assertEquals(unicode(obj),
                       u'<Status "Private">')
    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())