diff --git a/database/factories/DynaformFactory.php b/database/factories/DynaformFactory.php new file mode 100644 index 000000000..c790e5fda --- /dev/null +++ b/database/factories/DynaformFactory.php @@ -0,0 +1,26 @@ +define(\ProcessMaker\Model\Dynaform::class, function(Faker $faker) { + $date = $faker->dateTime(); + return [ + 'DYN_UID' => G::generateUniqueID(), + 'DYN_ID' => '', + 'DYN_TITLE' => '', + 'DYN_DESCRIPTION' => '', + 'PRO_UID' => function() { + $process = factory(\ProcessMaker\Model\Process::class)->create(); + return $process->PRO_UID; + }, + 'DYN_TYPE' => 'xmlform', + 'DYN_FILENAME' => '', + 'DYN_CONTENT' => '', + 'DYN_LABEL' => '', + 'DYN_VERSION' => 2, + 'DYN_UPDATE_DATE' => $date->format('Y-m-d H:i:s'), + ]; +}); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index c4d7364f0..60c6506dd 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -25,6 +25,7 @@ define('PATH_SEP', '/'); define('PATH_METHODS', dirname(__DIR__).'/workflow/engine/methods/'); define('SYS_LANG', 'en'); define('DB_ADAPTER', 'mysql'); +define('SYS_SKIN', 'neoclassic'); define('SYS_SYS', 'workflow'); define('PATH_WORKSPACE',PATH_TRUNK.'/shared/sites/' . SYS_SYS . '/'); define('PMTABLE_KEY','pmtable'); @@ -33,6 +34,7 @@ error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT); //This path includes pmTable model classes set_include_path(get_include_path() . PATH_SEPARATOR .dirname(__DIR__). "/shared/sites/".SYS_SYS."/"); + // Setup basic app services $app = require __DIR__ . '/../bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); diff --git a/tests/unit/workflow/engine/classes/PmDynaformTest.php b/tests/unit/workflow/engine/classes/PmDynaformTest.php new file mode 100644 index 000000000..d6c033209 --- /dev/null +++ b/tests/unit/workflow/engine/classes/PmDynaformTest.php @@ -0,0 +1,535 @@ +createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 6, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(); + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning null if parameters is empty. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_parameters_is_empty() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform([]); + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning null if current dynaform not exist. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_current_dynaform_not_exist() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => G::generateUniqueID()]); + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning null if parameters is not empty. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_parameters_is_not_empty() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(["APP_DATA" => []]); + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning null if parameter is a string. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_parameter_is_a_string() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(""); + + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning null if parameter is a integer. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_parameter_is_a_integer() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(1); + + $result = $pmDynaform->getDynaform(); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaform() method returning record property. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_record_property_if_record_is_not_null() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 4, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + $expected = (array) $dynaform->first()->toArray(); + unset($expected['id']); //This is removed because is aggregate from factory. + //first execution in constructor + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => $arrayForm['items'][0]['id']]); + //second execution + $pmDynaform->getDynaform(); + //third execution + $pmDynaform->getDynaform(); + + $this->assertEquals($expected, $pmDynaform->record); + } + + /** + * Check if the getDynaform() method setting langs property in null if current dynaform not exist. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_langs_property_in_null_if_current_dynaform_not_exist() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 6, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => G::generateUniqueID()]); + $pmDynaform->getDynaform(); + + $this->assertEquals(null, $pmDynaform->langs); + } + + /** + * Check if the getDynaform() method returning null if dynaform not exist in the process. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_null_if_dynaform_not_exist_in_the_process() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 5, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => G::generateUniqueID()]); + $pmDynaform->getDynaform(); + + $this->assertEquals(null, $pmDynaform->record); + } + + /** + * Check if the getDynaform() method returning fields. + * @covers PmDynaform::getDynaform + * @test + */ + public function it_should_return_a_dynaform_in_array_format() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 3, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + $expected = (array) $dynaform->first()->toArray(); + unset($expected['id']); //This is removed because is aggregate from factory. + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => $arrayForm['items'][0]['id']]); + $result = $pmDynaform->getDynaform(); + $this->assertEquals($expected, $result); + } + + /** + * Check if the getDynaforms() method returning null when not exist dynaform. + * @covers PmDynaform::getDynaforms + * @test + */ + public function it_should_return_null_when_not_exist_dynaform() + { + $process = factory(Process::class, 1)->create(); + + $arrayForm = $this->createArrayDynaform(); + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 7, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(); + $result = $pmDynaform->getDynaforms(['CURRENT_DYNAFORM' => G::generateUniqueID()]); + + $this->assertEquals(null, $result); + } + + /** + * Check if the getDynaforms() method returning null when record is null. + * @covers PmDynaform::getDynaforms + * @test + */ + public function it_should_return_null_when_record_is_null() + { + $pmDynaform = new PmDynaform(); + $pmDynaform->getDynaforms(); + + $this->assertEquals(null, $pmDynaform->record); + } + + /** + * Check if the getDynaforms() method returning record property. + * @covers PmDynaform::getDynaforms + * @test + */ + public function it_should_return_array_dynaforms_except_current_dynaform_in_second_execution() + { + $process = factory(Process::class, 1)->create(); + + $arrayForm = $this->createArrayDynaform(); + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 7, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $arrayForm2 = $this->createArrayDynaform(); + $dynaform2 = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 9, + 'DYN_UID' => $arrayForm2['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm2) + ]); + + $expected = (array) $dynaform2->first()->toArray(); + unset($expected['id']); //This is removed because is aggregate from factory. + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => $arrayForm['items'][0]['id']]); + $pmDynaform->getDynaforms(); + + $this->assertEquals([$expected], $pmDynaform->records); + } + + /** + * Check if the getDynaforms() method returning arrays dynaforms except current dynaform. + * @covers PmDynaform::getDynaforms + * @test + */ + public function it_should_return_array_dynaforms_except_current_dynaform() + { + $process = factory(Process::class, 1)->create(); + + $arrayForm = $this->createArrayDynaform(); + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 7, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $arrayForm2 = $this->createArrayDynaform(); + $dynaform2 = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 9, + 'DYN_UID' => $arrayForm2['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm2) + ]); + + $expected = (array) $dynaform2->first()->toArray(); + unset($expected['id']); //This is removed because is aggregate from factory. + + $pmDynaform = new PmDynaform(['CURRENT_DYNAFORM' => $arrayForm['items'][0]['id']]); + $result = $pmDynaform->getDynaforms(); + + $this->assertEquals([$expected], $result); + } + + /** + * Check if the isUsed() method is returning false when not exist data related to process id. + * @covers PmDynaform::isUsed + * @test + */ + public function it_should_return_false_when_not_exist_data_related_to_id_process() + { + $processId = G::generateUniqueID(); + + $pmDynaform = new PmDynaform(); + $result = $pmDynaform->isUsed($processId, 'var1'); + + $this->assertEquals(false, $result); + } + + /** + * Check if the isUsed() method is returning the ID of the dynaform in case + * the variable is part of the dynaform. + * @covers PmDynaform::isUsed + * @test + */ + public function it_should_return_id_of_dynaform_when_is_used_variable() + { + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 1, + 'DYN_UID' => $arrayForm['items'][0]['id'], + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(); + $result = $pmDynaform->isUsed($process[0]->PRO_UID, $arrayForm['items'][0]['variables'][0]); + + $this->assertEquals($dynaform[0]->DYN_UID, $result); + } + + /** + * Check if the isUsed() method is returning false in case the variable is + * not part of the dynaform. + * @covers PmDynaform::isUsed + * @test + */ + public function it_should_return_false_when_not_used_variable() + { + $arrayVariable = $this->createArrayVariable('var10'); + + $arrayForm = $this->createArrayDynaform(); + + $process = factory(Process::class, 1)->create(); + + $dynaform = factory(Dynaform::class, 1)->create([ + 'DYN_ID' => 2, + 'PRO_UID' => $process[0]->PRO_UID, + 'DYN_CONTENT' => G::json_encode($arrayForm) + ]); + + $pmDynaform = new PmDynaform(); + $result = $pmDynaform->isUsed($process[0]->PRO_UID, $arrayVariable); + + $this->assertEquals(false, $result); + } + + /** + * Return an object that represents the structure of a process variable. + * @return array + */ + private function createArrayVariable($varName) + { + return [ + "var_uid" => G::generateUniqueID(), + "prj_uid" => G::generateUniqueID(), + "var_name" => $varName, + "var_field_type" => "string", + "var_field_size" => 10, + "var_label" => "string", + "var_dbconnection" => "workflow", + "var_dbconnection_label" => "PM Database", + "var_sql" => "", + "var_null" => 0, + "var_default" => "", + "var_accepted_values" => "[]", + "inp_doc_uid" => "" + ]; + } + + /** + * Returns an object that represents the structure of a control. + * @return array + */ + private function createArrayControl($varUid, $varName) + { + return [ + "type" => "textarea", + "variable" => $varName, + "var_uid" => $varUid, + "dataType" => "string", + "protectedValue" => false, + "id" => "textareaVar001", + "name" => "textareaVar001", + "label" => "textarea_1", + "defaultValue" => "", + "placeholder" => "", + "hint" => "", + "required" => false, + "requiredFieldErrorMessage" => "", + "validate" => "", + "validateMessage" => "", + "mode" => "parent", + "dbConnection" => "workflow", + "dbConnectionLabel" => "PM Database", + "sql" => "", + "rows" => "5", + "var_name" => "textareaVar001", + "colSpan" => 12 + ]; + } + + /** + * Returns an object that represents the structure of a dynaform. + * @return array + */ + private function createArrayDynaform() + { + $var1 = $this->createArrayVariable('var1'); + $control1 = $this->createArrayControl($var1['var_uid'], $var1['var_name']); + + $var2 = $this->createArrayVariable('var2'); + $control2 = $this->createArrayControl($var2['var_uid'], $var2['var_name']); + + return [ + "name" => "subform", + "description" => "", + "items" => [ + [ + "type" => "form", + "variable" => "", + "var_uid" => "", + "dataType" => "", + "id" => G::generateUniqueID(), + "name" => "subform", + "description" => "", + "mode" => "edit", + "script" => "", + "language" => "en", + "externalLibs" => "", + "printable" => false, + "items" => [ + [$control1], + [$control2] + ], + "variables" => [ + $var1, + $var2 + ] + ] + ] + ]; + } +} diff --git a/workflow/engine/classes/PmDynaform.php b/workflow/engine/classes/PmDynaform.php index 0cb611a06..a4b8d5262 100644 --- a/workflow/engine/classes/PmDynaform.php +++ b/workflow/engine/classes/PmDynaform.php @@ -4,6 +4,7 @@ use ProcessMaker\Core\System; use ProcessMaker\BusinessModel\DynaForm\SuggestTrait; use ProcessMaker\BusinessModel\Cases; use ProcessMaker\BusinessModel\DynaForm\ValidatorFactory; +use ProcessMaker\Model\Dynaform as ModelDynaform; /** * Implementing pmDynaform library in the running case. @@ -78,6 +79,14 @@ class PmDynaform return $titleDynaform; } + /** + * Get a dynaform. + * @return array|null + * @see ConsolidatedCases->processConsolidated() + * @see workflow/engine/methods/cases/caseConsolidated.php + * @see ProcessMaker\BusinessModel\Cases->getCaseVariables() + * @see PmDynaform->__construct() + */ public function getDynaform() { if (!isset($this->fields["CURRENT_DYNAFORM"])) { @@ -86,22 +95,21 @@ class PmDynaform if ($this->record != null) { return $this->record; } - $a = new Criteria("workflow"); - $a->addSelectColumn(DynaformPeer::DYN_VERSION); - $a->addSelectColumn(DynaformPeer::DYN_LABEL); - $a->addSelectColumn(DynaformPeer::DYN_CONTENT); - $a->addSelectColumn(DynaformPeer::PRO_UID); - $a->addSelectColumn(DynaformPeer::DYN_UID); - $a->add(DynaformPeer::DYN_UID, $this->fields["CURRENT_DYNAFORM"], Criteria::EQUAL); - $ds = DynaformPeer::doSelectRS($a); - $ds->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $ds->next(); - $row = $ds->getRow(); - $this->record = isset($row) ? $row : null; - $this->langs = ($this->record["DYN_LABEL"] !== "" && $this->record["DYN_LABEL"] !== null) ? G::json_decode($this->record["DYN_LABEL"]) : null; + $dynaform = ModelDynaform::getByDynUid($this->fields["CURRENT_DYNAFORM"]); + if (empty($dynaform)) { + $this->langs = null; + return null; + } + $this->langs = empty($dynaform->DYN_LABEL) ? null : G::json_decode($dynaform->DYN_LABEL); + $this->record = (array) $dynaform; return $this->record; } + /** + * Get all dynaforms except this dynaform, related to process. + * @return array + * @see PmDynaform->__construct() + */ public function getDynaforms() { if ($this->record === null) { @@ -110,21 +118,11 @@ class PmDynaform if ($this->records != null) { return $this->records; } - $a = new Criteria("workflow"); - $a->addSelectColumn(DynaformPeer::DYN_UPDATE_DATE); - $a->addSelectColumn(DynaformPeer::DYN_VERSION); - $a->addSelectColumn(DynaformPeer::DYN_LABEL); - $a->addSelectColumn(DynaformPeer::DYN_CONTENT); - $a->addSelectColumn(DynaformPeer::PRO_UID); - $a->addSelectColumn(DynaformPeer::DYN_UID); - $a->add(DynaformPeer::PRO_UID, $this->record["PRO_UID"], Criteria::EQUAL); - $a->add(DynaformPeer::DYN_UID, $this->record["DYN_UID"], Criteria::NOT_EQUAL); - $ds = DynaformPeer::doSelectRS($a); - $ds->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $this->records = array(); - while ($ds->next()) { - array_push($this->records, $ds->getRow()); - } + $result = ModelDynaform::getByProUidExceptDynUid($this->record["PRO_UID"], $this->record["DYN_UID"]); + $result->transform(function($item) { + return (array) $item; + }); + $this->records = $result->toArray(); return $this->records; } @@ -1562,19 +1560,27 @@ class PmDynaform } } + /** + * Verify the use of the variable in all the forms of the process. + * + * @param string $processUid + * @param string $variable + * @return boolean | string + * + * @see ProcessMaker\BusinessModel\Variable->delete() + * @link https://wiki.processmaker.com/3.2/Variables#Managing_Variables + */ public function isUsed($processUid, $variable) { - $criteria = new Criteria("workflow"); - $criteria->addSelectColumn(DynaformPeer::DYN_UID); - $criteria->addSelectColumn(DynaformPeer::DYN_CONTENT); - $criteria->add(DynaformPeer::PRO_UID, $processUid, Criteria::EQUAL); - $rsCriteria = DynaformPeer::doSelectRS($criteria); - $rsCriteria->setFetchmode(ResultSet::FETCHMODE_ASSOC); - while ($rsCriteria->next()) { - $aRow = $rsCriteria->getRow(); - $json = G::json_decode($aRow['DYN_CONTENT']); + $result = ModelDynaform::getByProUid($processUid); + if (empty($result)) { + return false; + } + foreach ($result as $row) { + $dynaform = new PmDynaform(["CURRENT_DYNAFORM" => $row->DYN_UID]); + $json = G::json_decode($dynaform->record["DYN_CONTENT"]); if ($this->jsoni($json, $variable)) { - return $aRow['DYN_UID']; + return $row->DYN_UID; } } return false; diff --git a/workflow/engine/src/ProcessMaker/Model/Dynaform.php b/workflow/engine/src/ProcessMaker/Model/Dynaform.php new file mode 100644 index 000000000..4d270b2dc --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/Dynaform.php @@ -0,0 +1,64 @@ +belongsTo(Process::class, 'PRO_UID', 'PRO_UID'); + } + + /** + * Get dynaforms by PRO_UID. + * @param string $proUid + * @return object + */ + public static function getByProUid($proUid) + { + return DB::table('DYNAFORM') + ->select() + ->where('DYNAFORM.PRO_UID', '=', $proUid) + ->get(); + } + + /** + * Get dynaform by DYN_UID. + * @param string $dynUid + * @return object + */ + public static function getByDynUid($dynUid) + { + return DB::table('DYNAFORM') + ->select() + ->where('DYNAFORM.DYN_UID', '=', $dynUid) + ->first(); + } + + /** + * Get dynaforms by PRO_UID except the DYN_UID specified in the second parameter. + * @param string $proUid + * @param string $dynUid + * @return object + */ + public static function getByProUidExceptDynUid($proUid, $dynUid) + { + return DB::table('DYNAFORM') + ->select() + ->where('DYNAFORM.PRO_UID', '=', $proUid) + ->where('DYNAFORM.DYN_UID', '!=', $dynUid) + ->get(); + } +}