diff --git a/database/factories/BpmnDiagramFactory.php b/database/factories/BpmnDiagramFactory.php new file mode 100644 index 000000000..817fe6d3c --- /dev/null +++ b/database/factories/BpmnDiagramFactory.php @@ -0,0 +1,14 @@ +define(\ProcessMaker\Model\BpmnDiagram::class, function(Faker $faker) { + return [ + 'DIA_UID' => $faker->regexify("/[a-zA-Z]{32}/"), + 'PRJ_UID' => function() { + return factory(\ProcessMaker\Model\BpmnProject::class)->create()->PRJ_UID; + }, + 'DIA_NAME' => $faker->name, + 'DIA_IS_CLOSABLE' => 0, + ]; +}); diff --git a/database/factories/BpmnEventFactory.php b/database/factories/BpmnEventFactory.php new file mode 100644 index 000000000..5f411972d --- /dev/null +++ b/database/factories/BpmnEventFactory.php @@ -0,0 +1,32 @@ +define(\ProcessMaker\Model\BpmnEvent::class, function(Faker $faker) { + $bpmnProcess = factory(\ProcessMaker\Model\BpmnProcess::class)->create(); + return [ + 'EVN_UID' => $faker->regexify("/[a-zA-Z]{32}/"), + 'PRJ_UID' => $bpmnProcess->PRJ_UID, + 'PRO_UID' => $bpmnProcess->PRO_UID, + 'EVN_NAME' => $faker->name, + 'EVN_TYPE' => 'START', + 'EVN_MARKER' => 'EMPTY', + 'EVN_IS_INTERRUPTING' => 1, + 'EVN_ATTACHED_TO' => '', + 'EVN_CANCEL_ACTIVITY' => 0, + 'EVN_ACTIVITY_REF' => null, + 'EVN_WAIT_FOR_COMPLETION' => 0, + 'EVN_ERROR_NAME' => null, + 'EVN_ERROR_CODE' => null, + 'EVN_ESCALATION_NAME' => null, + 'EVN_ESCALATION_CODE' => null, + 'EVN_CONDITION' => null, + 'EVN_MESSAGE' => '', + 'EVN_OPERATION_NAME' => null, + 'EVN_OPERATION_IMPLEMENTATION_REF' => null, + 'EVN_TIME_DATE' => null, + 'EVN_TIME_CYCLE' => null, + 'EVN_TIME_DURATION' => null, + 'EVN_BEHAVIOR' => 'THROW', + ]; +}); diff --git a/database/factories/BpmnProcessFactory.php b/database/factories/BpmnProcessFactory.php new file mode 100644 index 000000000..f83d90a7b --- /dev/null +++ b/database/factories/BpmnProcessFactory.php @@ -0,0 +1,20 @@ +define(\ProcessMaker\Model\BpmnProcess::class, function(Faker $faker) { + return [ + 'PRO_UID' => $faker->regexify("/[a-zA-Z]{32}/"), + 'PRJ_UID' => function() { + return factory(\ProcessMaker\Model\BpmnProject::class)->create()->PRJ_UID; + }, + 'DIA_UID' => function() { + return factory(\ProcessMaker\Model\BpmnDiagram::class)->create()->DIA_UID; + }, + 'PRO_NAME' => $faker->title, + 'PRO_TYPE' => 'NONE', + 'PRO_IS_EXECUTABLE' => 0, + 'PRO_IS_CLOSED' => 0, + 'PRO_IS_SUBPROCESS' => 0, + ]; +}); diff --git a/database/factories/EmailEventFactory.php b/database/factories/EmailEventFactory.php new file mode 100644 index 000000000..f4839f65b --- /dev/null +++ b/database/factories/EmailEventFactory.php @@ -0,0 +1,21 @@ +define(\ProcessMaker\Model\EmailEvent::class, function(Faker $faker) { + $bpmnEvent = factory(\ProcessMaker\Model\BpmnEvent::class)->create(); + return [ + 'EMAIL_EVENT_UID' => $faker->regexify("/[a-zA-Z]{32}/"), + 'PRJ_UID' => $bpmnEvent->PRJ_UID, + 'EVN_UID' => $bpmnEvent->EVN_UID, + 'EMAIL_EVENT_FROM' => $faker->email, + 'EMAIL_EVENT_TO' => $faker->email, + 'EMAIL_EVENT_SUBJECT' => $faker->title, + 'PRF_UID' => function() { + return factory(\ProcessMaker\Model\ProcessFiles::class)->create()->PRF_UID; + }, + 'EMAIL_SERVER_UID' => function() { + return factory(\ProcessMaker\Model\EmailServerModel::class)->create()->MESS_UID; + }, + ]; +}); diff --git a/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/FilesManagerTest.php b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/FilesManagerTest.php new file mode 100644 index 000000000..650e795d2 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/BusinessModel/FilesManagerTest.php @@ -0,0 +1,208 @@ +faker = Factory::create(); + $this->directories = []; + } + + /** + * Tear down method. + */ + public function tearDown() + { + parent::tearDown(); + $this->directories = array_reverse($this->directories); + foreach ($this->directories as $value) { + rmdir($value); + } + } + + /** + * This test verifies if a file is missing. + * @test + * @covers \ProcessMaker\BusinessModel\FilesManager::deleteProcessFilesManager() + */ + public function it_should_deleted_public_files_when_not_exist() + { + $proUid = G::generateUniqueID(); + $prfUid = G::generateUniqueID(); + $filesManager = new FilesManager(); + + $this->expectException(Exception::class); + $filesManager->deleteProcessFilesManager($proUid, $prfUid); + } + + /** + * This represents the windows and linux separators. + */ + public function directorySeparator() + { + return [ + ["linux", "/"], + ["windows", "\\"] + ]; + } + + /** + * This test verifies the deletion of a template. + * @test + * @covers \ProcessMaker\BusinessModel\FilesManager::deleteProcessFilesManager() + * @dataProvider directorySeparator + */ + public function it_should_deleted_a_template_file($type, $separator) + { + $user = factory(UserModel::class)->create([ + 'USR_UID' => G::generateUniqueID() + ]); + + $process = factory(ProcessModel::class)->create([ + 'PRO_UID' => G::generateUniqueID() + ]); + + //create a template file + $directory = PATH_DATA_SITE; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $directory = PATH_DATA_PUBLIC; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $directory = PATH_DATA_PUBLIC . $process->PRO_UID; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $fileName = "template1.html"; + $path = $directory . "/" . $fileName; + file_put_contents($path, $this->faker->randomHtml()); + + $processFiles = factory(ProcessFilesModel::class)->create([ + 'PRF_UID' => G::generateUniqueID(), + 'PRO_UID' => $process->PRO_UID, + 'USR_UID' => $user->USR_UID, + 'PRF_PATH' => $separator . $fileName + ]); + + $filesManager = new FilesManager(); + $filesManager->deleteProcessFilesManager($process->PRO_UID, $processFiles->PRF_UID); + + //assert empty registry + $expectedEmptyObject = ProcessFilesModel::where('PRF_UID', '=', $processFiles->PRF_UID)->first(); + $this->assertTrue(empty($expectedEmptyObject)); + + //assert empty file + $this->assertTrue(!file_exists($path)); + } + + /** + * This test verifies the deletion of a public file. + * @test + * @covers \ProcessMaker\BusinessModel\FilesManager::deleteProcessFilesManager() + * @dataProvider directorySeparator + */ + public function it_should_deleted_a_public_file($type, $separator) + { + $user = factory(UserModel::class)->create([ + 'USR_UID' => G::generateUniqueID() + ]); + + $process = factory(ProcessModel::class)->create([ + 'PRO_UID' => G::generateUniqueID() + ]); + + //create a temporal file + $directory = PATH_DATA_SITE; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $directory = PATH_DATA_MAILTEMPLATES; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $directory = PATH_DATA_MAILTEMPLATES . $process->PRO_UID; + if (!is_dir($directory)) { + mkdir($directory); + $this->directories[] = $directory; + } + $fileName = "temporal.html"; + $path = $directory . "/" . $fileName; + file_put_contents($path, $this->faker->randomHtml()); + + $processFiles = factory(ProcessFilesModel::class)->create([ + 'PRF_UID' => G::generateUniqueID(), + 'PRO_UID' => $process->PRO_UID, + 'USR_UID' => $user->USR_UID, + 'PRF_PATH' => $separator . $fileName + ]); + + $filesManager = new FilesManager(); + $filesManager->deleteProcessFilesManager($process->PRO_UID, $processFiles->PRF_UID); + + //assert empty registry + $expectedEmptyObject = ProcessFilesModel::where('PRF_UID', '=', $processFiles->PRF_UID)->first(); + $this->assertTrue(empty($expectedEmptyObject)); + + //assert empty file + $this->assertTrue(!file_exists($path)); + } + + /** + * This test verifies the removal of a template that is being used by an + * intermediate email event. + * @test + * @covers \ProcessMaker\BusinessModel\FilesManager::deleteProcessFilesManager() + */ + public function it_should_deleted_public_files_with_event_relation() + { + $user = factory(UserModel::class)->create([ + 'USR_UID' => G::generateUniqueID() + ]); + + $process = factory(ProcessModel::class)->create([ + 'PRO_UID' => G::generateUniqueID() + ]); + + $processFiles = factory(ProcessFilesModel::class)->create([ + 'PRF_UID' => G::generateUniqueID(), + 'PRO_UID' => $process->PRO_UID, + 'USR_UID' => $user->USR_UID, + 'PRF_PATH' => '/' + ]); + + $emailEvent = factory(EmailEventModel::class)->create([ + 'PRF_UID' => $processFiles->PRF_UID + ]); + + $filesManager = new FilesManager(); + + $this->expectException(Exception::class); + $filesManager->deleteProcessFilesManager($process->PRO_UID, $processFiles->PRF_UID); + } +} diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php index 69ce4b4f6..64fdab430 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/FilesManager.php @@ -1,12 +1,14 @@ addSelectColumn(\ProcessFilesPeer::PRF_PATH); - $criteriaPf->add(\ProcessFilesPeer::PRF_UID, $prfUid, \Criteria::EQUAL); - $rsCriteria = \ProcessFilesPeer::doSelectRS($criteriaPf); - $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); - $rsCriteria->next(); - while ($aRow = $rsCriteria->getRow()) { - $path = $aRow['PRF_PATH']; - $rsCriteria->next(); + $criteriaProcessFiles = new Criteria("workflow"); + $criteriaProcessFiles->addSelectColumn(ProcessFilesPeer::PRF_PATH); + $criteriaProcessFiles->add(ProcessFilesPeer::PRF_UID, $prfUid, Criteria::EQUAL); + $resultSet1 = ProcessFilesPeer::doSelectRS($criteriaProcessFiles); + $resultSet1->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $resultSet1->next(); + while ($row = $resultSet1->getRow()) { + $path = $row['PRF_PATH']; + $resultSet1->next(); } if ($path == '') { - throw new \Exception(\G::LoadTranslation("ID_INVALID_VALUE_FOR", array('prf_uid'))); + throw new Exception(G::LoadTranslation("ID_INVALID_VALUE_FOR", array('prf_uid'))); } $relationshipEmailEvent = false; - $criteria = new \Criteria("workflow"); - $criteria->addSelectColumn(\EmailEventPeer::PRF_UID); - $criteria->add(\EmailEventPeer::PRF_UID, $prfUid, \Criteria::EQUAL); - $rsCriteria = \EmailEventPeer::doSelectRS($criteria); - $rsCriteria->setFetchmode(\ResultSet::FETCHMODE_ASSOC); - $rsCriteria->next(); - while ($aRow = $rsCriteria->getRow()) { + $criteria = new Criteria("workflow"); + $criteria->addSelectColumn(EmailEventPeer::PRF_UID); + $criteria->add(EmailEventPeer::PRF_UID, $prfUid, Criteria::EQUAL); + $resultSet2 = EmailEventPeer::doSelectRS($criteria); + $resultSet2->setFetchmode(ResultSet::FETCHMODE_ASSOC); + $resultSet2->next(); + while ($row = $resultSet2->getRow()) { $relationshipEmailEvent = true; - $rsCriteria->next(); + $resultSet2->next(); } - $explodePath = explode(DIRECTORY_SEPARATOR,$path); + + $path = str_replace("\\", "/", $path); + $fileName = basename($path); if ($relationshipEmailEvent && !$verifyingRelationship) { - throw new \Exception(\G::LoadTranslation(G::LoadTranslation('ID_CANNOT_REMOVE_TEMPLATE_EMAIL_EVENT', - [end($explodePath)]))); + throw new Exception(G::LoadTranslation(G::LoadTranslation('ID_CANNOT_REMOVE_TEMPLATE_EMAIL_EVENT', [$fileName]))); } - $sFile = end($explodePath); - $path = PATH_DATA_MAILTEMPLATES.$sProcessUID.DIRECTORY_SEPARATOR.$sFile; - + $path = PATH_DATA_MAILTEMPLATES . $proUid . "/" . $fileName; if (file_exists($path) && !is_dir($path)) { unlink($path); } else { - $path = PATH_DATA_PUBLIC.$sProcessUID.DIRECTORY_SEPARATOR.$sFile; - - if (file_exists($path) && !is_dir($path)) { - unlink($path); - } + $path = PATH_DATA_PUBLIC . $proUid . "/" . $fileName; + if (file_exists($path) && !is_dir($path)) { + unlink($path); + } } - $rs = \ProcessFilesPeer::doDelete($criteriaPf); + ProcessFilesPeer::doDelete($criteriaProcessFiles); } catch (Exception $e) { throw $e; } diff --git a/workflow/engine/src/ProcessMaker/Model/BpmnDiagram.php b/workflow/engine/src/ProcessMaker/Model/BpmnDiagram.php new file mode 100644 index 000000000..08ce8a4c8 --- /dev/null +++ b/workflow/engine/src/ProcessMaker/Model/BpmnDiagram.php @@ -0,0 +1,13 @@ +