From 025bd2a59db986d9a1ebac4b830fb4d3b35e13d8 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Fri, 1 Nov 2024 12:43:12 -0400 Subject: [PATCH 01/18] FOUR-19950: The migration of cases_participated crashes in dev clone fix comment fix comment count cases_participated rename temp tables --- ..._09_152947_populate_cases_participated.php | 249 ++++++++++++------ 1 file changed, 167 insertions(+), 82 deletions(-) diff --git a/upgrades/2024_10_09_152947_populate_cases_participated.php b/upgrades/2024_10_09_152947_populate_cases_participated.php index 4363a834a8..f5853ec898 100644 --- a/upgrades/2024_10_09_152947_populate_cases_participated.php +++ b/upgrades/2024_10_09_152947_populate_cases_participated.php @@ -15,52 +15,27 @@ class PopulateCasesParticipated extends Upgrade */ public function up() { - try { - DB::table('cases_participated')->truncate(); - - $this->getProcessRequests() - ->chunk(1000, function ($rows) { - $casesParticipated = []; - - foreach ($rows as $row) { - $processes = CaseUtils::storeProcesses(collect(json_decode($row->processes))); - $requests = CaseUtils::storeRequests(collect(json_decode($row->requests))); - $requestTokens = CaseUtils::storeRequestTokens(collect(json_decode($row->request_tokens))); - $tasks = CaseUtils::storeTasks(collect(json_decode($row->tasks))); - $participants = CaseUtils::storeParticipants(collect(json_decode($row->participants))); - - $dataKeywords = [ - 'case_number' => $row->case_number, - 'case_title' => $row->case_title, - ]; - - array_push($casesParticipated, [ - 'user_id' => $row->user_id, - 'case_number' => $row->case_number, - 'case_title' => $row->case_title, - 'case_title_formatted' => $row->case_title_formatted, - 'case_status' => $row->case_status, - 'processes' => $processes, - 'requests' => $requests, - 'request_tokens' => $requestTokens, - 'tasks' => $tasks, - 'participants' => $participants, - 'initiated_at' => $row->initiated_at, - 'completed_at' => $row->completed_at, - 'created_at' => $row->created_at, - 'updated_at' => $row->updated_at, - 'keywords' => CaseUtils::getKeywords($dataKeywords), - ]); - } - - DB::table('cases_participated')->insert($casesParticipated); - - Log::info('Inserted ' . count($casesParticipated) . ' cases participated records'); - }); - } catch (Exception $e) { - Log::error($e->getMessage()); - echo $e->getMessage(); - } + $this->validateDataConsistency(); + + DB::table('cases_participated')->truncate(); + echo PHP_EOL . ' Populating case_participated from process_requests' . PHP_EOL; + + $startTime = microtime(true); // Start the timer + + $this->createTemporaryTableWithNonSystemRequests(); + $this->logTimeElapsed('Created temporary table with non-system requests', $startTime); + + $this->createTemporaryParticipantsTable(); + $this->logTimeElapsed('Created temporary table with participants', $startTime); + + $this->insertIntoCasesParticipated(); + $this->logTimeElapsed('Inserted data into cases_participated', $startTime); + + $count = DB::table('cases_participated')->count(); + + echo PHP_EOL . "Cases Participated have been populated successfully. Total cases: {$count}" . PHP_EOL; + + echo PHP_EOL; } /** @@ -73,45 +48,155 @@ public function down() DB::table('cases_participated')->truncate(); } - protected function getProcessRequests(): Builder + /** + * Log the time elapsed since the start of the process. + * + * @param string $message Message to log + * @param float $startTime Time when the processing started (in microseconds) + * @return void + */ + private function logTimeElapsed(string $message, float $startTime): void + { + $currentTime = microtime(true); + $timeElapsed = $currentTime - $startTime; + + // Format the elapsed time to 4 decimal places for higher precision + echo " {$message} - Time elapsed: " . number_format($timeElapsed, 4) . ' seconds' . PHP_EOL; + } + + /** + * Creates a temporary table with request tokens associated with + * the process requests. + * + * @return void + * + * @throws Exception If there is an error creating the temporary table + */ + private function createTemporaryTableWithNonSystemRequests() { - return DB::table('process_requests as pr') + // Creating the query + $query = DB::table('process_requests') + ->select([ + 'process_requests.id', + 'process_requests.case_number', + 'process_requests.user_id', + 'process_requests.case_title', + 'process_requests.case_title_formatted', + 'process_requests.initiated_at', + 'process_requests.created_at', + 'process_requests.completed_at', + 'process_requests.updated_at', + 'process_requests.name', + 'process_requests.parent_request_id', + 'processes.id as process_id', + 'processes.name as process_name', + DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status) as status"), + DB::raw("JSON_ARRAYAGG( + JSON_OBJECT( + 'id', processes.id, + 'name', processes.name + ) + ) as processes"), + DB::raw("JSON_ARRAYAGG( + JSON_OBJECT( + 'id', process_requests.id, + 'name', process_requests.name, + 'parent_request_id', process_requests.parent_request_id + ) + ) as requests"), + ]) + ->join('processes', 'process_requests.process_id', '=', 'processes.id') + ->join('process_categories', 'processes.process_category_id', '=', 'process_categories.id') + ->whereNull('process_requests.parent_request_id') + ->where('process_categories.is_system', '=', false) + ->groupBy([ + 'process_requests.id', + 'process_requests.case_number', + 'process_requests.user_id', + 'process_requests.case_title', + 'process_requests.case_title_formatted', + 'process_requests.initiated_at', + 'process_requests.created_at', + 'process_requests.completed_at', + 'process_requests.updated_at', + DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status)"), + ]); + + // Execute the query and create a temporary table + DB::statement('CREATE TEMPORARY TABLE process_requests_temp2 AS ' . $query->toSql(), $query->getBindings()); + } + + /** + * Creates a temporary table from process_request_tokens, + * obtaining unique user_id by case_number + * + * @return void + * + * @throws Exception If there is an error creating the temporary table + */ + private function createTemporaryParticipantsTable() + { + // Build the query for `participants_temp2` + $query = DB::table('process_request_tokens as prt') ->select([ - 'u.id as user_id', + 'prt.user_id', 'pr.case_number', - 'pr.case_title', - 'pr.case_title_formatted', - DB::raw("IF(pr.status = 'ACTIVE', 'IN_PROGRESS', pr.status) as case_status"), - DB::raw('JSON_ARRAYAGG(JSON_OBJECT("id", pc.id, "name", pc.name)) as processes'), - DB::raw('JSON_ARRAYAGG(JSON_OBJECT("id", pr.id, "name", pc.name, "parent_request_id", pr.parent_request_id)) as requests'), - DB::raw('JSON_ARRAYAGG(prt.id) as request_tokens'), - DB::raw('JSON_ARRAYAGG(IF(prt.element_type != "callActivity", JSON_OBJECT("id", prt.id, "name", prt.element_name, "element_id", prt.element_id, "process_id", prt.process_id), NULL)) as tasks'), - 'par.participants', - 'pr.initiated_at', - 'pr.completed_at', - 'pr.created_at', - 'pr.updated_at', ]) - ->join('process_request_tokens as prt', 'pr.id', '=', 'prt.process_request_id') - ->join('users as u', 'prt.user_id', '=', 'u.id') - ->join('processes as pc', 'pr.process_id', '=', 'pc.id') - ->joinSub( - DB::table('users as u2') - ->selectRaw('JSON_ARRAYAGG(u2.id) as participants, pr2.case_number') - ->join('process_request_tokens as prt2', 'u2.id', '=', 'prt2.user_id') - ->join('process_requests as pr2', 'prt2.process_request_id', '=', 'pr2.id') - ->whereNotNull('pr2.case_number') - ->groupBy('pr2.case_number'), - 'par', - 'par.case_number', - '=', - 'pr.case_number' - ) - ->whereIn('pr.status', ['ACTIVE', 'COMPLETED']) - ->whereIn('prt.element_type', ['task', 'callActivity', 'scriptTask']) - ->whereNotNull('pr.case_number') - ->groupBy('u.id', 'pr.id') - ->orderBy('pr.id') - ->orderBy('u.id'); + ->join('process_requests_temp2 as pr', 'prt.process_request_id', '=', 'pr.id') + ->whereNotNull('prt.user_id') + ->where('prt.element_type', '=', 'task') + ->groupBy(['pr.case_number', 'prt.user_id']); + + // Execute the query and create the temporary table + DB::statement('CREATE TEMPORARY TABLE participants_temp2 AS ' . $query->toSql(), $query->getBindings()); + } + + private function insertIntoCasesParticipated() + { + $insertQuery = DB::table('cases_started as prt1') + ->join('participants_temp2 as part', 'prt1.case_number', '=', 'part.case_number') + ->select([ + 'prt1.case_number', + 'prt1.case_status', + 'prt1.case_title', + 'prt1.case_title_formatted', + 'prt1.completed_at', + 'prt1.created_at', + 'prt1.initiated_at', + 'prt1.keywords', + 'prt1.participants', + 'prt1.processes', + 'prt1.request_tokens', + 'prt1.requests', + 'prt1.tasks', + 'prt1.updated_at', + 'part.user_id', + ]); + + // Perform the insert and return the number of affected rows + return DB::table('cases_participated')->insertUsing([ + 'case_number', 'case_status', 'case_title', 'case_title_formatted', + 'completed_at', 'created_at', 'initiated_at', 'keywords', + 'participants', 'processes', 'request_tokens', 'requests', + 'tasks', 'updated_at', 'user_id', + ], $insertQuery); + } + + /** + * Check if exist inconsitency in "process_request" table + */ + private function validateDataConsistency() + { + $results = DB::table('process_requests') + ->select('case_number', DB::raw('count(*) as total')) + ->whereNull('parent_request_id') + ->whereNotNull('case_number') + ->groupBy('case_number') + ->having('total', '>', 1) + ->first(); + + if (!is_null($results)) { + throw new Exception('Inconsistency detected, multiple records with null parent for the same request.'); + } } } From c6364a69841a7fa92a9b17af5a236c2afe389517 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Mon, 4 Nov 2024 09:45:09 -0400 Subject: [PATCH 02/18] Test upgrade cases_started --- .../Upgrade/PopulateCaseStartedTest.php | 38 +++++++++++++++++++ ...024_10_09_032151_populate_case_started.php | 2 +- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/Feature/Upgrade/PopulateCaseStartedTest.php diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php new file mode 100644 index 0000000000..f6a9d9b4bc --- /dev/null +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -0,0 +1,38 @@ +count(5)->create(); + + // Call the up method + dump(DB::table('cases_started')->count()); + $populateCaseStarted->up(); + dump(DB::table('cases_started')->count()); + + // Assertions can be added here if needed + } +} diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index c6d29706e0..0dffeb4b27 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -30,7 +30,7 @@ public function up() // @todo add a validation to check the data consistency $this->validateDataConsistency(); - DB::table('cases_started')->truncate(); + DB::table('cases_started')->delete(); echo PHP_EOL . ' Populating case_started from process_requests' . PHP_EOL; $startTime = microtime(true); // Start the timer From a412cb72cdbb8a310cc76319af22ddc872fd2fb9 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Mon, 4 Nov 2024 10:42:51 -0400 Subject: [PATCH 03/18] add asserts to caseStartedTest --- .../Upgrade/PopulateCaseStartedTest.php | 58 ++++++++++++++++--- 1 file changed, 49 insertions(+), 9 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index f6a9d9b4bc..c180a2fab0 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -7,6 +7,7 @@ use PopulateCaseStarted; use ProcessMaker\Models\ProcessRequest; use Tests\TestCase; + // use Illuminate\Foundation\Testing\RefreshDatabase; class PopulateCaseStartedTest extends TestCase @@ -15,24 +16,63 @@ class PopulateCaseStartedTest extends TestCase protected function setUp(): void { - require base_path('upgrades/2024_10_09_032151_populate_case_started.php'); + require_once base_path('upgrades/2024_10_09_032151_populate_case_started.php'); parent::setUp(); - // Set up any necessary data or configurations here + } + + protected function tearDown(): void + { + // Drop temporary tables and reset any specific configurations + DB::statement('DROP TEMPORARY TABLE IF EXISTS process_requests_temp'); + DB::statement('DROP TEMPORARY TABLE IF EXISTS process_request_tokens_tmp'); + DB::table('cases_started')->delete(); + parent::tearDown(); } public function testUp() { - // Create an instance of the PopulateCaseStarted class + // Instantiate PopulateCaseStarted $populateCaseStarted = new PopulateCaseStarted(); - // Create some requests, tokens, sub processes - ProcessRequest::factory()->count(5)->create(); + // Confirm initial empty state of cases_started table + $initialCount = DB::table('cases_started')->count(); + $this->assertEquals(0, $initialCount, 'cases_started should be empty before migration'); + + // Create sample ProcessRequests with related data + $processRequests = ProcessRequest::factory()->count(5)->create(); - // Call the up method - dump(DB::table('cases_started')->count()); + // Run the migration $populateCaseStarted->up(); - dump(DB::table('cases_started')->count()); - // Assertions can be added here if needed + // Confirm record insertion into cases_started + $finalCount = DB::table('cases_started')->count(); + $this->assertEquals($processRequests->count(), $finalCount, 'cases_started count should match the number of ProcessRequests created'); + + foreach ($processRequests as $processRequest) { + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->case_number)->first(); + $this->assertNotNull($casesStartedRecord, 'Each ProcessRequest should have a corresponding record in cases_started'); + + // Validate field mapping and transformations + $this->assertSame($processRequest->user_id, $casesStartedRecord->user_id); + $this->assertSame($processRequest->case_number, $casesStartedRecord->case_number); + $this->assertSame($processRequest->case_title, $casesStartedRecord->case_title); + $this->assertSame($processRequest->case_title_formatted, $casesStartedRecord->case_title_formatted); + $this->assertSame($this->mapStatus($processRequest->status), $casesStartedRecord->case_status); + $this->assertEquals($processRequest->initiated_at, $casesStartedRecord->initiated_at); + $this->assertEquals($processRequest->completed_at, $casesStartedRecord->completed_at); + $this->assertEquals($processRequest->created_at, $casesStartedRecord->created_at); + $this->assertEquals($processRequest->updated_at, $casesStartedRecord->updated_at); + } + } + + /** + * Helper function to map ProcessRequest status to cases_started status + * + * @param string $status ProcessRequest status + * @return string cases_started status + */ + private function mapStatus($status) + { + return $status === 'ACTIVE' ? 'IN_PROGRESS' : $status; } } From 7c751334c754faf6d92cbe3c3fe6760560c1220b Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Mon, 4 Nov 2024 15:50:26 -0400 Subject: [PATCH 04/18] improve collection tests for populate cases started --- .../Upgrade/PopulateCaseStartedTest.php | 211 ++++++++++++++++++ 1 file changed, 211 insertions(+) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index c180a2fab0..8d97bd6e96 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -5,7 +5,10 @@ use Illuminate\Support\Facades\DB; use Mockery; use PopulateCaseStarted; +use ProcessMaker\Models\Process; use ProcessMaker\Models\ProcessRequest; +use ProcessMaker\Models\ProcessRequestToken; +use ProcessMaker\Models\User; use Tests\TestCase; // use Illuminate\Foundation\Testing\RefreshDatabase; @@ -65,6 +68,214 @@ public function testUp() } } + public function testTokensColumn() + { + // Instantiate PopulateCaseStarted + $populateCaseStarted = new PopulateCaseStarted(); + + // Confirm initial empty state of cases_started table + $initialCount = DB::table('cases_started')->count(); + $this->assertEquals(0, $initialCount, 'cases_started should be empty before migration'); + + // Create user + $user = User::factory()->create(); + $this->actingAs($user); + // Create sample ProcessRequests with related data + $processRequests = ProcessRequest::factory()->count(5)->create([ + 'user_id' => $user->id, + ]); + // Get the ID of the first process request to use as the shared process_request_id + $processRequest = $processRequests->first(); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest->id, + 'element_type' => 'startEvent', + ]); + $processRequestTokens = ProcessRequestToken::factory()->count(3)->create([ + 'process_request_id' => $processRequest->id, + 'element_type' => 'task', + ]); + $processRequestTokenIds = $processRequestTokens->pluck('id')->toArray(); + // Run the migration + $populateCaseStarted->up(); + + // Confirm record insertion into cases_started + $finalCount = DB::table('cases_started')->count(); + $this->assertEquals($processRequests->count(), $finalCount, 'cases_started count should match the number of ProcessRequests created'); + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->id)->first(); + $this->assertNotNull($casesStartedRecord, 'Each ProcessRequest should have a corresponding record in cases_started'); + + $tokensArray = json_decode($casesStartedRecord->request_tokens, true); + $this->assertEqualsCanonicalizing($tokensArray, $processRequestTokenIds); + } + + public function testParticipatedColumn() + { + // Instantiate PopulateCaseStarted + $populateCaseStarted = new PopulateCaseStarted(); + + // Confirm initial empty state of cases_started table + $initialCount = DB::table('cases_started')->count(); + $this->assertEquals(0, $initialCount, 'cases_started should be empty before migration'); + + // Create first user + $user1 = User::factory()->create(); + $this->actingAs($user1); + // Create second user + $user2 = User::factory()->create(); + $this->actingAs($user2); + + // Create sample ProcessRequests with related data + $processRequests = ProcessRequest::factory()->create([ + 'user_id' => $user1->id, + ]); + $processRequests = ProcessRequest::factory()->create([ + 'user_id' => $user2->id, + ]); + // Get the ID of the first process request to use as the shared process_request_id + $processRequest = $processRequests->first(); + + // Create ProcessRequestTokens for processRequest + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest->id, + 'element_type' => 'startEvent', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->count(2)->create([ + 'process_request_id' => $processRequest->id, + 'element_type' => 'task', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->count(2)->create([ + 'process_request_id' => $processRequest->id, + 'element_type' => 'task', + 'user_id' => $user2->id, + ]); + $processRequestTokens = DB::table('process_request_tokens')->where('process_request_id', $processRequest->id); + $participantIds = $processRequestTokens->pluck('user_id')->toArray(); + $uniqueParticipantIds = array_unique($participantIds); + // Run the migration + $populateCaseStarted->up(); + + // Confirm record insertion into cases_started + $finalCount = DB::table('cases_started')->count(); + $this->assertEquals($processRequests->count(), $finalCount, 'cases_started count should match the number of ProcessRequests created'); + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->id)->first(); + $this->assertNotNull($casesStartedRecord, 'Each ProcessRequest should have a corresponding record in cases_started'); + // Prepare the participants record + $tokensArray = json_decode($casesStartedRecord->participants, true); + // Assert both arrays contain the same items in any order + $this->assertEqualsCanonicalizing($tokensArray, $uniqueParticipantIds); + } + + public function testCasesStartedProcessColumn() + { + // Instantiate the migration class + $populateCaseStarted = new PopulateCaseStarted(); + + // Confirm the initial state of the `cases_started` table + $initialCount = DB::table('cases_started')->count(); + $this->assertEquals(0, $initialCount, 'cases_started table should be empty before migration'); + + // Create test users + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + // Create test processes + $process1 = Process::factory()->create(); + $process2 = Process::factory()->create(); + // Create sample ProcessRequests for both users + $processRequest1 = ProcessRequest::factory()->create([ + 'user_id' => $user1->id, + 'name' => $process1->name, + 'process_id' => $process1->id, + ]); + $processRequest2 = ProcessRequest::factory()->create([ + 'user_id' => $user2->id, + 'parent_request_id' => $processRequest1->id, + 'name' => $process2->name, + 'process_id' => $process1->id, + ]); + + // Create ProcessRequestTokens for processRequest1 + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'startEvent', + 'status' => 'TRIGGERED', + 'element_id' => 'node_1', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'callActivity', + 'status' => 'CLOSED', + 'element_id' => 'node_51', + 'user_id' => $user1->id, + 'subprocess_request_id' => $processRequest2->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + 'element_id' => 'node_12', + 'user_id' => $user1->id, + ]); + + // Create ProcessRequestTokens for processRequest2 + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'startEvent', + 'status' => 'TRIGGERED', + 'element_id' => 'node_1', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'task', + 'status' => 'CLOSED', + 'element_id' => 'node_2', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'task', + 'status' => 'CLOSED', + 'element_id' => 'node_12', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'end_event', + 'status' => 'CLOSED', + 'element_id' => 'node_25', + 'user_id' => null, + ]); + + // Run the migration + $populateCaseStarted->up(); + + // Validate that the ProcessRequest1 has a corresponding entry in `cases_started` + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest1->case_number)->first(); + $this->assertNotNull($casesStartedRecord, 'ProcessRequest should have a corresponding record in cases_started'); + + // Expected data structure for `cases_started.processes` column + $expectedData = [ + ['id' => $processRequest1->process_id, 'name' => $processRequest1->name], + ['id' => $processRequest2->process_id, 'name' => $processRequest2->name], + ]; + + // Decode the JSON data from `cases_started.processes` + $processesArray = json_decode($casesStartedRecord->processes); + + // Assert both arrays contain the same items in any order + $this->assertEqualsCanonicalizing($expectedData, $processesArray, 'The processes data in cases_started should match the expected data'); + } + /** * Helper function to map ProcessRequest status to cases_started status * From ad11d17236853793ffb8a4ff66ea27bbc75ef808 Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Mon, 4 Nov 2024 16:15:25 -0400 Subject: [PATCH 05/18] test: upgrade cases participated --- .../Upgrade/PopulateCasesParticipatedTest.php | 519 ++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 tests/Feature/Upgrade/PopulateCasesParticipatedTest.php diff --git a/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php b/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php new file mode 100644 index 0000000000..977922677c --- /dev/null +++ b/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php @@ -0,0 +1,519 @@ +user = User::factory()->create(); + $this->user2 = User::factory()->create(); + $this->user3 = User::factory()->create(); + + $this->process = Process::factory()->create(); + $this->subProcess1 = Process::factory()->create(); + $this->subProcess2 = Process::factory()->create(); + + $this->request = ProcessRequest::factory()->create([ + 'user_id' => $this->user->id, + 'status' => 'ACTIVE', + 'process_id' => $this->process->id, + ]); + $this->childRequest1 = ProcessRequest::factory()->create([ + 'user_id' => $this->user->id, + 'status' => 'ACTIVE', + 'parent_request_id' => $this->request->id, + 'process_id' => $this->subProcess1->id, + ]); + $this->childRequest2 = ProcessRequest::factory()->create([ + 'user_id' => $this->user->id, + 'status' => 'ACTIVE', + 'parent_request_id' => $this->request->id, + 'process_id' => $this->subProcess2->id, + ]); + } + + private function upgrade() + { + $this->artisan('migrate', [ + '--path' => 'upgrades/2024_10_09_152947_populate_cases_participated.php', + ])->run(); + } + + public function test_one_participant() + { + $tokens = ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 1); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'case_title' => $this->request->case_title, + 'case_title_formatted' => $this->request->case_title_formatted, + 'case_status' => 'IN_PROGRESS', + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'requests->[0]->id' => $this->request->id, + 'requests->[0]->name' => $this->request->name, + 'requests->[0]->parent_request_id' => $this->request->parent_request_id, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[4]' => $tokens[4]->id, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[0]->element_id' => $tokens[0]->element_id, + 'tasks->[0]->name' => $tokens[0]->element_name, + 'tasks->[0]->process_id' => $tokens[0]->process_id, + 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[4]->id' => $tokens[4]->id, + 'tasks->[4]->element_id' => $tokens[4]->element_id, + 'tasks->[4]->name' => $tokens[4]->element_name, + 'tasks->[4]->process_id' => $tokens[4]->process_id, + 'tasks->[4]->status' => $tokens[4]->status, + ]); + } + + public function test_multiple_participants() + { + $tokens = ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $tokens2 = ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $tokens3 = ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'case_title' => $this->request->case_title, + 'case_title_formatted' => $this->request->case_title_formatted, + 'case_status' => 'IN_PROGRESS', + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'requests->[0]->id' => $this->request->id, + 'requests->[0]->name' => $this->request->name, + 'requests->[0]->parent_request_id' => $this->request->parent_request_id, + 'request_tokens' => 1, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[9]' => $tokens2[4]->id, + 'request_tokens->[14]' => $tokens3[4]->id, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[0]->element_id' => $tokens[0]->element_id, + 'tasks->[0]->name' => $tokens[0]->element_name, + 'tasks->[0]->process_id' => $tokens[0]->process_id, + 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[9]->id' => $tokens2[4]->id, + 'tasks->[9]->element_id' => $tokens2[4]->element_id, + 'tasks->[9]->name' => $tokens2[4]->element_name, + 'tasks->[9]->process_id' => $tokens2[4]->process_id, + 'tasks->[9]->status' => $tokens2[4]->status, + 'tasks->[14]->id' => $tokens3[4]->id, + 'tasks->[14]->element_id' => $tokens3[4]->element_id, + 'tasks->[14]->name' => $tokens3[4]->element_name, + 'tasks->[14]->process_id' => $tokens3[4]->process_id, + 'tasks->[14]->status' => $tokens3[4]->status, + ]); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user2->id, + 'case_number' => $this->request->case_number, + 'case_title' => $this->request->case_title, + 'case_title_formatted' => $this->request->case_title_formatted, + 'case_status' => 'IN_PROGRESS', + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'requests->[0]->id' => $this->request->id, + 'requests->[0]->name' => $this->request->name, + 'requests->[0]->parent_request_id' => $this->request->parent_request_id, + 'request_tokens' => 1, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[9]' => $tokens2[4]->id, + 'request_tokens->[14]' => $tokens3[4]->id, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[0]->element_id' => $tokens[0]->element_id, + 'tasks->[0]->name' => $tokens[0]->element_name, + 'tasks->[0]->process_id' => $tokens[0]->process_id, + 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[9]->id' => $tokens2[4]->id, + 'tasks->[9]->element_id' => $tokens2[4]->element_id, + 'tasks->[9]->name' => $tokens2[4]->element_name, + 'tasks->[9]->process_id' => $tokens2[4]->process_id, + 'tasks->[9]->status' => $tokens2[4]->status, + 'tasks->[14]->id' => $tokens3[4]->id, + 'tasks->[14]->element_id' => $tokens3[4]->element_id, + 'tasks->[14]->name' => $tokens3[4]->element_name, + 'tasks->[14]->process_id' => $tokens3[4]->process_id, + 'tasks->[14]->status' => $tokens3[4]->status, + ]); + } + + public function test_participants() + { + ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + ProcessRequestToken::factory()->count(5)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'participants->[0]' => $this->user->id, + 'participants->[1]' => $this->user2->id, + 'participants->[2]' => $this->user3->id, + ]); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user2->id, + 'case_number' => $this->request->case_number, + 'participants->[0]' => $this->user->id, + 'participants->[1]' => $this->user2->id, + 'participants->[2]' => $this->user3->id, + ]); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user3->id, + 'case_number' => $this->request->case_number, + 'participants->[0]' => $this->user->id, + 'participants->[1]' => $this->user2->id, + 'participants->[2]' => $this->user3->id, + ]); + } + + public function test_request_tokens() + { + $tokens = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $tokens2 = ProcessRequestToken::factory()->count(3)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $tokens3 = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[1]' => $tokens[1]->id, + 'request_tokens->[2]' => $tokens2[0]->id, + 'request_tokens->[3]' => $tokens2[1]->id, + 'request_tokens->[4]' => $tokens2[2]->id, + 'request_tokens->[5]' => $tokens3[0]->id, + 'request_tokens->[6]' => $tokens3[1]->id, + ]); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user2->id, + 'case_number' => $this->request->case_number, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[1]' => $tokens[1]->id, + 'request_tokens->[2]' => $tokens2[0]->id, + 'request_tokens->[3]' => $tokens2[1]->id, + 'request_tokens->[4]' => $tokens2[2]->id, + 'request_tokens->[5]' => $tokens3[0]->id, + 'request_tokens->[6]' => $tokens3[1]->id, + ]); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user3->id, + 'case_number' => $this->request->case_number, + 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[1]' => $tokens[1]->id, + 'request_tokens->[2]' => $tokens2[0]->id, + 'request_tokens->[3]' => $tokens2[1]->id, + 'request_tokens->[4]' => $tokens2[2]->id, + 'request_tokens->[5]' => $tokens3[0]->id, + 'request_tokens->[6]' => $tokens3[1]->id, + ]); + } + + public function test_tasks() + { + $tokens = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $tokens2 = ProcessRequestToken::factory()->count(3)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'COMPLETED', + ]); + + $tokens3 = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[1]->id' => $tokens[1]->id, + 'tasks->[1]->status' => $tokens[1]->status, + 'tasks->[2]->id' => $tokens2[0]->id, + 'tasks->[2]->status' => $tokens2[0]->status, + 'tasks->[3]->id' => $tokens2[1]->id, + 'tasks->[3]->status' => $tokens2[1]->status, + 'tasks->[4]->id' => $tokens2[2]->id, + 'tasks->[4]->status' => $tokens2[2]->status, + 'tasks->[5]->id' => $tokens3[0]->id, + 'tasks->[5]->status' => $tokens3[0]->status, + 'tasks->[6]->id' => $tokens3[1]->id, + 'tasks->[6]->status' => $tokens3[1]->status, + ]); + } + + public function test_sub_processes() + { + ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + ProcessRequestToken::factory()->count(3)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'COMPLETED', + ]); + + ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->childRequest1->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'processes->[1]->id' => $this->subProcess1->id, + 'processes->[1]->name' => $this->subProcess1->name, + ]); + } + + public function test_child_requests() + { + ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + ProcessRequestToken::factory()->count(3)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->childRequest1->id, + 'element_type' => 'task', + 'status' => 'COMPLETED', + ]); + + ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->childRequest2->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'processes->[1]->id' => $this->subProcess1->id, + 'processes->[1]->name' => $this->subProcess1->name, + 'processes->[2]->id' => $this->subProcess2->id, + 'processes->[2]->name' => $this->subProcess2->name, + 'requests->[0]->id' => $this->request->id, + 'requests->[0]->name' => $this->request->name, + 'requests->[0]->parent_request_id' => $this->request->parent_request_id, + 'requests->[1]->id' => $this->childRequest1->id, + 'requests->[1]->name' => $this->childRequest1->name, + 'requests->[1]->parent_request_id' => $this->childRequest1->parent_request_id, + 'requests->[2]->id' => $this->childRequest2->id, + 'requests->[2]->name' => $this->childRequest2->name, + 'requests->[2]->parent_request_id' => $this->childRequest2->parent_request_id, + ]); + } + + public function test_sub_process_tasks() + { + $tokens = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user->id, + 'process_request_id' => $this->request->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $tokens2 = ProcessRequestToken::factory()->count(3)->create([ + 'user_id' => $this->user2->id, + 'process_request_id' => $this->childRequest1->id, + 'element_type' => 'task', + 'status' => 'COMPLETED', + ]); + + $tokens3 = ProcessRequestToken::factory()->count(2)->create([ + 'user_id' => $this->user3->id, + 'process_request_id' => $this->childRequest2->id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + ]); + + $this->upgrade(); + + $this->assertDatabaseCount('cases_participated', 3); + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'processes->[0]->id' => $this->process->id, + 'processes->[0]->name' => $this->process->name, + 'processes->[1]->id' => $this->subProcess1->id, + 'processes->[1]->name' => $this->subProcess1->name, + 'processes->[2]->id' => $this->subProcess2->id, + 'processes->[2]->name' => $this->subProcess2->name, + 'requests->[0]->id' => $this->request->id, + 'requests->[0]->name' => $this->request->name, + 'requests->[0]->parent_request_id' => $this->request->parent_request_id, + 'requests->[1]->id' => $this->childRequest1->id, + 'requests->[1]->name' => $this->childRequest1->name, + 'requests->[1]->parent_request_id' => $this->childRequest1->parent_request_id, + 'requests->[2]->id' => $this->childRequest2->id, + 'requests->[2]->name' => $this->childRequest2->name, + 'requests->[2]->parent_request_id' => $this->childRequest2->parent_request_id, + ]); + + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user->id, + 'case_number' => $this->request->case_number, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[1]->id' => $tokens[1]->id, + 'tasks->[2]->id' => $tokens2[0]->id, + 'tasks->[3]->id' => $tokens2[1]->id, + 'tasks->[4]->id' => $tokens2[2]->id, + 'tasks->[5]->id' => $tokens3[0]->id, + 'tasks->[6]->id' => $tokens3[1]->id, + ]); + + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user2->id, + 'case_number' => $this->request->case_number, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[1]->id' => $tokens[1]->id, + 'tasks->[2]->id' => $tokens2[0]->id, + 'tasks->[3]->id' => $tokens2[1]->id, + 'tasks->[4]->id' => $tokens2[2]->id, + 'tasks->[5]->id' => $tokens3[0]->id, + 'tasks->[6]->id' => $tokens3[1]->id, + ]); + + $this->assertDatabaseHas('cases_participated', [ + 'user_id' => $this->user3->id, + 'case_number' => $this->request->case_number, + 'tasks->[0]->id' => $tokens[0]->id, + 'tasks->[1]->id' => $tokens[1]->id, + 'tasks->[2]->id' => $tokens2[0]->id, + 'tasks->[3]->id' => $tokens2[1]->id, + 'tasks->[4]->id' => $tokens2[2]->id, + 'tasks->[5]->id' => $tokens3[0]->id, + 'tasks->[6]->id' => $tokens3[1]->id, + ]); + } +} From 1203d3a93f4f2f911db6c27ad51fd1975833636e Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Mon, 4 Nov 2024 16:16:58 -0400 Subject: [PATCH 06/18] improve test for request columns --- .../Upgrade/PopulateCaseStartedTest.php | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index 8d97bd6e96..22e178b6d2 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -276,6 +276,115 @@ public function testCasesStartedProcessColumn() $this->assertEqualsCanonicalizing($expectedData, $processesArray, 'The processes data in cases_started should match the expected data'); } + public function testCasesStarteRequestsColumn() + { + // Instantiate the migration class + $populateCaseStarted = new PopulateCaseStarted(); + + // Confirm the initial state of the `cases_started` table + $initialCount = DB::table('cases_started')->count(); + $this->assertEquals(0, $initialCount, 'cases_started table should be empty before migration'); + + // Create test users + $user1 = User::factory()->create(); + $user2 = User::factory()->create(); + // Create test processes + $process1 = Process::factory()->create(); + $process2 = Process::factory()->create(); + // Create sample ProcessRequests for both users + $processRequest1 = ProcessRequest::factory()->create([ + 'user_id' => $user1->id, + 'name' => $process1->name, + 'process_id' => $process1->id, + ]); + $processRequest2 = ProcessRequest::factory()->create([ + 'user_id' => $user2->id, + 'parent_request_id' => $processRequest1->id, + 'name' => $process2->name, + 'process_id' => $process1->id, + ]); + + // Create ProcessRequestTokens for processRequest1 + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'startEvent', + 'status' => 'TRIGGERED', + 'element_id' => 'node_1', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'callActivity', + 'status' => 'CLOSED', + 'element_id' => 'node_51', + 'user_id' => $user1->id, + 'subprocess_request_id' => $processRequest2->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest1->id, + 'process_id' => $processRequest1->process_id, + 'element_type' => 'task', + 'status' => 'ACTIVE', + 'element_id' => 'node_12', + 'user_id' => $user1->id, + ]); + + // Create ProcessRequestTokens for processRequest2 + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'startEvent', + 'status' => 'TRIGGERED', + 'element_id' => 'node_1', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'task', + 'status' => 'CLOSED', + 'element_id' => 'node_2', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'task', + 'status' => 'CLOSED', + 'element_id' => 'node_12', + 'user_id' => $user1->id, + ]); + ProcessRequestToken::factory()->create([ + 'process_request_id' => $processRequest2->id, + 'process_id' => $processRequest2->process_id, + 'element_type' => 'end_event', + 'status' => 'CLOSED', + 'element_id' => 'node_25', + 'user_id' => null, + ]); + + // Run the migration + $populateCaseStarted->up(); + + // Validate that the ProcessRequest1 has a corresponding entry in `cases_started` + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest1->case_number)->first(); + $this->assertNotNull($casesStartedRecord, 'ProcessRequest should have a corresponding record in cases_started'); + + // Expected data structure for `cases_started.processes` column + $expectedData = [ + ['id' => $processRequest1->id, 'name' => $processRequest1->name, 'parent_request_id' => $processRequest1->parent_request_id], + ['id' => $processRequest2->id, 'name' => $processRequest2->name, 'parent_request_id' => $processRequest1->parent_request_id], + ]; + + // Decode the JSON data from `cases_started.requests` + $requestsArray = json_decode($casesStartedRecord->requests); + + // Assert both arrays contain the same items in any order + $this->assertEqualsCanonicalizing($expectedData, $requestsArray, 'The requests data in cases_started should match the expected data'); + } + /** * Helper function to map ProcessRequest status to cases_started status * From 0e91eaf287372d0485bf620c63219b3a70596a61 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Mon, 4 Nov 2024 16:17:42 -0400 Subject: [PATCH 07/18] Improve case_started migration --- ...024_10_09_032151_populate_case_started.php | 37 ++++++------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index 0dffeb4b27..4556f898dc 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -90,19 +90,15 @@ private function createTemporaryTableWithNonSystemRequests() $subquery->select('case_number')->from('cases_started'); }) ->select( - 'process_requests.id', + DB::raw('min(process_requests.id) as id'), 'process_requests.case_number', - 'process_requests.user_id', - 'process_requests.case_title', - 'process_requests.case_title_formatted', - 'process_requests.initiated_at', - 'process_requests.created_at', - 'process_requests.completed_at', - 'process_requests.updated_at', - 'process_requests.name', - 'process_requests.parent_request_id', - 'processes.id as process_id', - 'processes.name as process_name', + DB::raw('min(process_requests.user_id) as user_id'), + DB::raw('max(process_requests.case_title) as case_title'), + DB::RAW('max(process_requests.case_title_formatted) as case_title_formatted'), + DB::raw('min(process_requests.initiated_at) as initiated_at'), + DB::raw('min(process_requests.created_at) as created_at'), + DB::raw('max(process_requests.completed_at) as completed_at'), + DB::raw('max(process_requests.updated_at) as updated_at'), DB::raw(' JSON_ARRAYAGG( JSON_OBJECT( @@ -120,19 +116,10 @@ private function createTemporaryTableWithNonSystemRequests() ) ) as requests '), // Collect requests in an array of objects - DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status) as status") + DB::raw("max(IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status)) as status") ) ->groupBy( - 'process_requests.id', - 'process_requests.case_number', - 'process_requests.user_id', - 'process_requests.case_title', - 'process_requests.case_title_formatted', - 'process_requests.initiated_at', - 'process_requests.created_at', - 'process_requests.completed_at', - 'process_requests.updated_at', - DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status)") + 'process_requests.case_number' ); // Group by all selected fields that are not aggregated DB::statement('CREATE TEMPORARY TABLE process_requests_temp AS ' . $query->toSql(), $query->getBindings()); @@ -159,7 +146,7 @@ private function createTemporaryParticipantsTable() FROM process_request_tokens pr INNER JOIN - process_requests_temp temp ON pr.process_request_id = temp.id + process_requests temp ON pr.process_request_id = temp.id WHERE pr.user_id IS NOT NULL AND pr.element_type = "task" @@ -179,7 +166,7 @@ private function createTemporaryTableWithRequestTokens() { // Creating the query $query = DB::table('process_request_tokens as pr') - ->join('process_requests_temp as temp', 'pr.process_request_id', '=', 'temp.id') + ->join('process_requests as temp', 'pr.process_request_id', '=', 'temp.id') ->join('participants_temp as part', 'temp.case_number', '=', 'part.case_number') ->select( 'temp.case_number', From ee78d3f95edc1c5b4b602948b27a8d34ed911176 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Mon, 4 Nov 2024 16:25:10 -0400 Subject: [PATCH 08/18] Show the first duplicated case_number --- upgrades/2024_10_09_032151_populate_case_started.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index 4556f898dc..a637f8fc62 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -304,7 +304,9 @@ private function validateDataConsistency() ->first(); if (!is_null($results)) { - throw new Exception('Inconsistency detected, multiple records with null parent for the same request.'); + throw new Exception('Inconsistency detected, multiple records with null parent for the same request. ' + . 'Case number: ' . $results->case_number . ' Count of parent Requests: ' . $results->total + ); } } } From 79277fcfe63de0e15420e62dce4acf3877efb6ab Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Mon, 4 Nov 2024 16:31:46 -0400 Subject: [PATCH 09/18] transform array to object --- tests/Feature/Upgrade/PopulateCaseStartedTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index 22e178b6d2..c68c16cdb1 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -265,8 +265,8 @@ public function testCasesStartedProcessColumn() // Expected data structure for `cases_started.processes` column $expectedData = [ - ['id' => $processRequest1->process_id, 'name' => $processRequest1->name], - ['id' => $processRequest2->process_id, 'name' => $processRequest2->name], + (object) ['id' => $processRequest1->process_id, 'name' => $processRequest1->name], + (object) ['id' => $processRequest2->process_id, 'name' => $processRequest2->name], ]; // Decode the JSON data from `cases_started.processes` @@ -374,8 +374,8 @@ public function testCasesStarteRequestsColumn() // Expected data structure for `cases_started.processes` column $expectedData = [ - ['id' => $processRequest1->id, 'name' => $processRequest1->name, 'parent_request_id' => $processRequest1->parent_request_id], - ['id' => $processRequest2->id, 'name' => $processRequest2->name, 'parent_request_id' => $processRequest1->parent_request_id], + (object) ['id' => $processRequest1->id, 'name' => $processRequest1->name, 'parent_request_id' => $processRequest1->parent_request_id], + (object) ['id' => $processRequest2->id, 'name' => $processRequest2->name, 'parent_request_id' => $processRequest1->parent_request_id], ]; // Decode the JSON data from `cases_started.requests` From 7633094dbc4a0b88e3d6208be5e49b4f42245da6 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Mon, 4 Nov 2024 17:51:46 -0400 Subject: [PATCH 10/18] Show a confirm message --- ...024_10_09_032151_populate_case_started.php | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index a637f8fc62..c369a89d33 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -94,7 +94,7 @@ private function createTemporaryTableWithNonSystemRequests() 'process_requests.case_number', DB::raw('min(process_requests.user_id) as user_id'), DB::raw('max(process_requests.case_title) as case_title'), - DB::RAW('max(process_requests.case_title_formatted) as case_title_formatted'), + DB::raw('max(process_requests.case_title_formatted) as case_title_formatted'), DB::raw('min(process_requests.initiated_at) as initiated_at'), DB::raw('min(process_requests.created_at) as created_at'), DB::raw('max(process_requests.completed_at) as completed_at'), @@ -304,9 +304,27 @@ private function validateDataConsistency() ->first(); if (!is_null($results)) { - throw new Exception('Inconsistency detected, multiple records with null parent for the same request. ' - . 'Case number: ' . $results->case_number . ' Count of parent Requests: ' . $results->total - ); + $warning = 'Inconsistency detected, multiple records with null parent for the same request. ' + . 'Case number: ' . $results->case_number . ' Count of parent Requests: ' . $results->total; + echo PHP_EOL . $warning . PHP_EOL; + // Ask to continue + if ($this->confirm($warning . ' Do you want to continue?')) { + return; + } } } + + function confirm($message) + { + // Show the confirmation message with a "yes/no" prompt + echo $message . " (yes/no): "; + + // Get user input from the command line + $handle = fopen("php://stdin", "r"); + $response = trim(fgets($handle)); + fclose($handle); + + // Check if the response is "yes" + return strtolower($response) === 'yes'; + } } From 6b1d15de8a1df6d11272914780da4918375cba4f Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Tue, 5 Nov 2024 09:00:50 -0400 Subject: [PATCH 11/18] Remove condition to save all the child requests in cases_started.requests --- upgrades/2024_10_09_032151_populate_case_started.php | 1 - 1 file changed, 1 deletion(-) diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index c369a89d33..afa6c7f3a4 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -83,7 +83,6 @@ private function createTemporaryTableWithNonSystemRequests() $query = DB::table('process_requests') ->join('processes', 'process_requests.process_id', '=', 'processes.id') ->join('process_categories', 'processes.process_category_id', '=', 'process_categories.id') - ->whereNull('process_requests.parent_request_id') // Filter out subrequests ->where('process_categories.is_system', false) // Filter out system categories ->whereNotIn('process_requests.case_number', function ($subquery) { // Filter out requests that have already been populated in the cases_started table From 376b5b1f8fcbf45e6f7d9cacf6dd45244d8b6525 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Tue, 5 Nov 2024 10:35:40 -0400 Subject: [PATCH 12/18] fix cypress failing test --- tests/Feature/Upgrade/PopulateCaseStartedTest.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index c68c16cdb1..1fd311c53c 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -192,7 +192,7 @@ public function testCasesStartedProcessColumn() 'user_id' => $user2->id, 'parent_request_id' => $processRequest1->id, 'name' => $process2->name, - 'process_id' => $process1->id, + 'process_id' => $process2->id, ]); // Create ProcessRequestTokens for processRequest1 @@ -301,7 +301,7 @@ public function testCasesStarteRequestsColumn() 'user_id' => $user2->id, 'parent_request_id' => $processRequest1->id, 'name' => $process2->name, - 'process_id' => $process1->id, + 'process_id' => $process2->id, ]); // Create ProcessRequestTokens for processRequest1 @@ -375,7 +375,7 @@ public function testCasesStarteRequestsColumn() // Expected data structure for `cases_started.processes` column $expectedData = [ (object) ['id' => $processRequest1->id, 'name' => $processRequest1->name, 'parent_request_id' => $processRequest1->parent_request_id], - (object) ['id' => $processRequest2->id, 'name' => $processRequest2->name, 'parent_request_id' => $processRequest1->parent_request_id], + (object) ['id' => $processRequest2->id, 'name' => $processRequest2->name, 'parent_request_id' => $processRequest2->parent_request_id], ]; // Decode the JSON data from `cases_started.requests` From 5cbedc515e7af62357c113046a3fa74c95e0b306 Mon Sep 17 00:00:00 2001 From: Rodrigo Quelca Date: Tue, 5 Nov 2024 10:39:11 -0400 Subject: [PATCH 13/18] fix bad test label --- tests/Feature/Upgrade/PopulateCaseStartedTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index 1fd311c53c..bbb2bcf8af 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -276,7 +276,7 @@ public function testCasesStartedProcessColumn() $this->assertEqualsCanonicalizing($expectedData, $processesArray, 'The processes data in cases_started should match the expected data'); } - public function testCasesStarteRequestsColumn() + public function testCasesStartedRequestsColumn() { // Instantiate the migration class $populateCaseStarted = new PopulateCaseStarted(); From 19b15765f670feb58b8ec633b1909f4546d2b4bf Mon Sep 17 00:00:00 2001 From: Miguel Angel Date: Tue, 5 Nov 2024 11:27:15 -0400 Subject: [PATCH 14/18] feat: ref cases participated upgrade --- ..._09_152947_populate_cases_participated.php | 156 ++++++------------ 1 file changed, 50 insertions(+), 106 deletions(-) diff --git a/upgrades/2024_10_09_152947_populate_cases_participated.php b/upgrades/2024_10_09_152947_populate_cases_participated.php index f5853ec898..5223755df8 100644 --- a/upgrades/2024_10_09_152947_populate_cases_participated.php +++ b/upgrades/2024_10_09_152947_populate_cases_participated.php @@ -1,9 +1,6 @@ validateDataConsistency(); + $total_participants = $this->validateDataConsistency(); DB::table('cases_participated')->truncate(); - echo PHP_EOL . ' Populating case_participated from process_requests' . PHP_EOL; + echo PHP_EOL . ' Populating case_participated from cases_started' . PHP_EOL; $startTime = microtime(true); // Start the timer - $this->createTemporaryTableWithNonSystemRequests(); - $this->logTimeElapsed('Created temporary table with non-system requests', $startTime); - $this->createTemporaryParticipantsTable(); $this->logTimeElapsed('Created temporary table with participants', $startTime); @@ -33,7 +27,8 @@ public function up() $count = DB::table('cases_participated')->count(); - echo PHP_EOL . "Cases Participated have been populated successfully. Total cases: {$count}" . PHP_EOL; + echo PHP_EOL . "Cases Started participants. Total cases started participants: {$total_participants}" . PHP_EOL; + echo PHP_EOL . "Cases Participated have been populated successfully. Total cases participated: {$count}" . PHP_EOL; echo PHP_EOL; } @@ -64,68 +59,6 @@ private function logTimeElapsed(string $message, float $startTime): void echo " {$message} - Time elapsed: " . number_format($timeElapsed, 4) . ' seconds' . PHP_EOL; } - /** - * Creates a temporary table with request tokens associated with - * the process requests. - * - * @return void - * - * @throws Exception If there is an error creating the temporary table - */ - private function createTemporaryTableWithNonSystemRequests() - { - // Creating the query - $query = DB::table('process_requests') - ->select([ - 'process_requests.id', - 'process_requests.case_number', - 'process_requests.user_id', - 'process_requests.case_title', - 'process_requests.case_title_formatted', - 'process_requests.initiated_at', - 'process_requests.created_at', - 'process_requests.completed_at', - 'process_requests.updated_at', - 'process_requests.name', - 'process_requests.parent_request_id', - 'processes.id as process_id', - 'processes.name as process_name', - DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status) as status"), - DB::raw("JSON_ARRAYAGG( - JSON_OBJECT( - 'id', processes.id, - 'name', processes.name - ) - ) as processes"), - DB::raw("JSON_ARRAYAGG( - JSON_OBJECT( - 'id', process_requests.id, - 'name', process_requests.name, - 'parent_request_id', process_requests.parent_request_id - ) - ) as requests"), - ]) - ->join('processes', 'process_requests.process_id', '=', 'processes.id') - ->join('process_categories', 'processes.process_category_id', '=', 'process_categories.id') - ->whereNull('process_requests.parent_request_id') - ->where('process_categories.is_system', '=', false) - ->groupBy([ - 'process_requests.id', - 'process_requests.case_number', - 'process_requests.user_id', - 'process_requests.case_title', - 'process_requests.case_title_formatted', - 'process_requests.initiated_at', - 'process_requests.created_at', - 'process_requests.completed_at', - 'process_requests.updated_at', - DB::raw("IF(process_requests.status = 'ACTIVE', 'IN_PROGRESS', process_requests.status)"), - ]); - - // Execute the query and create a temporary table - DB::statement('CREATE TEMPORARY TABLE process_requests_temp2 AS ' . $query->toSql(), $query->getBindings()); - } - /** * Creates a temporary table from process_request_tokens, * obtaining unique user_id by case_number @@ -137,15 +70,30 @@ private function createTemporaryTableWithNonSystemRequests() private function createTemporaryParticipantsTable() { // Build the query for `participants_temp2` - $query = DB::table('process_request_tokens as prt') + $query = DB::table('cases_started as cs') ->select([ - 'prt.user_id', - 'pr.case_number', + DB::raw('participants.item as user_id'), + 'cs.case_number', + 'cs.case_title', + 'cs.case_title_formatted', + 'cs.case_status', + 'cs.processes', + 'cs.requests', + 'cs.request_tokens', + 'cs.tasks', + 'cs.participants', + 'cs.initiated_at', + 'cs.completed_at', + 'cs.created_at', + 'cs.updated_at', + 'cs.keywords', ]) - ->join('process_requests_temp2 as pr', 'prt.process_request_id', '=', 'pr.id') - ->whereNotNull('prt.user_id') - ->where('prt.element_type', '=', 'task') - ->groupBy(['pr.case_number', 'prt.user_id']); + ->join( + DB::raw('JSON_TABLE(cs.participants, \'$[*]\' COLUMNS(item INT PATH \'$\')) AS participants'), + function ($join) { + // The join condition is essentially empty, just joins for each item in participants + } + ); // Execute the query and create the temporary table DB::statement('CREATE TEMPORARY TABLE participants_temp2 AS ' . $query->toSql(), $query->getBindings()); @@ -153,50 +101,46 @@ private function createTemporaryParticipantsTable() private function insertIntoCasesParticipated() { - $insertQuery = DB::table('cases_started as prt1') - ->join('participants_temp2 as part', 'prt1.case_number', '=', 'part.case_number') + $insertQuery = DB::table('participants_temp2 as part') ->select([ - 'prt1.case_number', - 'prt1.case_status', - 'prt1.case_title', - 'prt1.case_title_formatted', - 'prt1.completed_at', - 'prt1.created_at', - 'prt1.initiated_at', - 'prt1.keywords', - 'prt1.participants', - 'prt1.processes', - 'prt1.request_tokens', - 'prt1.requests', - 'prt1.tasks', - 'prt1.updated_at', 'part.user_id', + 'part.case_number', + 'part.case_title', + 'part.case_title_formatted', + 'part.case_status', + 'part.processes', + 'part.requests', + 'part.request_tokens', + 'part.tasks', + 'part.participants', + 'part.initiated_at', + 'part.completed_at', + 'part.created_at', + 'part.updated_at', + 'part.keywords', ]); // Perform the insert and return the number of affected rows return DB::table('cases_participated')->insertUsing([ - 'case_number', 'case_status', 'case_title', 'case_title_formatted', - 'completed_at', 'created_at', 'initiated_at', 'keywords', - 'participants', 'processes', 'request_tokens', 'requests', - 'tasks', 'updated_at', 'user_id', + 'user_id', 'case_number', 'case_title', 'case_title_formatted', 'case_status', + 'processes', 'requests', 'request_tokens', 'tasks', 'participants', + 'initiated_at', 'completed_at', 'created_at', 'updated_at', 'keywords', ], $insertQuery); } /** - * Check if exist inconsitency in "process_request" table + * Check if exist inconsistency in "process_request" table */ private function validateDataConsistency() { - $results = DB::table('process_requests') - ->select('case_number', DB::raw('count(*) as total')) - ->whereNull('parent_request_id') - ->whereNotNull('case_number') - ->groupBy('case_number') - ->having('total', '>', 1) + $results = DB::table('cases_started') + ->select(DB::raw('sum(json_length(participants)) total_participants')) ->first(); - if (!is_null($results)) { + if (is_null($results)) { throw new Exception('Inconsistency detected, multiple records with null parent for the same request.'); } + + return $results->total_participants; } } From 3dd22a763e0c83f5acc17c0de4a93fa3bd108340 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Tue, 5 Nov 2024 12:04:34 -0400 Subject: [PATCH 15/18] Fix migrations of case_started --- ...024_10_09_032151_populate_case_started.php | 87 ++++++++++++------- 1 file changed, 54 insertions(+), 33 deletions(-) diff --git a/upgrades/2024_10_09_032151_populate_case_started.php b/upgrades/2024_10_09_032151_populate_case_started.php index afa6c7f3a4..3c73dd6b79 100644 --- a/upgrades/2024_10_09_032151_populate_case_started.php +++ b/upgrades/2024_10_09_032151_populate_case_started.php @@ -84,6 +84,8 @@ private function createTemporaryTableWithNonSystemRequests() ->join('processes', 'process_requests.process_id', '=', 'processes.id') ->join('process_categories', 'processes.process_category_id', '=', 'process_categories.id') ->where('process_categories.is_system', false) // Filter out system categories + ->whereNotNull('process_requests.case_number') + ->whereNull('process_requests.parent_request_id') ->whereNotIn('process_requests.case_number', function ($subquery) { // Filter out requests that have already been populated in the cases_started table $subquery->select('case_number')->from('cases_started'); @@ -122,6 +124,37 @@ private function createTemporaryTableWithNonSystemRequests() ); // Group by all selected fields that are not aggregated DB::statement('CREATE TEMPORARY TABLE process_requests_temp AS ' . $query->toSql(), $query->getBindings()); + + DB::statement(<< Date: Tue, 5 Nov 2024 14:40:52 -0400 Subject: [PATCH 16/18] test: update cases participated upgrade tests --- .../Upgrade/PopulateCasesParticipatedTest.php | 257 +++++++++++++----- ..._09_152947_populate_cases_participated.php | 6 +- 2 files changed, 199 insertions(+), 64 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php b/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php index 977922677c..c4315a11f9 100644 --- a/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php +++ b/tests/Feature/Upgrade/PopulateCasesParticipatedTest.php @@ -3,6 +3,7 @@ namespace Tests\Upgrades; use Illuminate\Foundation\Testing\RefreshDatabase; +use ProcessMaker\Models\CaseStarted; use ProcessMaker\Models\Process; use ProcessMaker\Models\ProcessRequest; use ProcessMaker\Models\ProcessRequestToken; @@ -77,6 +78,44 @@ private function upgrade() ])->run(); } + private function getCaseStartedData($tokens) + { + $processes = collect([ + [ + 'id' => $this->process->id, + 'name' => $this->process->name, + ], + ]); + + $requests = collect([ + [ + 'id' => $this->request->id, + 'name' => $this->request->name, + 'parent_request_id' => $this->request->parent_request_id, + ], + ]); + + $tasks = $tokens->map(function ($item) { + return [ + 'id' => $item->id, + 'element_id' => $item->element_id, + 'name' => $item->element_name, + 'process_id' => $item->process_id, + 'status' => $item->status, + ]; + }); + + $requestTokens = $tokens->pluck('id'); + + return [ + 'processes' => $processes->toArray(), + 'requests' => $requests->toArray(), + 'tasks' => $tasks->toArray(), + 'request_tokens' => $requestTokens->toArray(), + 'participants' => $tokens->pluck('user_id')->unique()->values()->toArray(), + ]; + } + public function test_one_participant() { $tokens = ProcessRequestToken::factory()->count(5)->create([ @@ -85,15 +124,19 @@ public function test_one_participant() 'element_type' => 'task', ]); + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $this->getCaseStartedData($tokens))); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 1); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, - 'case_title' => $this->request->case_title, - 'case_title_formatted' => $this->request->case_title_formatted, - 'case_status' => 'IN_PROGRESS', + 'case_number' => $case->case_number, + 'case_title' => $case->case_title, + 'case_title_formatted' => $case->case_title_formatted, + 'case_status' => $case->case_status, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'requests->[0]->id' => $this->request->id, @@ -116,7 +159,7 @@ public function test_one_participant() public function test_multiple_participants() { - $tokens = ProcessRequestToken::factory()->count(5)->create([ + $tokens1 = ProcessRequestToken::factory()->count(5)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', @@ -134,29 +177,36 @@ public function test_multiple_participants() 'element_type' => 'task', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + + $data = $this->getCaseStartedData($tokens); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, - 'case_title' => $this->request->case_title, - 'case_title_formatted' => $this->request->case_title_formatted, - 'case_status' => 'IN_PROGRESS', + 'case_number' => $case->case_number, + 'case_title' => $case->case_title, + 'case_title_formatted' => $case->case_title_formatted, + 'case_status' => $case->case_status, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'requests->[0]->id' => $this->request->id, 'requests->[0]->name' => $this->request->name, 'requests->[0]->parent_request_id' => $this->request->parent_request_id, - 'request_tokens' => 1, - 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[0]' => $tokens1[0]->id, 'request_tokens->[9]' => $tokens2[4]->id, 'request_tokens->[14]' => $tokens3[4]->id, - 'tasks->[0]->id' => $tokens[0]->id, - 'tasks->[0]->element_id' => $tokens[0]->element_id, - 'tasks->[0]->name' => $tokens[0]->element_name, - 'tasks->[0]->process_id' => $tokens[0]->process_id, - 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[0]->id' => $tokens1[0]->id, + 'tasks->[0]->element_id' => $tokens1[0]->element_id, + 'tasks->[0]->name' => $tokens1[0]->element_name, + 'tasks->[0]->process_id' => $tokens1[0]->process_id, + 'tasks->[0]->status' => $tokens1[0]->status, 'tasks->[9]->id' => $tokens2[4]->id, 'tasks->[9]->element_id' => $tokens2[4]->element_id, 'tasks->[9]->name' => $tokens2[4]->element_name, @@ -168,26 +218,26 @@ public function test_multiple_participants() 'tasks->[14]->process_id' => $tokens3[4]->process_id, 'tasks->[14]->status' => $tokens3[4]->status, ]); + $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user2->id, - 'case_number' => $this->request->case_number, - 'case_title' => $this->request->case_title, - 'case_title_formatted' => $this->request->case_title_formatted, - 'case_status' => 'IN_PROGRESS', + 'case_number' => $case->case_number, + 'case_title' => $case->case_title, + 'case_title_formatted' => $case->case_title_formatted, + 'case_status' => $case->case_status, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'requests->[0]->id' => $this->request->id, 'requests->[0]->name' => $this->request->name, 'requests->[0]->parent_request_id' => $this->request->parent_request_id, - 'request_tokens' => 1, - 'request_tokens->[0]' => $tokens[0]->id, + 'request_tokens->[0]' => $tokens1[0]->id, 'request_tokens->[9]' => $tokens2[4]->id, 'request_tokens->[14]' => $tokens3[4]->id, - 'tasks->[0]->id' => $tokens[0]->id, - 'tasks->[0]->element_id' => $tokens[0]->element_id, - 'tasks->[0]->name' => $tokens[0]->element_name, - 'tasks->[0]->process_id' => $tokens[0]->process_id, - 'tasks->[0]->status' => $tokens[0]->status, + 'tasks->[0]->id' => $tokens1[0]->id, + 'tasks->[0]->element_id' => $tokens1[0]->element_id, + 'tasks->[0]->name' => $tokens1[0]->element_name, + 'tasks->[0]->process_id' => $tokens1[0]->process_id, + 'tasks->[0]->status' => $tokens1[0]->status, 'tasks->[9]->id' => $tokens2[4]->id, 'tasks->[9]->element_id' => $tokens2[4]->element_id, 'tasks->[9]->name' => $tokens2[4]->element_name, @@ -203,44 +253,51 @@ public function test_multiple_participants() public function test_participants() { - ProcessRequestToken::factory()->count(5)->create([ + $tokens1 = ProcessRequestToken::factory()->count(5)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', ]); - ProcessRequestToken::factory()->count(5)->create([ + $tokens2 = ProcessRequestToken::factory()->count(5)->create([ 'user_id' => $this->user2->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', ]); - ProcessRequestToken::factory()->count(5)->create([ + $tokens3 = ProcessRequestToken::factory()->count(5)->create([ 'user_id' => $this->user3->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'participants->[0]' => $this->user->id, 'participants->[1]' => $this->user2->id, 'participants->[2]' => $this->user3->id, ]); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user2->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'participants->[0]' => $this->user->id, 'participants->[1]' => $this->user2->id, 'participants->[2]' => $this->user3->id, ]); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user3->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'participants->[0]' => $this->user->id, 'participants->[1]' => $this->user2->id, 'participants->[2]' => $this->user3->id, @@ -249,7 +306,7 @@ public function test_participants() public function test_request_tokens() { - $tokens = ProcessRequestToken::factory()->count(2)->create([ + $tokens1 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', @@ -267,14 +324,21 @@ public function test_request_tokens() 'element_type' => 'task', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, - 'request_tokens->[0]' => $tokens[0]->id, - 'request_tokens->[1]' => $tokens[1]->id, + 'case_number' => $case->case_number, + 'request_tokens->[0]' => $tokens1[0]->id, + 'request_tokens->[1]' => $tokens1[1]->id, 'request_tokens->[2]' => $tokens2[0]->id, 'request_tokens->[3]' => $tokens2[1]->id, 'request_tokens->[4]' => $tokens2[2]->id, @@ -283,9 +347,9 @@ public function test_request_tokens() ]); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user2->id, - 'case_number' => $this->request->case_number, - 'request_tokens->[0]' => $tokens[0]->id, - 'request_tokens->[1]' => $tokens[1]->id, + 'case_number' => $case->case_number, + 'request_tokens->[0]' => $tokens1[0]->id, + 'request_tokens->[1]' => $tokens1[1]->id, 'request_tokens->[2]' => $tokens2[0]->id, 'request_tokens->[3]' => $tokens2[1]->id, 'request_tokens->[4]' => $tokens2[2]->id, @@ -294,9 +358,9 @@ public function test_request_tokens() ]); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user3->id, - 'case_number' => $this->request->case_number, - 'request_tokens->[0]' => $tokens[0]->id, - 'request_tokens->[1]' => $tokens[1]->id, + 'case_number' => $case->case_number, + 'request_tokens->[0]' => $tokens1[0]->id, + 'request_tokens->[1]' => $tokens1[1]->id, 'request_tokens->[2]' => $tokens2[0]->id, 'request_tokens->[3]' => $tokens2[1]->id, 'request_tokens->[4]' => $tokens2[2]->id, @@ -307,7 +371,7 @@ public function test_request_tokens() public function test_tasks() { - $tokens = ProcessRequestToken::factory()->count(2)->create([ + $tokens1 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', @@ -328,16 +392,23 @@ public function test_tasks() 'status' => 'ACTIVE', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, - 'tasks->[0]->id' => $tokens[0]->id, - 'tasks->[0]->status' => $tokens[0]->status, - 'tasks->[1]->id' => $tokens[1]->id, - 'tasks->[1]->status' => $tokens[1]->status, + 'case_number' => $case->case_number, + 'tasks->[0]->id' => $tokens1[0]->id, + 'tasks->[0]->status' => $tokens1[0]->status, + 'tasks->[1]->id' => $tokens1[1]->id, + 'tasks->[1]->status' => $tokens1[1]->status, 'tasks->[2]->id' => $tokens2[0]->id, 'tasks->[2]->status' => $tokens2[0]->status, 'tasks->[3]->id' => $tokens2[1]->id, @@ -353,33 +424,45 @@ public function test_tasks() public function test_sub_processes() { - ProcessRequestToken::factory()->count(2)->create([ + $tokens1 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', 'status' => 'ACTIVE', ]); - ProcessRequestToken::factory()->count(3)->create([ + $tokens2 = ProcessRequestToken::factory()->count(3)->create([ 'user_id' => $this->user2->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', 'status' => 'COMPLETED', ]); - ProcessRequestToken::factory()->count(2)->create([ + $tokens3 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user3->id, 'process_request_id' => $this->childRequest1->id, 'element_type' => 'task', 'status' => 'ACTIVE', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $data['processes'] = collect($data['processes'])->push([ + 'id' => $this->subProcess1->id, + 'name' => $this->subProcess1->name, + ])->toArray(); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'processes->[1]->id' => $this->subProcess1->id, @@ -389,33 +472,58 @@ public function test_sub_processes() public function test_child_requests() { - ProcessRequestToken::factory()->count(2)->create([ + $tokens1 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', 'status' => 'ACTIVE', ]); - ProcessRequestToken::factory()->count(3)->create([ + $tokens2 = ProcessRequestToken::factory()->count(3)->create([ 'user_id' => $this->user2->id, 'process_request_id' => $this->childRequest1->id, 'element_type' => 'task', 'status' => 'COMPLETED', ]); - ProcessRequestToken::factory()->count(2)->create([ + $tokens3 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user3->id, 'process_request_id' => $this->childRequest2->id, 'element_type' => 'task', 'status' => 'ACTIVE', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $data['processes'] = collect($data['processes'])->push([ + 'id' => $this->subProcess1->id, + 'name' => $this->subProcess1->name, + ])->push([ + 'id' => $this->subProcess2->id, + 'name' => $this->subProcess2->name, + ])->toArray(); + + $data['requests'] = collect($data['requests'])->push([ + 'id' => $this->childRequest1->id, + 'name' => $this->childRequest1->name, + 'parent_request_id' => $this->childRequest1->parent_request_id, + ])->push([ + 'id' => $this->childRequest2->id, + 'name' => $this->childRequest2->name, + 'parent_request_id' => $this->childRequest2->parent_request_id, + ])->toArray(); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'processes->[1]->id' => $this->subProcess1->id, @@ -436,7 +544,7 @@ public function test_child_requests() public function test_sub_process_tasks() { - $tokens = ProcessRequestToken::factory()->count(2)->create([ + $tokens1 = ProcessRequestToken::factory()->count(2)->create([ 'user_id' => $this->user->id, 'process_request_id' => $this->request->id, 'element_type' => 'task', @@ -457,12 +565,37 @@ public function test_sub_process_tasks() 'status' => 'ACTIVE', ]); + $tokens = $tokens1->merge($tokens2)->merge($tokens3); + $data = $this->getCaseStartedData($tokens); + + $data['processes'] = collect($data['processes'])->push([ + 'id' => $this->subProcess1->id, + 'name' => $this->subProcess1->name, + ])->push([ + 'id' => $this->subProcess2->id, + 'name' => $this->subProcess2->name, + ])->toArray(); + + $data['requests'] = collect($data['requests'])->push([ + 'id' => $this->childRequest1->id, + 'name' => $this->childRequest1->name, + 'parent_request_id' => $this->childRequest1->parent_request_id, + ])->push([ + 'id' => $this->childRequest2->id, + 'name' => $this->childRequest2->name, + 'parent_request_id' => $this->childRequest2->parent_request_id, + ])->toArray(); + + $case = CaseStarted::factory()->create(array_merge([ + 'user_id' => $this->user->id + ], $data)); + $this->upgrade(); $this->assertDatabaseCount('cases_participated', 3); $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'processes->[0]->id' => $this->process->id, 'processes->[0]->name' => $this->process->name, 'processes->[1]->id' => $this->subProcess1->id, @@ -482,7 +615,7 @@ public function test_sub_process_tasks() $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'tasks->[0]->id' => $tokens[0]->id, 'tasks->[1]->id' => $tokens[1]->id, 'tasks->[2]->id' => $tokens2[0]->id, @@ -494,7 +627,7 @@ public function test_sub_process_tasks() $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user2->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'tasks->[0]->id' => $tokens[0]->id, 'tasks->[1]->id' => $tokens[1]->id, 'tasks->[2]->id' => $tokens2[0]->id, @@ -506,7 +639,7 @@ public function test_sub_process_tasks() $this->assertDatabaseHas('cases_participated', [ 'user_id' => $this->user3->id, - 'case_number' => $this->request->case_number, + 'case_number' => $case->case_number, 'tasks->[0]->id' => $tokens[0]->id, 'tasks->[1]->id' => $tokens[1]->id, 'tasks->[2]->id' => $tokens2[0]->id, diff --git a/upgrades/2024_10_09_152947_populate_cases_participated.php b/upgrades/2024_10_09_152947_populate_cases_participated.php index 5223755df8..1984b90719 100644 --- a/upgrades/2024_10_09_152947_populate_cases_participated.php +++ b/upgrades/2024_10_09_152947_populate_cases_participated.php @@ -14,7 +14,7 @@ public function up() { $total_participants = $this->validateDataConsistency(); - DB::table('cases_participated')->truncate(); + DB::table('cases_participated')->delete(); echo PHP_EOL . ' Populating case_participated from cases_started' . PHP_EOL; $startTime = microtime(true); // Start the timer @@ -40,7 +40,7 @@ public function up() */ public function down() { - DB::table('cases_participated')->truncate(); + DB::table('cases_participated')->delete(); } /** @@ -69,6 +69,8 @@ private function logTimeElapsed(string $message, float $startTime): void */ private function createTemporaryParticipantsTable() { + DB::statement('DROP TEMPORARY TABLE IF EXISTS participants_temp2'); + // Build the query for `participants_temp2` $query = DB::table('cases_started as cs') ->select([ From bda389647273f957a0ce2e4461380356cc2e63bb Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Tue, 5 Nov 2024 16:46:56 -0400 Subject: [PATCH 17/18] Use RefreshDatabase for the test --- tests/Feature/Upgrade/PopulateCaseStartedTest.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index bbb2bcf8af..e2dee17f7a 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -2,8 +2,8 @@ namespace Tests\Upgrades; +use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\DB; -use Mockery; use PopulateCaseStarted; use ProcessMaker\Models\Process; use ProcessMaker\Models\ProcessRequest; @@ -11,11 +11,9 @@ use ProcessMaker\Models\User; use Tests\TestCase; -// use Illuminate\Foundation\Testing\RefreshDatabase; - class PopulateCaseStartedTest extends TestCase { - // use RefreshDatabase; + use RefreshDatabase; protected function setUp(): void { From 678b0eda188828ec406e7c02c716cd3c6d8309cd Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Tue, 5 Nov 2024 22:00:50 -0400 Subject: [PATCH 18/18] Fix test --- tests/Feature/Upgrade/PopulateCaseStartedTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Feature/Upgrade/PopulateCaseStartedTest.php b/tests/Feature/Upgrade/PopulateCaseStartedTest.php index e2dee17f7a..8160d0cbc5 100644 --- a/tests/Feature/Upgrade/PopulateCaseStartedTest.php +++ b/tests/Feature/Upgrade/PopulateCaseStartedTest.php @@ -99,7 +99,7 @@ public function testTokensColumn() // Confirm record insertion into cases_started $finalCount = DB::table('cases_started')->count(); $this->assertEquals($processRequests->count(), $finalCount, 'cases_started count should match the number of ProcessRequests created'); - $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->id)->first(); + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->case_number)->first(); $this->assertNotNull($casesStartedRecord, 'Each ProcessRequest should have a corresponding record in cases_started'); $tokensArray = json_decode($casesStartedRecord->request_tokens, true); @@ -157,7 +157,7 @@ public function testParticipatedColumn() // Confirm record insertion into cases_started $finalCount = DB::table('cases_started')->count(); $this->assertEquals($processRequests->count(), $finalCount, 'cases_started count should match the number of ProcessRequests created'); - $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->id)->first(); + $casesStartedRecord = DB::table('cases_started')->where('case_number', $processRequest->case_number)->first(); $this->assertNotNull($casesStartedRecord, 'Each ProcessRequest should have a corresponding record in cases_started'); // Prepare the participants record $tokensArray = json_decode($casesStartedRecord->participants, true);