diff --git a/phpmyfaq/src/phpMyFAQ/Search.php b/phpmyfaq/src/phpMyFAQ/Search.php index 6ac823e4d9..8ab437ddf0 100755 --- a/phpmyfaq/src/phpMyFAQ/Search.php +++ b/phpmyfaq/src/phpMyFAQ/Search.php @@ -77,7 +77,7 @@ public function getCategoryId(): ?int */ public function search(string $searchTerm, bool $allLanguages = true): array { - if (is_numeric($searchTerm)) { + if (is_numeric($searchTerm) && $this->configuration->get('search.searchForSolutionId')) { return $this->searchDatabase($searchTerm, $allLanguages); } diff --git a/tests/phpMyFAQ/SearchTest.php b/tests/phpMyFAQ/SearchTest.php index ace5f3aca3..4768c9cb75 100644 --- a/tests/phpMyFAQ/SearchTest.php +++ b/tests/phpMyFAQ/SearchTest.php @@ -7,6 +7,7 @@ use phpMyFAQ\Database\Sqlite3; use phpMyFAQ\Plugin\PluginException; use PHPUnit\Framework\TestCase; +use ReflectionClass; use stdClass; class SearchTest extends TestCase @@ -39,6 +40,19 @@ protected function tearDown(): void $this->search->deleteAllSearchTerms(); } + /** + * Helper method to set configuration values for testing using reflection + */ + private function setConfigValue(string $key, mixed $value): void + { + $reflection = new ReflectionClass($this->configuration); + $property = $reflection->getProperty('config'); + $property->setAccessible(true); + $config = $property->getValue($this->configuration); + $config[$key] = $value; + $property->setValue($this->configuration, $config); + } + public function testSetCategoryId(): void { $this->search->setCategoryId(1); @@ -54,8 +68,38 @@ public function testGetCategoryId(): void /** * @throws Exception */ - public function testSearchWithNumericTerm(): void + public function testSearchWithNumericTermWhenSolutionIdSearchEnabled(): void + { + $this->setConfigValue('search.searchForSolutionId', 'true'); + + $this->search = $this->getMockBuilder(Search::class) + ->setConstructorArgs([$this->configuration]) + ->onlyMethods(['searchDatabase']) + ->getMock(); + + $this->search->expects($this->once()) + ->method('searchDatabase') + ->with('123', true) + ->willReturn([]); + + $this->assertEquals([], $this->search->search('123')); + } + + /** + * @throws Exception + * When solution ID search is disabled and no search engines are enabled, + * numeric searches should fall through to searchDatabase() which will + * perform a full-text search (not a solution ID search). The database + * search classes check the configuration internally to determine the + * search type. The second parameter (true) indicates search across all + * languages, not the search type. + */ + public function testSearchWithNumericTermWhenSolutionIdSearchDisabled(): void { + $this->setConfigValue('search.searchForSolutionId', 'false'); + $this->setConfigValue('search.enableElasticsearch', 'false'); + $this->setConfigValue('search.enableOpenSearch', 'false'); + $this->search = $this->getMockBuilder(Search::class) ->setConstructorArgs([$this->configuration]) ->onlyMethods(['searchDatabase']) @@ -69,6 +113,49 @@ public function testSearchWithNumericTerm(): void $this->assertEquals([], $this->search->search('123')); } + /** + * @throws Exception + */ + public function testSearchWithNumericTermWhenElasticsearchEnabledAndSolutionIdSearchDisabled(): void + { + $this->setConfigValue('search.searchForSolutionId', 'false'); + $this->setConfigValue('search.enableElasticsearch', 'true'); + + $this->search = $this->getMockBuilder(Search::class) + ->setConstructorArgs([$this->configuration]) + ->onlyMethods(['searchElasticsearch']) + ->getMock(); + + $this->search->expects($this->once()) + ->method('searchElasticsearch') + ->with('123', true) + ->willReturn([]); + + $this->assertEquals([], $this->search->search('123')); + } + + /** + * @throws Exception + */ + public function testSearchWithNumericTermWhenOpenSearchEnabledAndSolutionIdSearchDisabled(): void + { + $this->setConfigValue('search.searchForSolutionId', 'false'); + $this->setConfigValue('search.enableElasticsearch', 'false'); + $this->setConfigValue('search.enableOpenSearch', 'true'); + + $this->search = $this->getMockBuilder(Search::class) + ->setConstructorArgs([$this->configuration]) + ->onlyMethods(['searchOpenSearch']) + ->getMock(); + + $this->search->expects($this->once()) + ->method('searchOpenSearch') + ->with('123', true) + ->willReturn([]); + + $this->assertEquals([], $this->search->search('123')); + } + /** * @throws Exception */