From dccb63c84b2fbe014a2bc0cf17b67b1baf56c5dc Mon Sep 17 00:00:00 2001 From: Andrea Adamczyk Date: Thu, 25 Jul 2019 14:50:06 -0400 Subject: [PATCH] PMC-633 --- tests/bootstrap.php | 149 ++++++++--------- .../src/ProcessMaker/Model/ProcessTest.php | 155 ++++++++++++++++++ .../src/ProcessMaker/BusinessModel/Light.php | 111 ++----------- .../engine/src/ProcessMaker/Model/Process.php | 24 +++ 4 files changed, 271 insertions(+), 168 deletions(-) create mode 100644 tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index ecb0a9f07..1314d19e7 100755 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -3,14 +3,13 @@ /** * Test harness bootstrap that sets up initial defines and builds up the initial database schema */ -// Bring in our standard bootstrap + include_once(__DIR__ . '/../bootstrap/autoload.php'); use Illuminate\Contracts\Console\Kernel; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Schema; -// Setup our required defines /** * @todo Migrate to configuration parameters */ @@ -35,20 +34,14 @@ define('PMTABLE_KEY', 'pmtable'); define('PATH_WORKFLOW_MYSQL_DATA', PATH_TRUNK . '/workflow/engine/data/mysql/'); define('PATH_RBAC_MYSQL_DATA', PATH_TRUNK . '/rbac/engine/data/mysql/'); define('PATH_LANGUAGECONT', PATH_DATA . '/META-INF/'); -define('PM_NEW_PROCESS_SAVE', 1006); -define('PATH_DATA_SITE', PATH_DATA . 'sites/' . SYS_SYS . '/'); -define("PATH_DATA_MAILTEMPLATES", PATH_DATA_SITE . "mailTemplates/"); -define('PATH_DATA_PUBLIC', PATH_DATA_SITE . 'public/'); define('DB_ADAPTER', 'mysql'); define('PATH_RBAC_HOME', PATH_TRUNK . '/rbac/'); define('PATH_RBAC', PATH_RBAC_HOME . 'engine/classes/'); define("PATH_CUSTOM_SKINS", PATH_DATA . "skins/"); define("PATH_TPL", PATH_CORE . "templates/"); -//timezone -$_SESSION['__SYSTEM_UTC_TIME_ZONE__'] = (int) (env('MAIN_SYSTEM_UTC_TIME_ZONE', 'workflow')) == 1; - -//Set Time Zone +// Set Time Zone +$_SESSION['__SYSTEM_UTC_TIME_ZONE__'] = (int)(env('MAIN_SYSTEM_UTC_TIME_ZONE', 'workflow')) == 1; ini_set('date.timezone', $_SESSION['__SYSTEM_UTC_TIME_ZONE__'] ? 'UTC' : env('MAIN_TIME_ZONE', 'America/New_York')); define('TIME_ZONE', ini_get('date.timezone')); @@ -56,25 +49,28 @@ define('TIME_ZONE', ini_get('date.timezone')); $app = require __DIR__ . '/../bootstrap/app.php'; $app->make(Kernel::class)->bootstrap(); -//Overwrite with the Processmaker env.ini configuration used in production environments +// Overwrite with the ProcessMaker env.ini configuration used in production environments //@todo: move env.ini configuration to .env ini_set('date.timezone', TIME_ZONE); //Set Time Zone date_default_timezone_set(TIME_ZONE); +// Configuration values config(['app.timezone' => TIME_ZONE]); - -//configuration values config([ "system.workspace" => SYS_SYS ]); +// Defining constants related to the workspace define("PATH_DATA_SITE", PATH_DATA . "sites/" . config("system.workspace") . "/"); define("PATH_DYNAFORM", PATH_DATA_SITE . "xmlForms/"); define("PATH_DATA_MAILTEMPLATES", PATH_DATA_SITE . "mailTemplates/"); define("PATH_DATA_PUBLIC", PATH_DATA_SITE . "public/"); - G::defineConstants(); -// Setup our testexternal database -config(['database.connections.testexternal' => [ +/** + * Database configurations + */ +// Setup connection to database SQLServer +config([ + 'database.connections.testexternal' => [ 'driver' => 'mysql', 'host' => env('DB_HOST', '127.0.0.1'), 'database' => 'testexternal', @@ -86,31 +82,25 @@ config(['database.connections.testexternal' => [ 'prefix' => '', 'strict' => true, 'engine' => null -]]); - -// Now, drop all test tables and repopulate with schema -Schema::connection('testexternal')->dropIfExists('test'); - -Schema::connection('testexternal')->create('test', function($table) { - $table->increments('id'); - $table->string('value'); -}); -DB::connection('testexternal')->table('test')->insert([ - 'value' => 'testvalue' + ] ]); -// Only do if we are supporting MSSql tests +/** + * Configuration for MSSQL + */ if (env('RUN_MSSQL_TESTS')) { - config(['database.connections.mssql' => [ + config([ + 'database.connections.mssql' => [ 'driver' => 'sqlsrv', 'host' => env('MSSQL_HOST', '127.0.0.1'), 'database' => env('MSSQL_DATABASE', 'testexternal'), 'username' => env('MSSQL_USERNAME', 'root'), 'password' => env('MSSQL_PASSWORD', 'password'), - ]]); + ] + ]); Schema::connection('mssql')->dropIfExists('test'); - Schema::connection('mssql')->create('test', function($table) { + Schema::connection('mssql')->create('test', function ($table) { $table->increments('id'); $table->string('value'); }); @@ -119,50 +109,63 @@ if (env('RUN_MSSQL_TESTS')) { ]); } +/** + * This is for standard ProcessMaker tables + */ +if (!env('POPULATE_DATABASE')) { + // Create a table for define the connection + Schema::connection('testexternal')->dropIfExists('test'); + Schema::connection('testexternal')->create('test', function ($table) { + $table->increments('id'); + $table->string('value'); + }); + DB::connection('testexternal')->table('test')->insert([ + 'value' => 'testvalue' + ]); -// THIS IS FOR STANDARD PROCESSMAKER TABLES -// Now, drop all test tables and repopulate with schema -DB::unprepared('SET FOREIGN_KEY_CHECKS = 0'); -$colname = 'Tables_in_' . env('DB_DATABASE'); -$tables = DB::select('SHOW TABLES'); -$drop = []; -foreach ($tables as $table) { - $drop[] = $table->$colname; + // Now, drop all test tables and repopulate with schema + DB::unprepared('SET FOREIGN_KEY_CHECKS = 0'); + $colname = 'Tables_in_' . env('DB_DATABASE', 'test'); + $tables = DB::select('SHOW TABLES'); + $drop = []; + foreach ($tables as $table) { + $drop[] = $table->$colname; + } + if (count($drop)) { + $drop = implode(',', $drop); + DB::statement("DROP TABLE $drop"); + DB::unprepared('SET FOREIGN_KEY_CHECKS = 1'); + } + + // Repopulate with schema and standard inserts + DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/schema.sql')); + DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/schema.sql')); + DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/insert.sql')); + DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/insert.sql')); + + // Set our APP_SEQUENCE val + DB::table('APP_SEQUENCE')->insert([ + 'ID' => 1 + ]); + + // Setup our initial oauth client for our web designer + DB::table('OAUTH_CLIENTS')->insert([ + 'CLIENT_ID' => 'x-pm-local-client', + 'CLIENT_SECRET' => '179ad45c6ce2cb97cf1029e212046e81', + 'CLIENT_NAME' => 'PM Web Designer', + 'CLIENT_DESCRIPTION' => 'ProcessMaker Web Designer App', + 'CLIENT_WEBSITE' => 'www.processmaker.com', + 'REDIRECT_URI' => config('app.url') . '/sys' . config('system.workspace') . '/en/neoclassic/oauth2/grant', + 'USR_UID' => '00000000000000000000000000000001' + ]); + DB::table('OAUTH_ACCESS_TOKENS')->insert([ + 'ACCESS_TOKEN' => '39704d17049f5aef45e884e7b769989269502f83', + 'CLIENT_ID' => 'x-pm-local-client', + 'USER_ID' => '00000000000000000000000000000001', + 'EXPIRES' => '2017-06-15 17:55:19', + 'SCOPE' => 'view_processes edit_processes *' + ]); } -if (count($drop)) { - $drop = implode(',', $drop); - DB::statement("DROP TABLE $drop"); - DB::unprepared('SET FOREIGN_KEY_CHECKS = 1'); -} - -// Repopulate with schema and standard inserts -DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/schema.sql')); -DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/schema.sql')); -DB::unprepared(file_get_contents(PATH_CORE . 'data/mysql/insert.sql')); -DB::unprepared(file_get_contents(PATH_RBAC_CORE . 'data/mysql/insert.sql')); - -// Set our APP_SEQUENCE val -DB::table('APP_SEQUENCE')->insert([ - 'ID' => 1 -]); - -// Setup our initial oauth client for our web designer -DB::table('OAUTH_CLIENTS')->insert([ - 'CLIENT_ID' => 'x-pm-local-client', - 'CLIENT_SECRET' => '179ad45c6ce2cb97cf1029e212046e81', - 'CLIENT_NAME' => 'PM Web Designer', - 'CLIENT_DESCRIPTION' => 'ProcessMaker Web Designer App', - 'CLIENT_WEBSITE' => 'www.processmaker.com', - 'REDIRECT_URI' => config('app.url') . '/sys' . config('system.workspace') . '/en/neoclassic/oauth2/grant', - 'USR_UID' => '00000000000000000000000000000001' -]); -DB::table('OAUTH_ACCESS_TOKENS')->insert([ - 'ACCESS_TOKEN' => '39704d17049f5aef45e884e7b769989269502f83', - 'CLIENT_ID' => 'x-pm-local-client', - 'USER_ID' => '00000000000000000000000000000001', - 'EXPIRES' => '2017-06-15 17:55:19', - 'SCOPE' => 'view_processes edit_processes *' -]); // We need to manually initialize Propel with our test database Propel::initConfiguration([ diff --git a/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php b/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php new file mode 100644 index 000000000..1d6dfe9e8 --- /dev/null +++ b/tests/unit/workflow/engine/src/ProcessMaker/Model/ProcessTest.php @@ -0,0 +1,155 @@ +create(); + $user2 = factory(User::class)->create(); + //Create process + $process1 = factory(Process::class)->create( + ['PRO_CREATE_USER' => $user1['USR_UID']] + ); + $process2 = factory(Process::class)->create( + ['PRO_CREATE_USER' => $user2['USR_UID']] + ); + + //Create a Process object + $process = new Process(); + //Call the getProcessList() method + $res = $process->getProcessList('', $user2['USR_UID']); + + //Assert the result is not empty + $this->assertNotEmpty($res); + //Assert there's one result + $this->assertCount(1, $res); + //Assert that the process returned is the one looked for + $this->assertEquals($process2['PRO_UID'], $res[0]['PRO_UID']); + //Assert the process that was not searched is not in the result + $this->assertNotEquals($process1['PRO_UID'], $res[0]['PRO_UID']); + } + + /** + * Tests that it returns the processes in an specific category + * @covers ::getProcessList + * @test + */ + public function it_should_return_the_processes_in_an_specific_category() + { + $catUid1 = G::generateUniqueID(); + $catUid2 = G::generateUniqueID(); + + //Create user + $user = factory(User::class)->create(); + //Create process + $process1 = factory(Process::class)->create( + [ + 'PRO_CREATE_USER' => $user['USR_UID'], + 'PRO_CATEGORY' => $catUid1 + ] + ); + $process2 = factory(Process::class)->create( + [ + 'PRO_CREATE_USER' => $user['USR_UID'], + 'PRO_CATEGORY' => $catUid2 + ] + ); + + //Create a Process object + $process = new Process(); + //Call the getProcessList() method + $res = $process->getProcessList($process1['PRO_CATEGORY'], $user['USR_UID']); + + //Assert the result is not empty + $this->assertNotEmpty($res); + //Assert there's one result + $this->assertCount(1, $res); + //Assert that the process returned belong to the category searched + $this->assertEquals($process1['PRO_UID'], $res[0]['PRO_UID']); + //Assert the process which their category was not searched is not in the result + $this->assertNotEquals($process2['PRO_UID'], $res[0]['PRO_UID']); + } + + /** + * Tests that it returns an empty array if no processes where found + * @covers ::getProcessList + * @test + */ + public function it_should_return_empty_if_no_processes_where_found() + { + //Create user + $user = factory(User::class)->create(); + //Create a Process object + $process = new Process(); + //Call the getProcessList() method + $res = $process->getProcessList('', $user['USR_UID']); + + //Assert the result is not empty + $this->assertEmpty($res); + } + + /** + * Test it returns all the processes in status active + * @covers ::getProcessList + * @test + */ + public function it_should_return_all_the_processes_in_status_active() + { + //Create user + $user = factory(User::class)->create(); + //Create process + $process1 = factory(Process::class)->create( + [ + 'PRO_CREATE_USER' => $user['USR_UID'], + 'PRO_STATUS' => 'ACTIVE' + ] + ); + $process2 = factory(Process::class)->create( + [ + 'PRO_CREATE_USER' => $user['USR_UID'], + 'PRO_STATUS' => 'INACTIVE' + ] + ); + $process3 = factory(Process::class)->create( + [ + 'PRO_CREATE_USER' => $user['USR_UID'], + 'PRO_STATUS' => 'DISABLED' + ] + ); + + //Create a Process object + $process = new Process(); + //Call the getProcessList() method + $res = $process->getProcessList('', $user['USR_UID']); + + //Assert the result is not empty + $this->assertNotEmpty($res); + //Assert there's one result + $this->assertCount(1, $res); + //Assert that the process returned is the one that has ACTIVE status + $this->assertEquals($process1['PRO_UID'], $res[0]['PRO_UID']); + //Assert the processes that have not ACTIVE status are not in the result + $this->assertNotEquals($process2['PRO_UID'], $res[0]['PRO_UID']); + $this->assertNotEquals($process3['PRO_UID'], $res[0]['PRO_UID']); + } +} \ No newline at end of file diff --git a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php index 4cbdb2c48..f6a135071 100644 --- a/workflow/engine/src/ProcessMaker/BusinessModel/Light.php +++ b/workflow/engine/src/ProcessMaker/BusinessModel/Light.php @@ -30,6 +30,7 @@ use ProcessMaker\ChangeLog\ChangeLog; /*----------------------------------********---------------------------------*/ use ProcessMaker\Core\RoutingScreen; use ProcessMaker\Core\System; +use ProcessMaker\Model\Process as ProcessEloquent; use ProcessMaker\Services\Api\Project\Activity\Step as ActivityStep; use ProcessMaker\Util\DateTime; use ProcessMaker\Validation\ExceptionRestApi; @@ -1237,109 +1238,29 @@ class Light } /** - * @param $action - * @param $categoryUid - * @param $userUid + * Return the list of processes + * + * @param string $action + * @param string $categoryUid + * @param string $userUid + * + * @see ProcessMaker\Services\Api\Light::getProcessList(); * * @return array - * @throws PropelException */ public function getProcessList($action, $categoryUid, $userUid) { - //$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : null; - //$categoryUid = isset( $_REQUEST['CATEGORY_UID'] ) ? $_REQUEST['CATEGORY_UID'] : null; - //$userUid = (isset( $_SESSION['USER_LOGGED'] ) && $_SESSION['USER_LOGGED'] != '') ? $_SESSION['USER_LOGGED'] : null; + $processes = []; + $processes[] = ['', G::LoadTranslation('ID_ALL_PROCESS')]; - // global $oAppCache; - $oAppCache = new AppCacheView(); - $processes = array(); - $processes[] = array('', G::LoadTranslation('ID_ALL_PROCESS')); + $process = new ProcessEloquent(); + $processList = $process->getProcessList($categoryUid, $userUid); - //get the list based in the action provided - switch ($action) { - case 'draft': - $cProcess = $oAppCache->getDraftListCriteria($userUid); //fast enough - break; - case 'sent': - $cProcess = $oAppCache->getSentListProcessCriteria($userUid); // fast enough - break; - case 'simple_search': - case 'search': - //in search action, the query to obtain all process is too slow, so we need to query directly to - //process and content tables, and for that reason we need the current language in AppCacheView. + $values = (array_map(function ($x) { + return array_values([$x['PRO_UID'], $x['PRO_TITLE']]); + }, $processList)); - $oConf = new Configurations(); - $oConf->loadConfig($x, 'APP_CACHE_VIEW_ENGINE', '', '', '', ''); - $appCacheViewEngine = $oConf->aConfig; - $lang = isset($appCacheViewEngine['LANG']) ? $appCacheViewEngine['LANG'] : 'en'; - - $cProcess = new Criteria('workflow'); - $cProcess->clearSelectColumns(); - $cProcess->addSelectColumn(ProcessPeer::PRO_UID); - $cProcess->addSelectColumn(ProcessPeer::PRO_TITLE); - if ($categoryUid) { - $cProcess->add(ProcessPeer::PRO_CATEGORY, $categoryUid); - } - $cProcess->add(ProcessPeer::PRO_STATUS, 'ACTIVE'); - $cProcess->addAscendingOrderByColumn(ProcessPeer::PRO_TITLE); - - $oDataset = ProcessPeer::doSelectRS($cProcess); - $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $oDataset->next(); - - while ($aRow = $oDataset->getRow()) { - $processes[] = array($aRow['PRO_UID'], $aRow['PRO_TITLE']); - $oDataset->next(); - } - - return print G::json_encode($processes); - break; - case 'unassigned': - $cProcess = $oAppCache->getUnassignedListCriteria($userUid); - break; - case 'paused': - $cProcess = $oAppCache->getPausedListCriteria($userUid); - break; - case 'to_revise': - $cProcess = $oAppCache->getToReviseListCriteria($userUid); - break; - case 'to_reassign': - $cProcess = $oAppCache->getToReassignListCriteria($userUid); - break; - case 'gral': - $cProcess = $oAppCache->getGeneralListCriteria(); - break; - case 'todo': - default: - $cProcess = $oAppCache->getToDoListCriteria($userUid); //fast enough - break; - } - //get the processes for this user in this action - $cProcess->clearSelectColumns(); - $cProcess->addSelectColumn(AppCacheViewPeer::PRO_UID); - $cProcess->addSelectColumn(AppCacheViewPeer::APP_PRO_TITLE); - $cProcess->setDistinct(AppCacheViewPeer::PRO_UID); - if ($categoryUid) { - require_once 'classes/model/Process.php'; - $cProcess->addAlias('CP', 'PROCESS'); - $cProcess->add('CP.PRO_CATEGORY', $categoryUid, Criteria::EQUAL); - $cProcess->addJoin(AppCacheViewPeer::PRO_UID, 'CP.PRO_UID', Criteria::LEFT_JOIN); - $cProcess->addAsColumn('CATEGORY_UID', 'CP.PRO_CATEGORY'); - } - - $cProcess->addAscendingOrderByColumn(AppCacheViewPeer::APP_PRO_TITLE); - - $oDataset = AppCacheViewPeer::doSelectRS($cProcess, Propel::getDbConnection('workflow_ro')); - $oDataset->setFetchmode(ResultSet::FETCHMODE_ASSOC); - $oDataset->next(); - - while ($aRow = $oDataset->getRow()) { - $processes[] = array( - $aRow['PRO_UID'], - $aRow['APP_PRO_TITLE'] - ); - $oDataset->next(); - } + $processes = array_merge($processes, $values); return $processes; } diff --git a/workflow/engine/src/ProcessMaker/Model/Process.php b/workflow/engine/src/ProcessMaker/Model/Process.php index b32b92eb1..ae50c3799 100644 --- a/workflow/engine/src/ProcessMaker/Model/Process.php +++ b/workflow/engine/src/ProcessMaker/Model/Process.php @@ -39,4 +39,28 @@ class Process extends Model { return $this->hasOne(ProcessCategory::class, 'PRO_CATEGORY', 'CATEGORY_UID'); } + + /** + * Obtains the process list for an specific user and/or for the specific category + * + * @param string $categoryUid + * @param string $userUid + * @return array + * + * @see ProcessMaker\BusinessModel\Light::getProcessList() + */ + public function getProcessList($categoryUid, $userUid) + { + $selectedColumns = ['PRO_UID', 'PRO_TITLE']; + $query = Process::query() + ->select($selectedColumns) + ->where('PRO_STATUS', 'ACTIVE') + ->where('PRO_CREATE_USER', $userUid); + + if (!empty($categoryUid)) { + $query->where('PRO_CATEGORY', $categoryUid); + } + + return ($query->get()->values()->toArray()); + } }