entities/test/unittest_wfobjs.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 20 Aug 2009 17:44:27 +0200
branch3.5
changeset 2920 64322aa83a1d
child 2939 a613cc003ab7
permissions -rw-r--r--
start a new workflow engine
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
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     4
class WorkflowTC(EnvBasedTC):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     5
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     6
    def setup_database(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     7
        rschema = self.schema['in_state']
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     8
        for x, y in rschema.iter_rdefs():
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
     9
            self.assertEquals(rschema.rproperty(x, y, 'cardinality'), '1*')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    10
        self.member = self.create_user('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    11
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    12
    def test_workflow_base(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    13
        e = self.create_user('toto')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    14
        self.assertEquals(e.state, 'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    15
        e.change_state('deactivated', u'deactivate 1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    16
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    17
        e.change_state('activated', u'activate 1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    18
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    19
        e.change_state('deactivated', u'deactivate 2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    20
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    21
        e.clear_related_cache('wf_info_for', 'object')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    22
        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
    23
                          ['deactivate 1', 'activate 1', 'deactivate 2'])
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    24
        self.assertEquals(e.latest_trinfo().comment, 'deactivate 2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    25
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    26
    # def test_wf_construction(self): # XXX update or kill me
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    27
    #     bar = self.mh.cmd_add_state(u'bar', ('Personne', 'Email'), initial=True)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    28
    #     baz = self.mh.cmd_add_transition(u'baz', ('Personne', 'Email'),
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    29
    #                                      (foo,), bar, ('managers',))
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    30
    #     for etype in ('Personne', 'Email'):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    31
    #         t1 = self.mh.rqlexec('Any N WHERE T transition_of ET, ET name "%s", T name N' %
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    32
    #                              etype)[0][0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    33
    #         self.assertEquals(t1, "baz")
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    34
    #     gn = self.mh.rqlexec('Any GN WHERE T require_group G, G name GN, T eid %s' % baz)[0][0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    35
    #     self.assertEquals(gn, 'managers')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    36
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    37
    def test_possible_transitions(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    38
        user = self.entity('CWUser X')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    39
        trs = list(user.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    40
        self.assertEquals(len(trs), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    41
        self.assertEquals(trs[0].name, u'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    42
        self.assertEquals(trs[0].destination().name, u'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    43
        # test a std user get no possible transition
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    44
        cnx = self.login('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    45
        # fetch the entity using the new session
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    46
        trs = list(cnx.user().possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    47
        self.assertEquals(len(trs), 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    48
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    49
    def _test_manager_deactivate(self, user):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    50
        user.clear_related_cache('in_state', 'subject')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    51
        self.assertEquals(len(user.in_state), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    52
        self.assertEquals(user.state, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    53
        trinfo = user.latest_trinfo()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    54
        self.assertEquals(trinfo.previous_state.name, 'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    55
        self.assertEquals(trinfo.new_state.name, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    56
        self.assertEquals(trinfo.comment, 'deactivate user')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    57
        self.assertEquals(trinfo.comment_format, 'text/plain')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    58
        return trinfo
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 test_change_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    61
        user = self.user()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    62
        user.change_state('deactivated', comment=u'deactivate user')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    63
        trinfo = self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    64
        self.assertEquals(trinfo.transition, None)
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_fire_transition(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    67
        user = self.user()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    68
        user.fire_transition('deactivate', comment=u'deactivate user')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    69
        self.assertEquals(user.state, 'deactivated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    70
        self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    71
        trinfo = self._test_manager_deactivate(user)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    72
        self.assertEquals(trinfo.transition.name, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    73
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    74
    # 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
    75
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    76
    def _test_stduser_deactivate(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    77
        ueid = self.member.eid
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    78
        self.create_user('tutu')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    79
        cnx = self.login('tutu')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    80
        req = self.request()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    81
        member = req.entity_from_eid(self.member.eid)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    82
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    83
                               member.fire_transition, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    84
        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
    85
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    86
        cnx = self.login('member')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    87
        req = self.request()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    88
        member = req.entity_from_eid(self.member.eid)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    89
        member.fire_transition('deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    90
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    91
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    92
                               member.fire_transition, 'activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    93
        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
    94
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    95
    def test_fire_transition_owned_by(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    96
        self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    97
                     '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
    98
                     'WHERE T name "deactivate"')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
    99
        self._test_stduser_deactivate()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   100
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   101
    def test_fire_transition_has_update_perm(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   102
        self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   103
                     '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
   104
                     'WHERE T name "deactivate"')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   105
        self._test_stduser_deactivate()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   106
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   107
    def _init_wf_with_shared_state_or_tr(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   108
        req = self.request()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   109
        etypes = dict(self.execute('Any N, ET WHERE ET is CWEType, ET name N'
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   110
                                   ', ET name IN ("CWGroup", "Bookmark")'))
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   111
        self.grpwf = req.create_entity('Workflow', ('workflow_of', 'ET'),
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   112
                                       ET=etypes['CWGroup'], name=u'group workflow')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   113
        self.bmkwf = req.execute('Any X WHERE X is Workflow, X workflow_of ET, ET name "Bookmark"').get_entity(0, 0)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   114
        self.state1 = self.grpwf.add_state(u'state1', initial=True)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   115
        self.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   116
                     {'s': self.state1.eid, 'wf': self.bmkwf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   117
        self.execute('SET WF initial_state S WHERE S eid %(s)s, WF eid %(wf)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   118
                     {'s': self.state1.eid, 'wf': self.bmkwf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   119
        self.state2 = self.grpwf.add_state(u'state2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   120
        self.group = self.add_entity('CWGroup', name=u't1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   121
        self.bookmark = self.add_entity('Bookmark', title=u'111', path=u'/view')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   122
        # commit to link to the initial state
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   123
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   124
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   125
    def test_transitions_selection(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   126
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   127
        ------------------------  tr1    -----------------
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   128
        | state1 (CWGroup, Bookmark) | ------> | state2 (CWGroup) |
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
                  |  tr2    ------------------
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   131
                  `------>  | state3 (Bookmark) |
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   132
                            ------------------
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   133
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   134
        self._init_wf_with_shared_state_or_tr()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   135
        state3 = self.bmkwf.add_state(u'state3')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   136
        tr1 = self.grpwf.add_transition(u'tr1', (self.state1,), self.state2)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   137
        tr2 = self.bmkwf.add_transition(u'tr2', (self.state1,), state3)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   138
        transitions = list(self.group.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   139
        self.assertEquals(len(transitions), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   140
        self.assertEquals(transitions[0].name, 'tr1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   141
        transitions = list(self.bookmark.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   142
        self.assertEquals(len(transitions), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   143
        self.assertEquals(transitions[0].name, 'tr2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   144
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   145
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   146
    def test_transitions_selection2(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   147
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   148
        ------------------------  tr1 (Bookmark)   -----------------------
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   149
        | state1 (CWGroup, Bookmark) | -------------> | state2 (CWGroup,Bookmark) |
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   150
        ------------------------                -----------------------
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   151
                  |  tr2 (CWGroup)                     |
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   152
                  `---------------------------------/
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   153
        """
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   154
        self._init_wf_with_shared_state_or_tr()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   155
        self.execute('SET S state_of WF WHERE S eid %(s)s, WF eid %(wf)s',
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   156
                     {'s': self.state2.eid, 'wf': self.bmkwf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   157
        tr1 = self.bmkwf.add_transition(u'tr1', (self.state1,), self.state2)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   158
        tr2 = self.grpwf.add_transition(u'tr2', (self.state1,), self.state2)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   159
        transitions = list(self.group.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   160
        self.assertEquals(len(transitions), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   161
        self.assertEquals(transitions[0].name, 'tr2')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   162
        transitions = list(self.bookmark.possible_transitions())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   163
        self.assertEquals(len(transitions), 1)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   164
        self.assertEquals(transitions[0].name, 'tr1')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   165
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   166
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   167
from cubicweb.devtools.apptest import RepositoryBasedTC
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   168
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   169
class WorkflowHooksTC(RepositoryBasedTC):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   170
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   171
    def setUp(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   172
        RepositoryBasedTC.setUp(self)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   173
        self.wf = self.session.user.current_workflow
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   174
        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
   175
        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
   176
        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
   177
        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
   178
        ueid = self.create_user('stduser', commit=False)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   179
        # test initial state is set
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   180
        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
   181
                            {'x' : ueid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   182
        self.failIf(rset, rset.rows)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   183
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   184
        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
   185
                                    {'x' : ueid})[0][0]
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   186
        self.assertEquals(initialstate, u'activated')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   187
        # 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
   188
        # 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
   189
        # enforcement
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   190
        self.execute('SET X require_group G '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   191
                     '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
   192
                     {'wf': self.wf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   193
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   194
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   195
    def tearDown(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   196
        self.execute('DELETE X require_group G '
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   197
                     '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
   198
                     {'wf': self.wf.eid})
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   199
        self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   200
        RepositoryBasedTC.tearDown(self)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   201
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   202
    # 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
   203
    # def test_initial_state(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   204
    #     cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   205
    #     cu = cnx.cursor()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   206
    #     self.assertRaises(ValidationError, cu.execute,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   207
    #                       '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
   208
    #                       '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
   209
    #     cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   210
    #     # though managers can do whatever he want
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   211
    #     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
   212
    #                  '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
   213
    #     self.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   214
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   215
    # test that the workflow is correctly enforced
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   216
    def test_transition_checking1(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   217
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   218
        user = cnx.user(self.current_session())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   219
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   220
                               user.fire_transition, 'activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   221
        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
   222
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   223
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   224
    def test_transition_checking2(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   225
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   226
        user = cnx.user(self.current_session())
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   227
        assert user.state == 'activated'
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   228
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   229
                               user.fire_transition, 'dummy')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   230
        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
   231
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   232
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   233
    def test_transition_checking3(self):
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   234
        cnx = self.login('stduser')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   235
        session = self.current_session()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   236
        user = cnx.user(session)
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   237
        user.fire_transition('deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   238
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   239
        session.set_pool()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   240
        ex = self.assertRaises(ValidationError,
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   241
                               user.fire_transition, 'deactivate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   242
        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
   243
        # get back now
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   244
        user.fire_transition('activate')
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   245
        cnx.commit()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   246
        cnx.close()
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   247
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   248
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   249
if __name__ == '__main__':
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   250
    from logilab.common.testlib import unittest_main
64322aa83a1d start a new workflow engine
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents:
diff changeset
   251
    unittest_main()