Commit abf43baf authored by Sylvain Thénault's avatar Sylvain Thénault
Browse files

introduce 'go back' transition: transition without destination state will go...

introduce 'go back' transition: transition without destination state will go to the state we were coming from

branch : stable
parent 921737d2e3a8
......@@ -98,7 +98,7 @@ class WorkflowTC(CubicWebTC):
trs = list(user.possible_transitions())
self.assertEquals(len(trs), 1)
self.assertEquals(trs[0].name, u'deactivate')
self.assertEquals(trs[0].destination().name, u'deactivated')
self.assertEquals(trs[0].destination(None).name, u'deactivated')
# test a std user get no possible transition
cnx = self.login('member')
# fetch the entity using the new session
......@@ -141,6 +141,27 @@ class WorkflowTC(CubicWebTC):
trinfo = self._test_manager_deactivate(user)
self.assertEquals(, 'deactivate')
def test_goback_transition(self):
wf = self.session.user.current_workflow
asleep = wf.add_state('asleep')
wf.add_transition('rest', (wf.state_by_name('activated'), wf.state_by_name('deactivated')),
wf.add_transition('wake up', asleep)
user = self.create_user('stduser')
user.fire_transition('wake up')
self.assertEquals(user.state, 'activated')
user.fire_transition('wake up')
self.assertEquals(user.state, 'deactivated')
# XXX test managers can change state without matching transition
def _test_stduser_deactivate(self):
......@@ -207,7 +228,7 @@ class WorkflowTC(CubicWebTC):
state3 = mwf.add_state(u'state3')
swftr1 = mwf.add_wftransition(u'swftr1', swf, state1,
[(swfstate2, state2), (swfstate3, state3)])
self.assertEquals(swftr1.destination().eid, swfstate1.eid)
self.assertEquals(swftr1.destination(None).eid, swfstate1.eid)
# workflows built, begin test = self.request().create_entity('CWGroup', name=u'grp1')
......@@ -256,8 +256,12 @@ class Transition(BaseTransition):
"""customized class for Transition entities"""
__regid__ = 'Transition'
def destination(self):
return self.destination_state[0]
def destination(self, entity):
return self.destination_state[0]
except IndexError:
return entity.latest_trinfo().previous_state
def parent(self):
return self.workflow
......@@ -232,7 +232,7 @@ class FireTransitionHook(WorkflowHook):
raise ValidationError(entity.eid, {'by_transition': msg})
if entity.get('to_state'):
deststateeid = entity['to_state']
if not cowpowers and deststateeid != tr.destination().eid:
if not cowpowers and deststateeid != tr.destination(forentity).eid:
msg = session._("transition isn't allowed")
raise ValidationError(entity.eid, {'by_transition': msg})
if swtr is None:
......@@ -241,7 +241,7 @@ class FireTransitionHook(WorkflowHook):
msg = session._("state doesn't belong to entity's workflow")
raise ValidationError(entity.eid, {'to_state': msg})
deststateeid = tr.destination().eid
deststateeid = tr.destination(forentity).eid
# everything is ok, add missing information on the trinfo entity
entity['from_state'] = fromstate.eid
entity['to_state'] = deststateeid
sync_schema_props_perms('destination_state', syncperms=False)
......@@ -97,12 +97,13 @@ class BaseTransition(EntityType):
class Transition(BaseTransition):
"""use to define a transition from one or multiple states to a destination
states in workflow's definitions.
states in workflow's definitions. Transition without destination state will
go back to the state from which we arrived to the current state.
__specializes_schema__ = True
destination_state = SubjectRelation(
'State', cardinality='1*',
'State', cardinality='?*',
constraints=[RQLConstraint('S transition_of WF, O state_of WF',
msg=_('state and transition don\'t belong the the same workflow'))],
description=_('destination state for this transition'))
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment