class routingSubflowTestCase(unittest.TestCase):

    def setUp(self):
        # Create an OpenFlow folder
        self.of = CMFOpenflowTool('of')

        # Create a Process Definition with a subflow activity.
        self.of.addProcess(id='main', BeginEnd=1)
        self.main_pd = getattr(self.of, 'main')
        self.main_pd.addActivity('sub', kind='subflow', subflow='test_subflow')
        self.main_pd.addTransition(id='Begin_sub', From='Begin', To='sub')
        self.main_pd.addTransition(id='sub_End', From='sub', To='End')
        begin = getattr(self.main_pd, 'Begin')
        begin.edit(start_mode=1, finish_mode=1)

        # Create a Process Definition "subflow" that will act as a subflow.
        self.of.addProcess(id='test_subflow', BeginEnd=1)
        self.sub_pd = getattr(self.of, 'test_subflow')
        self.sub_pd.addTransition(id='Begin_End', From='Begin', To='End')
        getattr(self.sub_pd, 'Begin').edit(kind='standard')
        getattr(self.sub_pd, 'End').edit(kind='standard')

        # Create a Process Instance of "main"
        pid = self.of.addInstance('main', 'test', 'testComment', 'TestTitle', 1)
        self.pi = getattr(self.of, pid)


    def checkSubflowWorkitemsCreation(self):
        """ Check the subflow workitems creation """
        assert getattr(self.pi, '1'), 'workitem 1  not created'
        assert getattr(self.pi, '2').activity_id == 'Begin' , 'workitem 2 activity not correct'
        assert getattr(self.pi, '2').process_id == 'test_subflow' , 'workitem 2 process not correct'
        self.w = getattr(self.pi, '2')
        self.of.activateWorkitem(self.pi.id, self.w.id)
        self.of.completeWorkitem(self.pi.id, self.w.id)
        self.of.forwardWorkitem(self.pi.id, self.w.id)
        assert getattr(self.pi, '3').activity_id == 'End' , 'workitem 3 activity not correct'
        assert getattr(self.pi, '3').process_id == 'test_subflow' , 'workitem 3 process not correct'


    def checkCompleteSubflow(self):
        """ Check the subflow completion """
        self.w = getattr(self.pi, '2')
        self.of.activateWorkitem(self.pi.id, self.w.id)
        self.of.completeWorkitem(self.pi.id, self.w.id)
        self.of.forwardWorkitem(self.pi.id, self.w.id)
        assert getattr(self.pi, '3'), 'workitem 3  not created'
        assert self.of.getSubflowWorkitem(self.pi.id, '3',getattr(self.pi, '3').process_id) == '1', 'subflow workitem not correct'
        self.of.activateWorkitem(self.pi.id, '3')
        self.of.completeWorkitem(self.pi.id, '3')
        assert getattr(self.pi, '1').status == 'complete', 'subflow workitem status not correct'
        assert getattr(self.pi, '4'), 'workitem 4 not created'
class routingXOrSplitTestCase(unittest.TestCase):

    def setUp(self):

        # Create an OpenFlow folder
        self.of = CMFOpenflowTool('of')

        # Create a Process Definition with two activity (Begin, End) and one transition.
        self.of.addProcess(id='xor_split', BeginEnd=1)
        self.pd = getattr(self.of, 'xor_split')
        begin = getattr(self.pd, 'Begin')
        begin.edit(split_mode='xor')
        end = getattr(self.pd, 'End')
        end.edit(join_mode='xor')
        self.pd.addActivity('a1')
        self.pd.addActivity('a2')
        self.pd.addTransition(id='Begin_a1', From='Begin', To='a1', condition='python:1')
        self.pd.addTransition(id='Begin_a2', From='Begin', To='a2', condition='python:0')
        self.pd.addTransition(id='a1_End', From='a1', To='End')
        self.pd.addTransition(id='a2_End', From='a2', To='End')
        getattr(self.pd, 'Begin').edit(kind='standard')
        getattr(self.pd, 'End').edit(kind='standard')

        # Create and activate a Process Instance of the Process definition mentioned above
        pid = self.of.addInstance('xor_split', 'test', 'testComment', 'TestTitle', 0)
        self.pi = getattr(self.of, pid)
        self.of.startInstance(self.pi.id)

        # Forward first workitem
        self.w0 = getattr(self.pi, '0')
        self.of.activateWorkitem(self.pi.id, self.w0.id)
        self.of.completeWorkitem(self.pi.id, self.w0.id)
        self.of.forwardWorkitem(self.pi.id, self.w0.id)
 
    def checkWorkitemSplit(self):
        """ Check the workitem split to two alternative activity"""
        assert getattr(self.pi, '1'), 'workitem 1 not created'
        assert getattr(self.pi, '1').activity_id == 'a1', 'workitem 1 activity not correct'
        assert not hasattr(self.pi, '2'), 'workitem 2 created'


    def checkWorkitemJoin(self):
        """ Check the workitem join from two alternative activity"""
        self.w1 = getattr(self.pi, '1')
        self.of.activateWorkitem(self.pi.id, self.w1.id)
        self.of.completeWorkitem(self.pi.id, self.w1.id)
        self.of.forwardWorkitem(self.pi.id, self.w1.id)
        assert getattr(self.pi, '2'), 'workitem 2 not created'
        assert getattr(self.pi, '2').activity_id == 'End', 'activity of workitem 2 is not correct'
class countWorkitemsTestCase(unittest.TestCase):

    def setUp(self):
        # Create an OpenFlow folder
        self.of = CMFOpenflowTool('of')

        # Create some Process Definition
        for id in ['first','second','third']:
            self.of.addProcess(id=id, BeginEnd=1)
            self.pd = getattr(self.of, id)
            self.pd.addTransition(id=id, From='Begin', To='End')
            self.pd['Begin'].edit(kind='Standard')
            # Routing: 6 workitems
            # instance with workitem inactive and unassigned
            pid = self.of.addInstance(id, 'test1', 'testComment', 'TestTitle', 1)
            # instance with workitem inactive and assigned
            pid = self.of.addInstance(id, 'test2', 'testComment', 'TestTitle', 1)
            pid = self.of.assignWorkitem(pid,'0','testUser')
            # instance with workitem active
            pid = self.of.addInstance(id, 'test3', 'testComment', 'TestTitle', 1)
            self.of.activateWorkitem(pid,'0','testUser')
            # instance with workitem completed
            pid=self.of.addInstance(id, 'test4', 'testComment', 'TestTitle', 1)
            self.of.activateWorkitem(pid,'0','testUser')
            self.of.completeWorkitem(pid,'0')
            # instance with 2 workitems completed
            pid=self.of.addInstance(id, 'test5', 'testComment', 'TestTitle', 1)
            self.of.activateWorkitem(pid,'0','testUser')
            self.of.completeWorkitem(pid,'0')
            self.of.forwardWorkitem(pid,'0')

    def checkCountWorkitems(self):
        """ Check results of countWorkitems"""
        assert self.of.countWorkitems()=={'to do':'6', 'to assign':'3', 'completed':'9'},'Result error for process'
        assert self.of.countWorkitems('first')=={'to do':'2', 'to assign':'1', 'completed':'3'},'Result error for process'
        assert self.of.countWorkitems('first','Begin')=={'to do':'2', 'to assign':'1', 'completed':'2'},'Result error for process and activity'
        assert self.of.countWorkitems('first','Begin','testUser')=={'to do':'2', 'to assign':'1', 'completed':'2'},'Result error for process, activity and user'
class routingAndSplitTestCase(unittest.TestCase):

    def setUp(self):

        # Create an OpenFlow folder 
        self.of = CMFOpenflowTool('of')
        
        # Create a Process Definition with two parallel activity
        self.of.addProcess(id='begin_end', BeginEnd=1)
        self.pd = getattr(self.of, 'begin_end')
        self.pd.addActivity('a1')
        self.pd.addActivity('a2')
        self.pd.addTransition(id='Begin_a1', From='Begin', To='a1')
        self.pd.addTransition(id='Begin_a2', From='Begin', To='a2')
        self.pd.addTransition(id='a1_End', From='a1', To='End')
        self.pd.addTransition(id='a2_End', From='a2', To='End')
        getattr(self.pd, 'Begin').edit(kind='standard')
        getattr(self.pd, 'End').edit(kind='standard')

        # Create and activate a Process Instance of the Process definition mentioned above
        pid = self.of.addInstance('begin_end', 'test', 'testComment', 'TestTitle', 0)
        self.pi = getattr(self.of, pid)
        self.of.startInstance(self.pi.id)

        # Forward first workitem
        self.w0 = getattr(self.pi, '0')
        self.of.activateWorkitem(self.pi.id, self.w0.id)
        self.of.completeWorkitem(self.pi.id, self.w0.id)
        self.of.forwardWorkitem(self.pi.id, self.w0.id)

    def checkWorkitemSplit(self):
        """ Check the workitem split to two parallel activity"""
        assert getattr(self.pi, '1'), 'workitem 1 not created'
        assert getattr(self.pi, '2'), 'workitem 2 not created'
        assert getattr(self.pi, '1').status == 'inactive', 'workitem 1 status not correct'
        assert getattr(self.pi, '2').status == 'inactive', 'workitem 2 status not correct'


    def checkWorkitemJoin(self):
        """ Check the workitem join from two parallel activity """
        self.w1 = getattr(self.pi, '1')
        self.of.activateWorkitem(self.pi.id, self.w1.id)
        self.of.completeWorkitem(self.pi.id, self.w1.id)
        self.of.forwardWorkitem(self.pi.id, self.w1.id)
        assert getattr(self.pi, '3'), 'workitem 3 not created'
        assert getattr(self.pi, '3').blocked, 'workitem 3 is not blocked'
        self.w2 = getattr(self.pi, '2')
        self.of.activateWorkitem(self.pi.id, self.w2.id)
        self.of.completeWorkitem(self.pi.id, self.w2.id)
        self.of.forwardWorkitem(self.pi.id, self.w2.id)
        assert getattr(self.pi, '3').status == 'inactive', 'workitem 3 is not inactive'
        assert not getattr(self.pi, '3').blocked, 'workitem 3 is still blocked'
class routingSimpleTestCase(unittest.TestCase):

    def setUp(self):
        # Create an OpenFlow folder
        self.of = CMFOpenflowTool('of')

        # Create a Process Definition with two activity (Begin, End) and one transition.
        self.of.addProcess(id='begin_end', BeginEnd=1)
        self.pd = getattr(self.of, 'begin_end')
        self.pd.addTransition(id='begin_end', From='Begin', To='End')
        getattr(self.pd, 'Begin').edit(kind='standard')
        getattr(self.pd, 'End').edit(kind='standard')


        # Create a Process Instance of the Process definition mentioned above
        pid = self.of.addInstance('begin_end', 'test', 'testComment', 'TestTitle', 0)
        self.pi = getattr(self.of, pid)

    def checkCreation(self):
        """ Check for the correct creation of the test objects """
        assert self.of, 'openflow folder not created'
        assert self.pd, 'process definition not created'
        assert getattr(self.pd, 'Begin'), 'Begin activity not created'
        assert getattr(self.pd, 'End'), 'End activity not created'
        assert getattr(self.pd, 'begin_end'), 'begin_end transition not created'
        assert self.pi, 'process instance not created'


    def checkActivateInstance(self):
        """ Check the Process Instance activation """
        assert self.pi.status == 'initiated', 'process instance starting status not correct'
        self.of.startInstance(self.pi.id)
        assert self.pi.status == 'running', 'process instance activation not correct'


    def checkSuspendInstance(self):
        """ Check the Process Instance activation """
        assert self.pi.status == 'initiated', 'process instance starting status not correct'
        self.of.suspendInstance(self.pi.id)
        assert self.pi.status == 'suspended', 'process instance suspension not correct'


    def checkResumeInstance(self):
        """ Check the Process Instance activation """
        assert self.pi.status == 'initiated', 'process instance starting status not correct'
        self.of.suspendInstance(self.pi.id)
        assert self.pi.status == 'suspended', 'process instance suspension not correct'
        self.of.resumeInstance(self.pi.id)
        assert self.pi.status == 'initiated', 'process instance suspension not correct'


    def checkTerminationInstance(self):
        """ Check the Process Instance activation """
        assert self.pi.status == 'initiated', 'process instance starting status not correct'
        self.of.terminateInstance(self.pi.id)
        assert self.pi.status == 'terminated', 'process instance suspension not correct'


    def checkAssignUnassignedWorkitem(self):
        """ Check the workitem creation and activation """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        assert self.w.status == 'inactive', 'workitem creation not correct'
        self.of.assignWorkitem(self.pi.id, self.w.id, 'testActor')
        assert self.w.actor == 'testActor', 'workitem assignement not correct'
        self.of.unassignWorkitem(self.pi.id, self.w.id)
        assert self.w.actor == '', 'workitem unassignement not correct'


    def checkActivateWorkitem(self):
        """ Check the workitem creation and activation """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        assert self.w.status == 'inactive', 'workitem creation not correct'
        self.of.activateWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'active', 'workitem activation not correct'


    def checkInactivateWorkitem(self):
        """ Check the workitem inactivation """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        assert self.w.status == 'inactive', 'workitem creation not correct'
        self.of.activateWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'active', 'workitem activation not correct'
        self.of.inactivateWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'inactive', 'workitem inactivation not correct'


    def checkSuspendWorkitem(self):
        """ Check the workitem suspended """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        assert self.w.status == 'inactive', 'workitem creation not correct'
        self.of.suspendWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'suspended', 'workitem suspension not correct'


    def checkResumeWorkitem(self):
        """ Check the workitem resume """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        assert self.w.status == 'inactive', 'workitem creation not correct'
        self.of.suspendWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'suspended', 'workitem suspension not correct'
        self.of.resumeWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'inactive', 'workitem inactivation not correct'


    def checkCompleteWorkitem(self):
        """ Check the workitem completion """
        self.of.startInstance(self.pi.id)
        self.w = getattr(self.pi, '0')
        self.of.activateWorkitem(self.pi.id, self.w.id)
        self.of.completeWorkitem(self.pi.id, self.w.id)
        assert self.w.status == 'complete', 'workitem completion not correct'


    def checkForwardWorkitem(self):
        """ Check the workitem forwarding """
        self.of.startInstance(self.pi.id)
        self.w0 = getattr(self.pi, '0')
        self.of.activateWorkitem(self.pi.id, self.w0.id)
        self.of.completeWorkitem(self.pi.id, self.w0.id)
        self.of.forwardWorkitem(self.pi.id, self.w0.id)
        assert getattr(self.pi, '1'), 'new workitem not created'
        assert getattr(self.pi, '1').status == 'inactive', 'new workitem status not correct'


    def checkCompleteInstance(self):
        """ Check the process instance completion """
        self.of.startInstance(self.pi.id)
        self.w0 = getattr(self.pi, '0')
        self.of.activateWorkitem(self.pi.id, self.w0.id)
        self.of.completeWorkitem(self.pi.id, self.w0.id)
        self.of.forwardWorkitem(self.pi.id, self.w0.id)
        self.w1 = getattr(self.pi, '1')
        self.of.activateWorkitem(self.pi.id, self.w1.id)
        self.of.completeWorkitem(self.pi.id, self.w1.id)
        assert self.w0.status == 'complete', 'first workitem completion not correct'
        assert self.w1.status == 'complete', 'last workitem completion not correct'
        assert self.pi.status == 'complete', 'process instance completion not correct'