From 7962d40a0fc2fc89b18ff9b381dfcf057c978748 Mon Sep 17 00:00:00 2001 From: Erik Amaru Ortiz Date: Mon, 24 Feb 2014 19:10:45 -0400 Subject: [PATCH] Updating Unit Tests for BpmnWorkflow Adapter, and some Bpmn->Workflow logic --- workflow/engine/classes/model/BpmnEvent.php | 12 +- workflow/engine/classes/model/BpmnFlow.php | 47 ++- workflow/engine/classes/model/BpmnGateway.php | 17 +- workflow/engine/classes/model/Route.php | 20 ++ .../Project/Adapter/BpmnWorkflow.php | 219 ++++++++----- .../engine/src/ProcessMaker/Project/Bpmn.php | 39 ++- .../src/ProcessMaker/Project/Workflow.php | 23 ++ .../engine/src/ProcessMaker/Util/Logger.php | 6 +- .../src/Services/Api/ProcessMaker/Project.php | 6 +- .../Project/Adapter/BpmnWorkflowTest.php | 298 +++++++++++++++++- 10 files changed, 589 insertions(+), 98 deletions(-) diff --git a/workflow/engine/classes/model/BpmnEvent.php b/workflow/engine/classes/model/BpmnEvent.php index e4c4a8c06..9a1446b03 100644 --- a/workflow/engine/classes/model/BpmnEvent.php +++ b/workflow/engine/classes/model/BpmnEvent.php @@ -85,9 +85,9 @@ class BpmnEvent extends BaseBpmnEvent // OVERRIDES - public function setActUid($actUid) + public function setActUid($evnUid) { - parent::setActUid($actUid); + parent::setEvnUid($evnUid); $this->bound->setElementUid($this->getEvnUid()); } @@ -165,4 +165,12 @@ class BpmnEvent extends BaseBpmnEvent return $data; } + + public static function exists($evnUid) + { + $c = new Criteria("workflow"); + $c->add(BpmnEventPeer::EVN_UID, $evnUid); + + return BpmnEventPeer::doCount($c) > 0 ? true : false; + } } // BpmnEvent diff --git a/workflow/engine/classes/model/BpmnFlow.php b/workflow/engine/classes/model/BpmnFlow.php index b6e1ca984..6d800f692 100644 --- a/workflow/engine/classes/model/BpmnFlow.php +++ b/workflow/engine/classes/model/BpmnFlow.php @@ -21,17 +21,27 @@ class BpmnFlow extends BaseBpmnFlow * @param $value string * @return \BpmnFlow|null */ - public static function findOneBy($field, $value) + public static function findOneBy($field, $value = null) { $rows = self::findAllBy($field, $value); return empty($rows) ? null : $rows[0]; } - public static function findAllBy($field, $value) + /** + * @param $field + * @param null $value + * @return \BpmnFlow[] + */ + public static function findAllBy($field, $value = null) { + $field = is_array($field) ? $field : array($field => $value); + $c = new Criteria('workflow'); - $c->add($field, $value, Criteria::EQUAL); + + foreach ($field as $key => $value) { + $c->add($key, $value, Criteria::EQUAL); + } return BpmnFlowPeer::doSelect($c); } @@ -83,4 +93,35 @@ class BpmnFlow extends BaseBpmnFlow return $flow; } + /*public static function select($select, $where = array()) + { + $data = array(); + + $c = new Criteria('workflow'); + if ($select !== '*') { + if (is_array($select)) { + foreach ($select as $column) { + $c->addSelectColumn($column); + } + } else { + $c->addSelectColumn($select); + } + } + + if (! empty($where)) { + foreach ($where as $column => $value) { + $c->add($column, $value); + } + } + + $rs = BpmnFlowPeer::doSelectRS($c); + $rs->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + while ($rs->next()) { + $data[] = $rs->getRow(); + } + + return $data; + }*/ + } // BpmnFlow diff --git a/workflow/engine/classes/model/BpmnGateway.php b/workflow/engine/classes/model/BpmnGateway.php index 107c16f64..5a5be2835 100644 --- a/workflow/engine/classes/model/BpmnGateway.php +++ b/workflow/engine/classes/model/BpmnGateway.php @@ -45,6 +45,11 @@ class BpmnGateway extends BaseBpmnGateway } } + /** + * @param $field + * @param $value + * @return \BpmnGateway|null + */ public static function findOneBy($field, $value) { $rows = self::findAllBy($field, $value); @@ -87,8 +92,8 @@ class BpmnGateway extends BaseBpmnGateway public function setActUid($actUid) { - parent::setActUid($actUid); - $this->bound->setElementUid($this->getActUid()); + parent::setGatUid($actUid); + $this->bound->setElementUid($this->getGatUid()); } public function setPrjUid($prjUid) @@ -166,4 +171,12 @@ class BpmnGateway extends BaseBpmnGateway return $data; } + public static function exists($gatUid) + { + $c = new Criteria("workflow"); + $c->add(BpmnGatewayPeer::GAT_UID, $gatUid); + + return BpmnGatewayPeer::doCount($c) > 0 ? true : false; + } + } // BpmnGateway diff --git a/workflow/engine/classes/model/Route.php b/workflow/engine/classes/model/Route.php index ecafc14c0..b0a0d1e12 100755 --- a/workflow/engine/classes/model/Route.php +++ b/workflow/engine/classes/model/Route.php @@ -238,5 +238,25 @@ class Route extends BaseRoute return RoutePeer::doSelect($c); } + + public static function getAll($proUid = null, $start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER) + { + $c = new Criteria('workflow'); + $c->addSelectColumn("ROUTE.*"); + + if (! is_null($proUid)) { + $c->add(RoutePeer::PRO_UID, $proUid, Criteria::EQUAL); + } + + $rs = RoutePeer::doSelectRS($c); + $rs->setFetchmode(\ResultSet::FETCHMODE_ASSOC); + + $routes = array(); + while ($rs->next()) { + $routes[] = $changeCaseTo !== CASE_UPPER ? array_change_key_case($rs->getRow(), CASE_LOWER) : $rs->getRow(); + } + + return $routes; + } } diff --git a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php index 1e44b5732..7ec39c752 100644 --- a/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Adapter/BpmnWorkflow.php @@ -3,6 +3,7 @@ namespace ProcessMaker\Project\Adapter; use ProcessMaker\Project; use ProcessMaker\Util\Hash; +use Symfony\Component\DependencyInjection\Exception\LogicException; /** * Class BpmnWorkflow @@ -105,7 +106,8 @@ class BpmnWorkflow extends Project\Bpmn { $taskData = array(); - $taskData["TAS_UID"] = parent::addActivity($data); + $actUid = parent::addActivity($data); + $taskData["TAS_UID"] = $actUid; if (array_key_exists("ACT_NAME", $data)) { $taskData["TAS_TITLE"] = $data["ACT_NAME"]; @@ -118,6 +120,8 @@ class BpmnWorkflow extends Project\Bpmn } $this->wp->addTask($taskData); + + return $actUid; } public function updateActivity($actUid, $data) @@ -145,55 +149,47 @@ class BpmnWorkflow extends Project\Bpmn $this->wp->removeTask($actUid); } - public function addFlow($data, $diagram) - { - $flows = $diagram["flows"]; - $gateways = $diagram["gateways"]; - $events = $diagram["events"]; - - parent::addFlow($data); +// public function addFlow($data) +// { +// parent::addFlow($data); // to add a workflow route // - activity -> activity ==> route // - activity -> gateway -> activity ==> selection, evaluation, parallel or parallel by evaluation route - $routes = self::mapBpmnFlowsToWorkflowRoute($data, $flows, $gateways, $events); +// $routes = self::mapBpmnFlowsToWorkflowRoute($data, $flows); +// +// if ($routes !== null) { +// foreach ($routes as $routeData) { +// $this->wp->addRoute($routeData["from"], $routeData["to"], $routeData["type"]); +// } +// +// return true; +// } +// +// // to add start event->activity as initial or end task +// switch ($data["FLO_ELEMENT_ORIGIN_TYPE"]) { +// case "bpmnEvent": +// switch ($data["FLO_ELEMENT_DEST_TYPE"]) { +// case "bpmnActivity": +// $event = \BpmnEventPeer::retrieveByPK($data["FLO_ELEMENT_ORIGIN"]); +// +// switch ($event && $event->getEvnType()) { +// case "START": +// // then set that activity/task as "Start Task" +// $this->wp->setStartTask($data["FLO_ELEMENT_DEST"]); +// break; +// } +// break; +// } +// break; +// } - if ($routes !== null) { - foreach ($routes as $routeData) { - $this->wp->addRoute($routeData["from"], $routeData["to"], $routeData["type"]); - } +// } - return true; - } - - // to add start event->activity as initial or end task - switch ($data["FLO_ELEMENT_ORIGIN_TYPE"]) { - case "bpmnEvent": - switch ($data["FLO_ELEMENT_DEST_TYPE"]) { - case "bpmnActivity": - $event = \BpmnEventPeer::retrieveByPK($data["FLO_ELEMENT_ORIGIN"]); - - switch ($event && $event->getEvnType()) { - case "START": - // then set that activity/task as "Start Task" - $this->wp->setStartTask($data["FLO_ELEMENT_DEST"]); - break; - } - break; - } - break; - } - } - - public function updateFlow($floUid, $data) - { - if (! self::isModified("flow", $floUid, $data)) { - self::log("Update Flow: $floUid (No Changes)"); - return false; - } - - parent::updateFlow($floUid, $data); - } +// public function updateFlow($floUid, $data, $flows) +// { +// parent::updateFlow($floUid, $data); +// } public function removeFlow($floUid) { @@ -224,7 +220,20 @@ class BpmnWorkflow extends Project\Bpmn $this->wp->setEndTask($activity->getActUid(), false); } } + } else { + switch ($flow->getFloElementOriginType()) { + case "bpmnActivity": + switch ($flow->getFloElementDestType()) { + // activity->activity + case "bpmnActivity": + $this->wp->removeRouteFromTo($flow->getFloElementOrigin(), $flow->getFloElementDest()); + break; + } + break; + } } + + // TODO Complete for other routes, activity->activity, activity->gateway and viceversa } public function addEvent($data) @@ -236,35 +245,102 @@ class BpmnWorkflow extends Project\Bpmn parent::addEvent($data); } - public function removeEvent($evnUid) + public function mapBpmnFlowsToWorkflowRoutes() { -// $event = \BpmnEventPeer::retrieveByPK($evnUid); -// -// switch ($event->getEvnType()) { -// case "START": -// $flow = \BpmnFlow::findOneBy(\BpmnFlowPeer::FLO_ELEMENT_ORIGIN, $event->getEvnUid()); -// if (! is_null($flow) && $flow->getFloElementDestType() == "bpmnActivity") { -// $activity = \BpmnActivityPeer::retrieveByPK($flow->getFloElementDest()); -// if (! is_null($activity)) { -// $this->wp->setStartTask($activity->getActUid(), false); -// } -// } -// break; -// case "END": -// $flow = \BpmnFlow::findOneBy(\BpmnFlowPeer::FLO_ELEMENT_DEST, $event->getEvnUid()); -// if (! is_null($flow) && $flow->getFloElementOriginType() == "bpmnActivity") { -// $activity = \BpmnActivityPeer::retrieveByPK($flow->getFloElementOrigin()); -// if (! is_null($activity)) { -// $this->wp->setEndTask($activity->getActUid(), false); -// } -// } -// break; -// } + $activities = $this->getActivities(); - parent::removeEvent($evnUid); + foreach ($activities as $activity) { + + $flows = \BpmnFlow::findAllBy(array( + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN => $activity["ACT_UID"], + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN_TYPE => "bpmnActivity" + )); + + // + foreach ($flows as $flow) { + switch ($flow->getFloElementDestType()) { + case "bpmnActivity": + // (activity -> activity) + $this->wp->addRoute($activity["ACT_UID"], $flow->getFloElementDest(), "SEQUENTIAL"); + break; + + case "bpmnGateway": + // (activity -> gateway) + // we must find the related flows: gateway -> + $gatUid = $flow->getFloElementDest(); + $gatewayFlows = \BpmnFlow::findAllBy(array( + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN => $gatUid, + \BpmnFlowPeer::FLO_ELEMENT_ORIGIN_TYPE => "bpmnGateway" + )); + + foreach ($gatewayFlows as $gatewayFlow) { + $gatewayFlow = $gatewayFlow->toArray(); + + switch ($gatewayFlow['FLO_ELEMENT_DEST_TYPE']) { + case 'bpmnActivity': + // (gateway -> activity) + $gateway = \BpmnGateway::findOneBy(\BpmnGatewayPeer::GAT_UID, $gatUid)->toArray(); + + switch ($gateway["GAT_TYPE"]) { + //case 'SELECTION': + case self::BPMN_GATEWAY_COMPLEX: + $routeType = "SELECT"; + break; + //case 'EVALUATION': + case self::BPMN_GATEWAY_EXCLUSIVE: + $routeType = "EVALUATE"; + break; + //case 'PARALLEL': + case self::BPMN_GATEWAY_PARALLEL: + if ($gateway["GAT_DIRECTION"] == "DIVERGING") { + $routeType = "PARALLEL"; + } elseif ($gateway["GAT_DIRECTION"] == "CONVERGING") { + $routeType = "SEC-JOIN"; + } else { + throw new \LogicException(sprintf( + "Invalid Gateway direction, accepted values: [%s|%s], given: %s.", + "DIVERGING", "CONVERGING", $gateway["GAT_DIRECTION"] + )); + } + break; + //case 'PARALLEL_EVALUATION': + case self::BPMN_GATEWAY_INCLUSIVE: + if ($gateway["GAT_DIRECTION"] == "DIVERGING") { + $routeType = "PARALLEL-BY-EVALUATION"; + } elseif ($gateway["GAT_DIRECTION"] == "CONVERGING") { + $routeType = "SEC-JOIN"; + } else { + throw new \LogicException(sprintf( + "Invalid Gateway direction, accepted values: [%s|%s], given: %s.", + "DIVERGING", "CONVERGING", $gateway["GAT_DIRECTION"] + )); + } + break; +// case 'PARALLEL_JOIN': +// $routeType = 'SEC-JOIN'; +// break; + default: + throw new \LogicException(sprintf("Unsupported Gateway type: %s", $gateway['GAT_TYPE'])); + } + + $this->wp->addRoute($activity["ACT_UID"], $gatewayFlow['FLO_ELEMENT_DEST'], $routeType); + break; + default: + // for processmaker is only allowed flows between "gateway -> activity" + // any another flow is considered invalid + throw new \LogicException(sprintf( + "For ProcessMaker is only allowed flows between \"gateway -> activity\" " . PHP_EOL . + "Given: bpmnGateway -> " . $gatewayFlow['FLO_ELEMENT_DEST_TYPE'] + )); + } + } + break; + } + } + } } - public static function mapBpmnFlowsToWorkflowRoute($flow, $flows, $gateways, $events) + public static function mapBpmnFlowsToWorkflowRoute2($flow, $flows, $gateways, $events) { $fromUid = $flow['FLO_ELEMENT_ORIGIN']; $result = array(); @@ -387,11 +463,6 @@ class BpmnWorkflow extends Project\Bpmn return $result; } -// public function getActivities() -// { -// return parent::getActivities(); -// } - public function remove() { parent::remove(); diff --git a/workflow/engine/src/ProcessMaker/Project/Bpmn.php b/workflow/engine/src/ProcessMaker/Project/Bpmn.php index 262e6dcab..a19110254 100644 --- a/workflow/engine/src/ProcessMaker/Project/Bpmn.php +++ b/workflow/engine/src/ProcessMaker/Project/Bpmn.php @@ -325,6 +325,7 @@ class Bpmn extends Handler $activity = ActivityPeer::retrieveByPK($actUid); $activity->delete(); + //TODO if the activity was removed, the related flows to that activity must be removed self::log("Remove Activity Success!"); } catch (\Exception $e) { @@ -438,7 +439,6 @@ class Bpmn extends Handler $gateway->setPrjUid($this->getUid()); $gateway->setProUid($this->getProcess("object")->getProUid()); $gateway->save(); - self::log("Add Gateway Success!"); } catch (\Exception $e) { self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); @@ -518,13 +518,48 @@ class Bpmn extends Handler } try { + switch ($data["FLO_ELEMENT_ORIGIN_TYPE"]) { + case "bpmnActivity": $class = "BpmnActivity"; break; + case "bpmnGateway": $class = "BpmnGateway"; break; + case "bpmnEvent": $class = "BpmnEvent"; break; + default: + throw new \RuntimeException(sprintf("Invalid Object type, accepted types: [%s|%s|%s], given %s.", + "BpmnActivity", "BpmnBpmnGateway", "BpmnEvent", $data["FLO_ELEMENT_ORIGIN_TYPE"] + )); + } + + // Validate origin object exists + if (! $class::exists($data["FLO_ELEMENT_ORIGIN"])) { + throw new \RuntimeException(sprintf("Reference not found, the %s with UID: %s, does not exist!", + ucfirst($data["FLO_ELEMENT_ORIGIN_TYPE"]), $data["FLO_ELEMENT_ORIGIN"] + )); + } + + switch ($data["FLO_ELEMENT_DEST_TYPE"]) { + case "bpmnActivity": $class = "BpmnActivity"; break; + case "bpmnGateway": $class = "BpmnGateway"; break; + case "bpmnEvent": $class = "BpmnEvent"; break; + default: + throw new \RuntimeException(sprintf("Invalid Object type, accepted types: [%s|%s|%s], given %s.", + "BpmnActivity", "BpmnBpmnGateway", "BpmnEvent", $data["FLO_ELEMENT_DEST_TYPE"] + )); + } + + // Validate origin object exists + if (! $class::exists($data["FLO_ELEMENT_DEST"])) { + throw new \RuntimeException(sprintf("Reference not found, the %s with UID: %s, does not exist!", + ucfirst($data["FLO_ELEMENT_DEST_TYPE"]), $data["FLO_ELEMENT_DEST"] + )); + } + $flow = new Flow(); $flow->fromArray($data, BasePeer::TYPE_FIELDNAME); $flow->setPrjUid($this->getUid()); $flow->setDiaUid($this->getDiagram("object")->getDiaUid()); $flow->save(); - self::log("Add Flow Success!"); + + return $flow->getFloUid(); } catch (\Exception $e) { self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); throw $e; diff --git a/workflow/engine/src/ProcessMaker/Project/Workflow.php b/workflow/engine/src/ProcessMaker/Project/Workflow.php index 3dfd0e6f0..148b9cc56 100644 --- a/workflow/engine/src/ProcessMaker/Project/Workflow.php +++ b/workflow/engine/src/ProcessMaker/Project/Workflow.php @@ -325,6 +325,24 @@ class Workflow extends Handler } } + public function removeRouteFromTo($fromTasUid, $toTasUid) + { + try { + self::log("Remove Route from $fromTasUid -> to $toTasUid"); + + $route = Route::findOneBy(array( + RoutePeer::TAS_UID => $fromTasUid, + RoutePeer::ROU_NEXT_TASK => $toTasUid + )); + + $route->delete(); + self::log("Remove Route Success!"); + } catch (\Exception $e) { + self::log("Exception: ", $e->getMessage(), "Trace: ", $e->getTraceAsString()); + throw $e; + } + } + public function getRoute($rouUid) { $route = new Route(); @@ -332,6 +350,11 @@ class Workflow extends Handler return $route->load($rouUid); } + public function getRoutes() + { + return Route::getAll($proUid = null, $start = null, $limit = null, $filter = '', $changeCaseTo = CASE_UPPER); + } + /**************************************************************************************************** * Migrated Methods from class.processMap.php class * diff --git a/workflow/engine/src/ProcessMaker/Util/Logger.php b/workflow/engine/src/ProcessMaker/Util/Logger.php index 6818599fb..7dc8716d4 100644 --- a/workflow/engine/src/ProcessMaker/Util/Logger.php +++ b/workflow/engine/src/ProcessMaker/Util/Logger.php @@ -4,7 +4,7 @@ namespace ProcessMaker\Util; /** * Singleton Class Logger * - * This Utility is usefull to log local messages + * This Utility is useful to log local messages * @package ProcessMaker\Util * @author Erik Amaru Ortiz */ @@ -43,7 +43,7 @@ class Logger $this->setLog(date('Y-m-d H:i:s') . " "); foreach ($args as $str) { - $this->setLog((is_string($str) ? $str : print_r($str, true)) . PHP_EOL); + $this->setLog((is_string($str) ? $str : var_export($str, true)) . PHP_EOL); } } @@ -53,7 +53,7 @@ class Logger $this->setLog(date('Y-m-d H:i:s') . " "); foreach ($args as $str) { - $this->setLog((is_string($str) ? $str : print_r($str, true)) . " "); + $this->setLog((is_string($str) ? $str : var_export($str, true)) . " "); } } diff --git a/workflow/engine/src/Services/Api/ProcessMaker/Project.php b/workflow/engine/src/Services/Api/ProcessMaker/Project.php index 140089e54..d8f866620 100644 --- a/workflow/engine/src/Services/Api/ProcessMaker/Project.php +++ b/workflow/engine/src/Services/Api/ProcessMaker/Project.php @@ -249,9 +249,9 @@ class Project extends Api foreach ($diagram["flows"] as $flowData) { $flow = $bwp->getFlow($flowData["FLO_UID"]); if (is_null($flow)) { - $bwp->addFlow($flowData, $diagram); + $bwp->addFlow($flowData, $diagram["flows"]); } elseif (! $bwp->isEquals($flow, $flowData)) { - $bwp->updateFlow($flowData["FLO_UID"], $flowData); + $bwp->updateFlow($flowData["FLO_UID"], $flowData, $diagram["flows"]); } else { Util\Logger::log("Update Flow ({$flowData["FLO_UID"]}) Skipped - No changes required"); } @@ -266,6 +266,8 @@ class Project extends Api } } + $bwp->mapBpmnFlowsToWorkflowRoutes(); + return $result; } catch (\Exception $e) { throw new RestException(Api::STAT_APP_EXCEPTION, $e->getMessage()); diff --git a/workflow/engine/src/Tests/ProcessMaker/Project/Adapter/BpmnWorkflowTest.php b/workflow/engine/src/Tests/ProcessMaker/Project/Adapter/BpmnWorkflowTest.php index 2a00fb174..5dd78bdee 100644 --- a/workflow/engine/src/Tests/ProcessMaker/Project/Adapter/BpmnWorkflowTest.php +++ b/workflow/engine/src/Tests/ProcessMaker/Project/Adapter/BpmnWorkflowTest.php @@ -2,6 +2,8 @@ namespace Tests\ProcessMaker\Project\Adapter; use \ProcessMaker\Project; +use \ProcessMaker\Exception; + if (! class_exists("Propel")) { include_once __DIR__ . "/../../../bootstrap.php"; @@ -19,6 +21,7 @@ class BpmnWorkflowTest extends \PHPUnit_Framework_TestCase public static function tearDownAfterClass() { + return false; //cleaning DB foreach (self::$uids as $prjUid) { $bwap = Project\Adapter\BpmnWorkflow::load($prjUid); @@ -60,6 +63,8 @@ class BpmnWorkflowTest extends \PHPUnit_Framework_TestCase $this->assertEquals($project["PRJ_NAME"], $process["PRO_TITLE"]); $this->assertEquals($project["PRJ_DESCRIPTION"], $process["PRO_DESCRIPTION"]); $this->assertEquals($project["PRJ_AUTHOR"], $process["PRO_CREATE_USER"]); + + return $bwap; } function testCreate() @@ -85,8 +90,6 @@ class BpmnWorkflowTest extends \PHPUnit_Framework_TestCase $wp = null; } - self::$uids[] = $bwap->getUid(); - $this->assertNotEmpty($bp); $this->assertNotEmpty($wp); $this->assertEquals($bp->getUid(), $wp->getUid()); @@ -98,20 +101,295 @@ class BpmnWorkflowTest extends \PHPUnit_Framework_TestCase $this->assertEquals($project["PRJ_DESCRIPTION"], $process["PRO_DESCRIPTION"]); $this->assertEquals($project["PRJ_AUTHOR"], $process["PRO_CREATE_USER"]); + return $bwap; + } + + /** + * @depends testCreate + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + */ + function testRemove(Project\Adapter\BpmnWorkflow $bwap) + { + $prjUid = $bwap->getUid(); + $bwap->remove(); + $bp = $wp = null; + + try { + $bp = Project\Bpmn::load($prjUid); + } catch (Exception\ProjectNotFound $e) {} + + try { + $wp = Project\Workflow::load($prjUid); + } catch (Exception\ProjectNotFound $e) {} + + $this->assertNull($bp); + $this->assertNull($wp); + } + + /* + * Testing Project's Activity + */ + + /** + * @depends testNew + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + * @return string + */ + function testAddActivity($bwap) + { + // before add activity, we need to add a diagram and process to the project $bwap->addDiagram(); $bwap->addProcess(); - // Save to DB - $bwap->addActivity(array( + // add the new activity + $actUid = $bwap->addActivity(array( "ACT_NAME" => "Activity #1", "BOU_X" => "50", "BOU_Y" => "50" )); - $bwap->addActivity(array( - "ACT_NAME" => "Activity #2", - "BOU_X" => "250", - "BOU_Y" => "250" - )); + $wp = Project\Workflow::load($bwap->getUid()); + + $activity = $bwap->getActivity($actUid); + $task = $wp->getTask($actUid); + + $this->assertEquals($activity["ACT_NAME"], $task["TAS_TITLE"]); + $this->assertEquals($activity["BOU_X"], $task["TAS_POSX"]); + $this->assertEquals($activity["BOU_Y"], $task["TAS_POSY"]); + + return $actUid; } -} \ No newline at end of file + + /** + * @depends testNew + * @depends testAddActivity + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + * @param string $actUid + */ + function testUpdateActivity($bwap, $actUid) + { + $updatedData = array( + "ACT_NAME" => "Activity #1 - (Modified)", + "BOU_X" => 122, + "BOU_Y" => 250 + ); + + $bwap->updateActivity($actUid, $updatedData); + $activity = $bwap->getActivity($actUid); + $wp = Project\Workflow::load($bwap->getUid()); + $task = $wp->getTask($actUid); + + $this->assertEquals($activity["ACT_NAME"], $task["TAS_TITLE"]); + $this->assertEquals($activity["BOU_X"], $task["TAS_POSX"]); + $this->assertEquals($activity["BOU_Y"], $task["TAS_POSY"]); + } + + /** + * @depends testNew + * @depends testAddActivity + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + * @param string $actUid + */ + function testRemoveActivity($bwap, $actUid) + { + $bwap->removeActivity($actUid); + $activity = $bwap->getActivity($actUid); + + $this->assertNull($activity); + } + + /* + * Testing Project's Flows + */ + + /** + * @depends testNew + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + * @return string + */ + function testAddActivityToActivityFlow($bwap) + { + $actUid1 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #1", + "BOU_X" => 122, + "BOU_Y" => 222 + )); + $actUid2 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #2", + "BOU_X" => 322, + "BOU_Y" => 422 + )); + + $flowData = array( + 'FLO_TYPE' => 'SEQUENCE', + 'FLO_ELEMENT_ORIGIN' => $actUid1, + 'FLO_ELEMENT_ORIGIN_TYPE' => 'bpmnActivity', + 'FLO_ELEMENT_DEST' => $actUid2, + 'FLO_ELEMENT_DEST_TYPE' => 'bpmnActivity', + 'FLO_X1' => 326, + 'FLO_Y1' => 146, + 'FLO_X2' => 461, + 'FLO_Y2' => 146, + ); + + $flowUid = $bwap->addFlow($flowData); + $bwap->mapBpmnFlowsToWorkflowRoutes(); + + $route = \Route::findOneBy(array( + \RoutePeer::TAS_UID => $actUid1, + \RoutePeer::ROU_NEXT_TASK => $actUid2 + )); + + $this->assertNotNull($route); + $this->assertTrue(is_string($flowUid)); + $this->assertEquals(32, strlen($flowUid)); + $this->assertEquals($route->getRouNextTask(), $actUid2); + $this->assertEquals($route->getRouType(), "SEQUENTIAL"); + + return array("flow_uid" => $flowUid, "activitiesUid" => array($actUid1, $actUid2)); + } + + + /** + * @depends testNew + * @depends testAddActivityToActivityFlow + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + * @param array $input + */ + function testRemoveActivityToActivityFlow($bwap, $input) + { + $bwap->removeFlow($input["flow_uid"]); + $this->assertNull($bwap->getFlow($input["flow_uid"])); + + $route = \Route::findOneBy(array( + \RoutePeer::TAS_UID => $input["activitiesUid"][0], + \RoutePeer::ROU_NEXT_TASK => $input["activitiesUid"][1] + )); + + $this->assertNull($route); + + // cleaning + $bwap->removeActivity($input["activitiesUid"][0]); + $bwap->removeActivity($input["activitiesUid"][1]); + + $this->assertCount(0, $bwap->getActivities()); + } + + /** + * @depends testNew + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + */ + function testActivityToInclusiveGatewayToActivityFlowsSingle($bwap) + { + $actUid1 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #1", + "BOU_X" => 198, + "BOU_Y" => 56 + )); + $actUid2 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #2", + "BOU_X" => 198, + "BOU_Y" => 250 + )); + $gatUid = $bwap->addGateway(array( + "GAT_NAME" => "Gateway #1", + "GAT_TYPE" => "INCLUSIVE", + "GAT_DIRECTION" => "DIVERGING", + "BOU_X" => 256, + "BOU_Y" => 163 + )); + + $flowUid1 = $bwap->addFlow(array( + 'FLO_TYPE' => 'SEQUENCE', + 'FLO_ELEMENT_ORIGIN' => $actUid1, + 'FLO_ELEMENT_ORIGIN_TYPE' => 'bpmnActivity', + 'FLO_ELEMENT_DEST' => $gatUid, + 'FLO_ELEMENT_DEST_TYPE' => 'bpmnGateway', + 'FLO_X1' => 273, + 'FLO_Y1' => 273, + 'FLO_X2' => 163, + 'FLO_Y2' => 163, + )); + + $flowUid2 = $bwap->addFlow(array( + 'FLO_TYPE' => 'SEQUENCE', + 'FLO_ELEMENT_ORIGIN' => $gatUid, + 'FLO_ELEMENT_ORIGIN_TYPE' => 'bpmnGateway', + 'FLO_ELEMENT_DEST' => $actUid2, + 'FLO_ELEMENT_DEST_TYPE' => 'bpmnActivity', + 'FLO_X1' => 273, + 'FLO_Y1' => 273, + 'FLO_X2' => 249, + 'FLO_Y2' => 249, + )); + + $bwap->mapBpmnFlowsToWorkflowRoutes(); + + // cleaning + $bwap->removeActivity($actUid1); + $bwap->removeActivity($actUid2); + $bwap->removeFlow($flowUid1); + $bwap->removeFlow($flowUid2); + + $this->assertCount(0, $bwap->getActivities()); + $this->assertCount(0, $bwap->getFlows()); + + $wp = Project\Workflow::load($bwap->getUid()); + + $this->assertCount(0, $wp->getTasks()); + $this->assertCount(0, $wp->getRoutes()); + } + + /** + * @depends testNew + * @param \ProcessMaker\Project\Adapter\BpmnWorkflow $bwap + */ + function testActivityToInclusiveGatewayToActivityFlowsMultiple($bwap) + { + /*$actUid1 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #1", + "BOU_X" => 198, + "BOU_Y" => 56 + )); + $actUid2 = $bwap->addActivity(array( + "ACT_NAME" => "Activity #2", + "BOU_X" => 198, + "BOU_Y" => 250 + )); + $gatUid = $bwap->addGateway(array( + "GAT_NAME" => "Gateway #1", + "GAT_TYPE" => "INCLUSIVE", + "GAT_DIRECTION" => "DIVERGING", + "BOU_X" => 256, + "BOU_Y" => 163 + )); + + $flowUid1 = $bwap->addFlow(array( + 'FLO_TYPE' => 'SEQUENCE', + 'FLO_ELEMENT_ORIGIN' => $actUid1, + 'FLO_ELEMENT_ORIGIN_TYPE' => 'bpmnActivity', + 'FLO_ELEMENT_DEST' => $gatUid, + 'FLO_ELEMENT_DEST_TYPE' => 'bpmnGateway', + 'FLO_X1' => 273, + 'FLO_Y1' => 273, + 'FLO_X2' => 163, + 'FLO_Y2' => 163, + )); + + $flowUid1 = $bwap->addFlow(array( + 'FLO_TYPE' => 'SEQUENCE', + 'FLO_ELEMENT_ORIGIN' => $gatUid, + 'FLO_ELEMENT_ORIGIN_TYPE' => 'bpmnGateway', + 'FLO_ELEMENT_DEST' => $actUid2, + 'FLO_ELEMENT_DEST_TYPE' => 'bpmnActivity', + 'FLO_X1' => 273, + 'FLO_Y1' => 273, + 'FLO_X2' => 249, + 'FLO_Y2' => 249, + )); + + $bwap->mapBpmnFlowsToWorkflowRoutes();*/ + } +} + +