entities/test/unittest_wfobjs.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 08 Oct 2009 12:34:31 +0200
branchstable
changeset 3622 f4317edf4058
parent 3617 9036a8fbbd57
child 3628 440931181322
permissions -rw-r--r--
merge
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     1
from cubicweb.devtools.apptest import EnvBasedTC
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     2
from cubicweb import ValidationError
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     3
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
     4
def add_wf(self, etype, name=None, default=False):
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
     5
    if name is None:
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
     6
        name = etype
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
     7
    wf = self.execute('INSERT Workflow X: X name %(n)s', {'n': unicode(name)}).get_entity(0, 0)
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
     8
    self.execute('SET WF workflow_of ET WHERE WF eid %(wf)s, ET name %(et)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
     9
                 {'wf': wf.eid, 'et': etype})
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
    10
    if default:
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
    11
        self.execute('SET ET default_workflow WF WHERE WF eid %(wf)s, ET name %(et)s',
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
    12
                     {'wf': wf.eid, 'et': etype})
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    13
    return wf
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    14
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    15
def parse_hist(wfhist):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    16
    return [(ti.previous_state.name, ti.new_state.name,
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    17
             ti.transition and ti.transition.name, ti.comment)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    18
            for ti in wfhist]
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    19
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    20
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    21
class WorkflowBuildingTC(EnvBasedTC):
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    22
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    23
    def test_wf_construction(self):
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    24
        wf = add_wf(self, 'Company')
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    25
        foo = wf.add_state(u'foo', initial=True)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    26
        bar = wf.add_state(u'bar')
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    27
        self.assertEquals(wf.state_by_name('bar').eid, bar.eid)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    28
        self.assertEquals(wf.state_by_name('barrr'), None)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    29
        baz = wf.add_transition(u'baz', (foo,), bar, ('managers',))
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    30
        self.assertEquals(wf.transition_by_name('baz').eid, baz.eid)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    31
        self.assertEquals(len(baz.require_group), 1)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    32
        self.assertEquals(baz.require_group[0].name, 'managers')
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    33
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    34
    def test_duplicated_state(self):
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    35
        wf = add_wf(self, 'Company')
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    36
        wf.add_state(u'foo', initial=True)
2979
94277323239d test two different wfs may have a state of the same name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2977
diff changeset
    37
        self.commit()
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    38
        wf.add_state(u'foo')
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    39
        ex = self.assertRaises(ValidationError, self.commit)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    40
        # XXX enhance message
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    41
        self.assertEquals(ex.errors, {'state_of': 'unique constraint S name N, Y state_of O, Y name N failed'})
2979
94277323239d test two different wfs may have a state of the same name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2977
diff changeset
    42
        # no pb if not in the same workflow
94277323239d test two different wfs may have a state of the same name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2977
diff changeset
    43
        wf2 = add_wf(self, 'Company')
94277323239d test two different wfs may have a state of the same name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2977
diff changeset
    44
        foo = wf2.add_state(u'foo', initial=True)
94277323239d test two different wfs may have a state of the same name
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2977
diff changeset
    45
        self.commit()
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    46
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    47
    def test_duplicated_transition(self):
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
    48
        wf = add_wf(self, 'Company')
2939
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    49
        foo = wf.add_state(u'foo', initial=True)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    50
        bar = wf.add_state(u'bar')
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    51
        wf.add_transition(u'baz', (foo,), bar, ('managers',))
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    52
        wf.add_transition(u'baz', (bar,), foo)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    53
        ex = self.assertRaises(ValidationError, self.commit)
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    54
        # XXX enhance message
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    55
        self.assertEquals(ex.errors, {'transition_of': 'unique constraint S name N, Y transition_of O, Y name N failed'})
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    56
a613cc003ab7 make state/transition name unique within a workflow
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2920
diff changeset
    57
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
class WorkflowTC(EnvBasedTC):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    59
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    60
    def setup_database(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
        rschema = self.schema['in_state']
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
        for x, y in rschema.iter_rdefs():
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
            self.assertEquals(rschema.rproperty(x, y, 'cardinality'), '1*')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
        self.member = self.create_user('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    65
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    66
    def test_workflow_base(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
        e = self.create_user('toto')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
        self.assertEquals(e.state, 'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
        e.change_state('deactivated', u'deactivate 1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
        e.change_state('activated', u'activate 1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
        e.change_state('deactivated', u'deactivate 2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    75
        e.clear_related_cache('wf_info_for', 'object')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
        self.assertEquals([tr.comment for tr in e.reverse_wf_info_for],
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
                          ['deactivate 1', 'activate 1', 'deactivate 2'])
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
        self.assertEquals(e.latest_trinfo().comment, 'deactivate 2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
    def test_possible_transitions(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
        user = self.entity('CWUser X')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
        trs = list(user.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
        self.assertEquals(len(trs), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    84
        self.assertEquals(trs[0].name, u'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    85
        self.assertEquals(trs[0].destination().name, u'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        # test a std user get no possible transition
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
        cnx = self.login('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
        # fetch the entity using the new session
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    89
        trs = list(cnx.user().possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    90
        self.assertEquals(len(trs), 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    91
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    92
    def _test_manager_deactivate(self, user):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
        user.clear_related_cache('in_state', 'subject')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    94
        self.assertEquals(len(user.in_state), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    95
        self.assertEquals(user.state, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    96
        trinfo = user.latest_trinfo()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    97
        self.assertEquals(trinfo.previous_state.name, 'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    98
        self.assertEquals(trinfo.new_state.name, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
        self.assertEquals(trinfo.comment, 'deactivate user')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
        self.assertEquals(trinfo.comment_format, 'text/plain')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
        return trinfo
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   103
    def test_change_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   104
        user = self.user()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
        user.change_state('deactivated', comment=u'deactivate user')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
        trinfo = self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
        self.assertEquals(trinfo.transition, None)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
2983
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   109
    def test_set_in_state_bad_wf(self):
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   110
        wf = add_wf(self, 'CWUser')
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   111
        s = wf.add_state(u'foo', initial=True)
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   112
        self.commit()
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   113
        ex = self.assertRaises(ValidationError, self.session().unsafe_execute,
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   114
                               'SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   115
                               {'x': self.user().eid, 's': s.eid}, 'x')
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   116
        self.assertEquals(ex.errors, {'in_state': "state doesn't belong to entity's workflow. "
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   117
                                      "You may want to set a custom workflow for this entity first."})
b458631fe347 [wf] test in_state consistency
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2982
diff changeset
   118
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
    def test_fire_transition(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
        user = self.user()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
        user.fire_transition('deactivate', comment=u'deactivate user')
2982
1768dbe8e9b3 [wf] need to clear cache here
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2979
diff changeset
   122
        user.clear_all_caches()
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        self.assertEquals(user.state, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
        self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
        trinfo = self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        self.assertEquals(trinfo.transition.name, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
    # XXX test managers can change state without matching transition
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   129
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   130
    def _test_stduser_deactivate(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
        ueid = self.member.eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
        self.create_user('tutu')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
        cnx = self.login('tutu')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
        req = self.request()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        member = req.entity_from_eid(self.member.eid)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
                               member.fire_transition, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        self.assertEquals(ex.errors, {'by_transition': "transition may not be fired"})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        cnx = self.login('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        req = self.request()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
        member = req.entity_from_eid(self.member.eid)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
        member.fire_transition('deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
                               member.fire_transition, 'activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
        self.assertEquals(ex.errors, {'by_transition': "transition may not be fired"})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
    def test_fire_transition_owned_by(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
        self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   151
                     'X expression "X owned_by U", T condition X '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
                     'WHERE T name "deactivate"')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
        self._test_stduser_deactivate()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
    def test_fire_transition_has_update_perm(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
        self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
                     'X expression "U has_update_permission X", T condition X '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
                     'WHERE T name "deactivate"')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
        self._test_stduser_deactivate()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
3616
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   161
    def test_swf_fire_in_a_row(self):
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   162
        # sub-workflow
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   163
        subwf = add_wf(self, 'CWGroup', name='subworkflow')
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   164
        xsigning = subwf.add_state('xsigning', initial=True)
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   165
        xaborted = subwf.add_state('xaborted')
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   166
        xsigned = subwf.add_state('xsigned')
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   167
        xabort = subwf.add_transition('xabort', (xsigning,), xaborted)
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   168
        xsign = subwf.add_transition('xsign', (xsigning,), xsigning)
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   169
        xcomplete = subwf.add_transition('xcomplete', (xsigning,), xsigned,
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   170
                                         type=u'auto')
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   171
        # main workflow
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   172
        twf = add_wf(self, 'CWGroup', name='mainwf', default=True)
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   173
        created    = twf.add_state(_('created'), initial=True)
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   174
        identified = twf.add_state(_('identified'))
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   175
        released   = twf.add_state(_('released'))
3617
9036a8fbbd57 add a commit point, a new transition exhibits the problem again
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3616
diff changeset
   176
        closed   = twf.add_state(_('closed'))
3616
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   177
        twf.add_wftransition(_('identify'), subwf, (created,),
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   178
                             [(xsigned, identified), (xaborted, created)])
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   179
        twf.add_wftransition(_('release'), subwf, (identified,),
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   180
                             [(xsigned, released), (xaborted, identified)])
3617
9036a8fbbd57 add a commit point, a new transition exhibits the problem again
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3616
diff changeset
   181
        twf.add_wftransition(_('close'), subwf, (released,),
9036a8fbbd57 add a commit point, a new transition exhibits the problem again
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3616
diff changeset
   182
                             [(xsigned, closed), (xaborted, released)])
3616
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   183
        self.commit()
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   184
        group = self.add_entity('CWGroup', name=u'grp1')
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   185
        self.commit()
3617
9036a8fbbd57 add a commit point, a new transition exhibits the problem again
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3616
diff changeset
   186
        for trans in ('identify', 'release', 'close'):
3616
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   187
            group.fire_transition(trans)
3617
9036a8fbbd57 add a commit point, a new transition exhibits the problem again
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3616
diff changeset
   188
            self.commit()
3616
600ee58a1375 a problem with consecutive transition firing when subworkflows are involved
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 3587
diff changeset
   189
2992
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   190
    def test_subworkflow_base(self):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   191
        """subworkflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   192
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   193
        +-----------+  tr1   +-----------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   194
        | swfstate1 | ------>| swfstate2 |
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   195
        +-----------+        +-----------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   196
                  |  tr2  +-----------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   197
                  `------>| swfstate3 |
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   198
                          +-----------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   199
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   200
        main workflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   201
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   202
        +--------+  swftr1             +--------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   203
        | state1 | -------[swfstate2]->| state2 |
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   204
        +--------+     |               +--------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   205
                       |               +--------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   206
                       `-[swfstate3]-->| state3 |
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   207
                                       +--------+
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   208
        """
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   209
        # sub-workflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   210
        swf = add_wf(self, 'CWGroup', name='subworkflow')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   211
        swfstate1 = swf.add_state(u'swfstate1', initial=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   212
        swfstate2 = swf.add_state(u'swfstate2')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   213
        swfstate3 = swf.add_state(u'swfstate3')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   214
        tr1 = swf.add_transition(u'tr1', (swfstate1,), swfstate2)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   215
        tr2 = swf.add_transition(u'tr2', (swfstate1,), swfstate3)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   216
        # main workflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   217
        mwf = add_wf(self, 'CWGroup', name='main workflow', default=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   218
        state1 = mwf.add_state(u'state1', initial=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   219
        state2 = mwf.add_state(u'state2')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   220
        state3 = mwf.add_state(u'state3')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   221
        swftr1 = mwf.add_wftransition(u'swftr1', swf, state1,
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   222
                                      [(swfstate2, state2), (swfstate3, state3)])
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   223
        self.assertEquals(swftr1.destination().eid, swfstate1.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   224
        # workflows built, begin test
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   225
        self.group = self.add_entity('CWGroup', name=u'grp1')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   226
        self.commit()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   227
        self.assertEquals(self.group.current_state.eid, state1.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   228
        self.assertEquals(self.group.current_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   229
        self.assertEquals(self.group.main_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   230
        self.assertEquals(self.group.subworkflow_input_transition(), None)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   231
        self.group.fire_transition('swftr1', u'go')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   232
        self.commit()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   233
        self.group.clear_all_caches()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   234
        self.assertEquals(self.group.current_state.eid, swfstate1.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   235
        self.assertEquals(self.group.current_workflow.eid, swf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   236
        self.assertEquals(self.group.main_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   237
        self.assertEquals(self.group.subworkflow_input_transition().eid, swftr1.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   238
        self.group.fire_transition('tr1', u'go')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   239
        self.commit()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   240
        self.group.clear_all_caches()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   241
        self.assertEquals(self.group.current_state.eid, state2.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   242
        self.assertEquals(self.group.current_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   243
        self.assertEquals(self.group.main_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   244
        self.assertEquals(self.group.subworkflow_input_transition(), None)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   245
        # force back to swfstate1 is impossible since we can't any more find
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   246
        # subworkflow input transition
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   247
        ex = self.assertRaises(ValidationError,
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   248
                               self.group.change_state, swfstate1, u'gadget')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   249
        self.assertEquals(ex.errors, {'to_state': "state doesn't belong to entity's current workflow"})
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   250
        self.rollback()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   251
        # force back to state1
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   252
        self.group.change_state('state1', u'gadget')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   253
        self.group.fire_transition('swftr1', u'au')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   254
        self.group.clear_all_caches()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   255
        self.group.fire_transition('tr2', u'chapeau')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   256
        self.commit()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   257
        self.group.clear_all_caches()
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   258
        self.assertEquals(self.group.current_state.eid, state3.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   259
        self.assertEquals(self.group.current_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   260
        self.assertEquals(self.group.main_workflow.eid, mwf.eid)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   261
        self.assertListEquals(parse_hist(self.group.workflow_history),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   262
                              [('state1', 'swfstate1', 'swftr1', 'go'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   263
                               ('swfstate1', 'swfstate2', 'tr1', 'go'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   264
                               ('swfstate2', 'state2', 'swftr1', 'exiting from subworkflow subworkflow'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   265
                               ('state2', 'state1', None, 'gadget'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   266
                               ('state1', 'swfstate1', 'swftr1', 'au'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   267
                               ('swfstate1', 'swfstate3', 'tr2', 'chapeau'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   268
                               ('swfstate3', 'state3', 'swftr1', 'exiting from subworkflow subworkflow'),
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   269
                               ])
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   270
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   271
    def test_subworkflow_exit_consistency(self):
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   272
        # sub-workflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   273
        swf = add_wf(self, 'CWGroup', name='subworkflow')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   274
        swfstate1 = swf.add_state(u'swfstate1', initial=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   275
        swfstate2 = swf.add_state(u'swfstate2')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   276
        tr1 = swf.add_transition(u'tr1', (swfstate1,), swfstate2)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   277
        # main workflow
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   278
        mwf = add_wf(self, 'CWGroup', name='main workflow', default=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   279
        state1 = mwf.add_state(u'state1', initial=True)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   280
        state2 = mwf.add_state(u'state2')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   281
        state3 = mwf.add_state(u'state3')
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   282
        mwf.add_wftransition(u'swftr1', swf, state1,
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   283
                             [(swfstate2, state2), (swfstate2, state3)])
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   284
        ex = self.assertRaises(ValidationError, self.commit)
a5b8bf107a1a [wf] test and hooks for WorkflowTransition support
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2985
diff changeset
   285
        self.assertEquals(ex.errors, {'subworkflow_exit': u"can't have multiple exits on the same state"})
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   286
2954
48507919b6e3 [wf] oops, BaseTransition.__init__ may be called for subclasses
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2949
diff changeset
   287
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   288
class CustomWorkflowTC(EnvBasedTC):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   289
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   290
    def setup_database(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   291
        self.member = self.create_user('member')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   292
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   293
    def tearDown(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   294
        super(CustomWorkflowTC, self).tearDown()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   295
        self.execute('DELETE X custom_workflow WF')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   296
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   297
    def test_custom_wf_replace_state_no_history(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   298
        """member in inital state with no previous history, state is simply
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   299
        redirected when changing workflow
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   300
        """
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   301
        wf = add_wf(self, 'CWUser')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   302
        wf.add_state('asleep', initial=True)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   303
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   304
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   305
        self.member.clear_all_caches()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   306
        self.assertEquals(self.member.state, 'activated')# no change before commit
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   307
        self.commit()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   308
        self.member.clear_all_caches()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   309
        self.assertEquals(self.member.current_workflow.eid, wf.eid)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   310
        self.assertEquals(self.member.state, 'asleep')
3587
5b3725f315fc test fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3528
diff changeset
   311
        self.assertEquals(self.member.workflow_history, ())
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   312
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   313
    def test_custom_wf_replace_state_keep_history(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   314
        """member in inital state with some history, state is redirected and
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   315
        state change is recorded to history
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   316
        """
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   317
        self.member.fire_transition('deactivate')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   318
        self.member.fire_transition('activate')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   319
        wf = add_wf(self, 'CWUser')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   320
        wf.add_state('asleep', initial=True)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   321
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   322
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   323
        self.commit()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   324
        self.member.clear_all_caches()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   325
        self.assertEquals(self.member.current_workflow.eid, wf.eid)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   326
        self.assertEquals(self.member.state, 'asleep')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   327
        self.assertEquals(parse_hist(self.member.workflow_history),
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   328
                          [('activated', 'deactivated', 'deactivate', None),
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   329
                           ('deactivated', 'activated', 'activate', None),
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   330
                           ('activated', 'asleep', None, 'workflow changed to "CWUser"')])
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   331
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   332
    def test_custom_wf_no_initial_state(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   333
        """try to set a custom workflow which has no initial state"""
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   334
        self.member.fire_transition('deactivate')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   335
        wf = add_wf(self, 'CWUser')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   336
        wf.add_state('asleep')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   337
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   338
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   339
        ex = self.assertRaises(ValidationError, self.commit)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   340
        self.assertEquals(ex.errors, {'custom_workflow': u'workflow has no initial state'})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   341
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   342
    def test_custom_wf_bad_etype(self):
2985
79185b3ccf2c cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2984
diff changeset
   343
        """try to set a custom workflow which doesn't apply to entity type"""
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   344
        wf = add_wf(self, 'Company')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   345
        wf.add_state('asleep', initial=True)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   346
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   347
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   348
        ex = self.assertRaises(ValidationError, self.commit)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   349
        self.assertEquals(ex.errors, {'custom_workflow': 'constraint S is ET, O workflow_of ET failed'})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   350
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   351
    def test_del_custom_wf(self):
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   352
        """member in some state shared by the new workflow, nothing has to be
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   353
        done
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   354
        """
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   355
        self.member.fire_transition('deactivate')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   356
        wf = add_wf(self, 'CWUser')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   357
        wf.add_state('asleep', initial=True)
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   358
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   359
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   360
        self.commit()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   361
        self.execute('DELETE X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   362
                     {'wf': wf.eid, 'x': self.member.eid})
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   363
        self.member.clear_all_caches()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   364
        self.assertEquals(self.member.state, 'asleep')# no change before commit
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   365
        self.commit()
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   366
        self.member.clear_all_caches()
3206
5a51ac97f1d3 tests update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   367
        self.assertEquals(self.member.current_workflow.name, "default user workflow")
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   368
        self.assertEquals(self.member.state, 'activated')
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   369
        self.assertEquals(parse_hist(self.member.workflow_history),
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   370
                          [('activated', 'deactivated', 'deactivate', None),
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   371
                           ('deactivated', 'asleep', None, 'workflow changed to "CWUser"'),
3206
5a51ac97f1d3 tests update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2992
diff changeset
   372
                           ('asleep', 'activated', None, 'workflow changed to "default user workflow"'),])
2949
a2aa2c51f3be test and implements workflow changes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2939
diff changeset
   373
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   374
3528
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   375
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   376
class AutoTransitionTC(EnvBasedTC):
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   377
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   378
    def setup_database(self):
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   379
        self.wf = add_wf(self, 'CWUser')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   380
        asleep = self.wf.add_state('asleep', initial=True)
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   381
        dead = self.wf.add_state('dead')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   382
        self.wf.add_transition('rest', asleep, asleep)
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   383
        self.wf.add_transition('sick', asleep, dead, type=u'auto',
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   384
                               conditions=({'expr': u'U surname "toto"',
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   385
                                            'mainvars': u'U'},))
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   386
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   387
    def test_auto_transition_fired(self):
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   388
        user = self.create_user('member')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   389
        self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   390
                     {'wf': self.wf.eid, 'x': user.eid})
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   391
        self.commit()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   392
        user.clear_all_caches()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   393
        self.assertEquals(user.state, 'asleep')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   394
        self.assertEquals([t.name for t in user.possible_transitions()],
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   395
                          ['rest'])
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   396
        user.fire_transition('rest')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   397
        self.commit()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   398
        user.clear_all_caches()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   399
        self.assertEquals(user.state, 'asleep')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   400
        self.assertEquals([t.name for t in user.possible_transitions()],
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   401
                          ['rest'])
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   402
        self.assertEquals(parse_hist(user.workflow_history),
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   403
                          [('asleep', 'asleep', 'rest', None)])
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   404
        self.request().user.set_attributes(surname=u'toto') # fulfill condition
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   405
        self.commit()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   406
        user.fire_transition('rest')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   407
        self.commit()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   408
        user.clear_all_caches()
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   409
        self.assertEquals(user.state, 'dead')
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   410
        self.assertEquals(parse_hist(user.workflow_history),
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   411
                          [('asleep', 'asleep', 'rest', None),
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   412
                           ('asleep', 'asleep', 'rest', None),
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   413
                           ('asleep', 'dead', 'sick', None),])
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   414
77a69de16709 support for automatic transition
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3206
diff changeset
   415
2920
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   416
from cubicweb.devtools.apptest import RepositoryBasedTC
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   417
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   418
class WorkflowHooksTC(RepositoryBasedTC):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   419
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   420
    def setUp(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   421
        RepositoryBasedTC.setUp(self)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   422
        self.wf = self.session.user.current_workflow
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   423
        self.s_activated = self.wf.state_by_name('activated').eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   424
        self.s_deactivated = self.wf.state_by_name('deactivated').eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   425
        self.s_dummy = self.wf.add_state(u'dummy').eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   426
        self.wf.add_transition(u'dummy', (self.s_deactivated,), self.s_dummy)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   427
        ueid = self.create_user('stduser', commit=False)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   428
        # test initial state is set
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   429
        rset = self.execute('Any N WHERE S name N, X in_state S, X eid %(x)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   430
                            {'x' : ueid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   431
        self.failIf(rset, rset.rows)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   432
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   433
        initialstate = self.execute('Any N WHERE S name N, X in_state S, X eid %(x)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   434
                                    {'x' : ueid})[0][0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   435
        self.assertEquals(initialstate, u'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   436
        # give access to users group on the user's wf transitions
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   437
        # so we can test wf enforcing on euser (managers don't have anymore this
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   438
        # enforcement
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   439
        self.execute('SET X require_group G '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   440
                     'WHERE G name "users", X transition_of WF, WF eid %(wf)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   441
                     {'wf': self.wf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   442
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   443
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   444
    def tearDown(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   445
        self.execute('DELETE X require_group G '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   446
                     'WHERE G name "users", X transition_of WF, WF eid %(wf)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   447
                     {'wf': self.wf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   448
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   449
        RepositoryBasedTC.tearDown(self)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   450
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   451
    # XXX currently, we've to rely on hooks to set initial state, or to use unsafe_execute
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   452
    # def test_initial_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   453
    #     cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   454
    #     cu = cnx.cursor()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   455
    #     self.assertRaises(ValidationError, cu.execute,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   456
    #                       'INSERT CWUser X: X login "badaboum", X upassword %(pwd)s, '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   457
    #                       'X in_state S WHERE S name "deactivated"', {'pwd': 'oops'})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   458
    #     cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   459
    #     # though managers can do whatever he want
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   460
    #     self.execute('INSERT CWUser X: X login "badaboum", X upassword %(pwd)s, '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   461
    #                  'X in_state S, X in_group G WHERE S name "deactivated", G name "users"', {'pwd': 'oops'})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   462
    #     self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   463
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   464
    # test that the workflow is correctly enforced
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   465
    def test_transition_checking1(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   466
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   467
        user = cnx.user(self.current_session())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   468
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   469
                               user.fire_transition, 'activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   470
        self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   471
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   472
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   473
    def test_transition_checking2(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   474
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   475
        user = cnx.user(self.current_session())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   476
        assert user.state == 'activated'
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   477
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   478
                               user.fire_transition, 'dummy')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   479
        self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   480
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   481
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   482
    def test_transition_checking3(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   483
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   484
        session = self.current_session()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   485
        user = cnx.user(session)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   486
        user.fire_transition('deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   487
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   488
        session.set_pool()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   489
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   490
                               user.fire_transition, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   491
        self.assertEquals(ex.errors, {'by_transition': u"transition isn't allowed"})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   492
        # get back now
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   493
        user.fire_transition('activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   494
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   495
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   496
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   497
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   498
if __name__ == '__main__':
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   499
    from logilab.common.testlib import unittest_main
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   500
    unittest_main()