diff --git a/ProcessMaker/Http/Controllers/Api/V1_1/ProcessVariableController.php b/ProcessMaker/Http/Controllers/Api/V1_1/ProcessVariableController.php index 2b5f462923..1aff342c03 100644 --- a/ProcessMaker/Http/Controllers/Api/V1_1/ProcessVariableController.php +++ b/ProcessMaker/Http/Controllers/Api/V1_1/ProcessVariableController.php @@ -236,7 +236,9 @@ public function getProcessesVariables(array $processIds, $excludeSavedSearch, $p // and applies filtering for excluded fields. $query = DB::table('asset_variables as av') ->join('var_finder_variables as vfv', 'av.id', '=', 'vfv.asset_variable_id') - ->whereIn('av.process_id', $processIds) + ->when($processIds !== [], function ($query) use ($processIds) { + $query->whereIn('av.process_id', $processIds); + }) ->groupBy('vfv.field', 'vfv.label') ->select([ DB::raw('MAX(vfv.id) as id'), @@ -256,7 +258,7 @@ public function getProcessesVariables(array $processIds, $excludeSavedSearch, $p return $this->mergeOnlyAvailableColumns($paginator, $savedSearch, $activeColumns); } - return $query->paginate($perPage, ['*'], 'page', $page); + return $paginator; } /** @@ -288,9 +290,23 @@ private function mergeAvailableColumns(?SavedSearch $savedSearch = null) $availableColumns = collect(); if ($savedSearch?->available_columns) { - $availableColumns = $savedSearch->available_columns->merge( - $savedSearch->getDataColumnsAttribute() ?? collect() - ); + $availableColumns = $savedSearch->available_columns; + + if ( + $savedSearch->type === SavedSearch::TYPE_COLLECTION + || !class_exists(ProcessVariable::class) + || !Schema::hasTable('process_variables') + || !self::$useVarFinder + ) { + $availableColumns = $availableColumns->merge( + $savedSearch->getDataColumnsAttribute() ?? collect() + ); + } else { + $availableColumns = $availableColumns + ->merge($savedSearch->process_columns) + ->unique('field') + ->values(); + } } return $availableColumns; diff --git a/tests/Feature/Api/V1_1/ProcessVariableControllerTest.php b/tests/Feature/Api/V1_1/ProcessVariableControllerTest.php index 0b013681de..5f8e6f4cd7 100644 --- a/tests/Feature/Api/V1_1/ProcessVariableControllerTest.php +++ b/tests/Feature/Api/V1_1/ProcessVariableControllerTest.php @@ -544,4 +544,131 @@ public function test_saved_search_with_no_available_columns(): void $this->assertFalse($filteredFields->contains('initiated_at')); $this->assertFalse($filteredFields->contains('completed_at')); } + + public function test_only_available_with_empty_process_ids_returns_defaults_and_variables(): void + { + $this->setupCreateUser(); + + if (!$this->isVariablesFinderEnabled) { + $this->markTestSkipped('VariableFinder is required for this test.'); + } + + $savedSearch = SavedSearch::factory()->create([ + 'type' => 'request', + 'meta' => [ + 'icon' => 'bath', + 'file' => null, + 'collection_id' => null, + 'columns' => [], + ], + 'pmql' => '', + ]); + + $response = $this->apiCall( + 'GET', + '/api/1.1/processes/variables?processIds=&savedSearchId=' . $savedSearch->id . '&onlyAvailable=' + ); + + $response->assertStatus(200); + + $fields = collect($response->json('data'))->pluck('field'); + + $this->assertTrue($fields->contains('case_number')); + $this->assertTrue($fields->contains('name')); + $this->assertGreaterThan(10, $fields->count()); + } + + public function test_only_available_first_page_includes_defaults_and_paginated_variables(): void + { + $this->setupCreateUser(); + + if (!$this->isVariablesFinderEnabled) { + $this->markTestSkipped('VariableFinder is required for this test.'); + } + + $savedSearch = SavedSearch::factory()->create([ + 'type' => 'request', + 'meta' => [ + 'icon' => 'bath', + 'file' => null, + 'collection_id' => null, + 'columns' => [], + ], + 'pmql' => '', + ]); + + $response = $this->apiCall( + 'GET', + '/api/1.1/processes/variables?processIds=1&savedSearchId=' . $savedSearch->id . '&onlyAvailable=&page=1&per_page=5' + ); + + $response->assertStatus(200); + + $fields = collect($response->json('data'))->pluck('field'); + + $this->assertTrue($fields->contains('case_number')); + $this->assertGreaterThan(5, $fields->count()); + } + + public function test_second_page_without_only_available_omits_saved_search_defaults(): void + { + $this->setupCreateUser(); + + if (!$this->isVariablesFinderEnabled) { + $this->markTestSkipped('VariableFinder is required for this test.'); + } + + $savedSearch = SavedSearch::factory()->create([ + 'type' => 'request', + 'meta' => [ + 'icon' => 'bath', + 'file' => null, + 'collection_id' => null, + 'columns' => [], + ], + 'pmql' => '', + ]); + + $response = $this->apiCall( + 'GET', + '/api/1.1/processes/variables?processIds=1&savedSearchId=' . $savedSearch->id . '&page=2&per_page=5' + ); + + $response->assertStatus(200); + + $fields = collect($response->json('data'))->pluck('field'); + + $this->assertFalse($fields->contains('case_number')); + $this->assertFalse($fields->contains('case_title')); + $this->assertGreaterThan(0, $fields->count()); + } + + public function test_empty_process_ids_returns_variable_finder_rows(): void + { + $this->setupCreateUser(); + + if (!$this->isVariablesFinderEnabled) { + $this->markTestSkipped('VariableFinder is required for this test.'); + } + + $response = $this->apiCall('GET', '/api/1.1/processes/variables?processIds=&page=1&per_page=100'); + + $response->assertStatus(200); + $this->assertEquals(30, $response->json('meta.total')); + } + + public function test_non_only_available_request_returns_single_paginated_page(): void + { + $this->setupCreateUser(); + + if (!$this->isVariablesFinderEnabled) { + $this->markTestSkipped('VariableFinder is required for this test.'); + } + + $response = $this->apiCall('GET', '/api/1.1/processes/variables?processIds=1&page=1&per_page=5'); + + $response->assertStatus(200); + $this->assertCount(5, $response->json('data')); + $this->assertEquals(10, $response->json('meta.total')); + } }