Skip to content

Commit d0374a2

Browse files
committed
test: added more tests for Bookmark and Search classes
1 parent 922bb02 commit d0374a2

2 files changed

Lines changed: 176 additions & 0 deletions

File tree

tests/phpMyFAQ/BookmarkTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,16 @@ public function testGetAll(): void
9292
$this->bookmark->remove(1);
9393
}
9494

95+
public function testGetAllReturnsCachedBookmarksWithoutRepositoryLookup(): void
96+
{
97+
$reflection = new ReflectionClass(Bookmark::class);
98+
$property = $reflection->getProperty('bookmarkCache');
99+
$cachedBookmarks = [(object) ['faqid' => 42]];
100+
$property->setValue($this->bookmark, $cachedBookmarks);
101+
102+
$this->assertSame($cachedBookmarks, $this->bookmark->getAll());
103+
}
104+
95105
public function testRemove(): void
96106
{
97107
$this->bookmark->add(1);
@@ -123,6 +133,15 @@ public function testIsFaqBookmarkWithInvalidIdReturnsFalse(): void
123133
$this->assertFalse($this->bookmark->isFaqBookmark(-10));
124134
}
125135

136+
public function testIsFaqBookmarkIgnoresBookmarksWithoutFaqIdProperty(): void
137+
{
138+
$reflection = new ReflectionClass(Bookmark::class);
139+
$property = $reflection->getProperty('bookmarkCache');
140+
$property->setValue($this->bookmark, [(object) ['bookmark' => 1]]);
141+
142+
$this->assertFalse($this->bookmark->isFaqBookmark(1));
143+
}
144+
126145
public function testRemoveInvalidId(): void
127146
{
128147
$this->assertFalse($this->bookmark->remove(0));

tests/phpMyFAQ/SearchTest.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,14 @@
33
namespace phpMyFAQ;
44

55
use Exception;
6+
use phpMyFAQ\Configuration\ElasticsearchConfiguration;
7+
use phpMyFAQ\Configuration\OpenSearchConfiguration;
68
use phpMyFAQ\Database\Sqlite3;
79
use phpMyFAQ\Plugin\PluginException;
10+
use phpMyFAQ\Search\Search\Elasticsearch;
11+
use OpenSearch\Client as OpenSearchClient;
812
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
13+
use PHPUnit\Framework\Attributes\UsesClass;
914
use PHPUnit\Framework\TestCase;
1015
use ReflectionClass;
1116
use ReflectionMethod;
@@ -14,6 +19,9 @@
1419
use Symfony\Component\HttpFoundation\Session\SessionInterface;
1520

1621
#[AllowMockObjectsWithoutExpectations]
22+
#[UsesClass(Elasticsearch::class)]
23+
#[UsesClass(ElasticsearchConfiguration::class)]
24+
#[UsesClass(OpenSearchConfiguration::class)]
1725
class SearchTest extends TestCase
1826
{
1927
private Configuration $configuration;
@@ -305,6 +313,155 @@ public function testAutoCompleteFallsBackToDatabaseSearch(): void
305313
$this->assertSame([['question' => 'foo']], $search->autoComplete('foo'));
306314
}
307315

316+
/**
317+
* @throws Exception
318+
*/
319+
public function testLogSearchTermReturnsEarlyForEmptyString(): void
320+
{
321+
$this->assertSame(0, $this->search->getSearchesCount());
322+
323+
$this->search->logSearchTerm('');
324+
325+
$this->assertSame(0, $this->search->getSearchesCount());
326+
}
327+
328+
/**
329+
* @throws Exception
330+
*/
331+
public function testAutoCompleteUsesOpenSearchWhenConfigured(): void
332+
{
333+
$language = $this->createMock(Language::class);
334+
$language->method('getLanguage')->willReturn('en');
335+
336+
$category = $this->createMock(Category::class);
337+
$category->method('getAllCategoryIds')->willReturn([1, 2, 3]);
338+
339+
$client = $this
340+
->getMockBuilder(OpenSearchClient::class)
341+
->disableOriginalConstructor()
342+
->onlyMethods(['search'])
343+
->getMock();
344+
$client
345+
->expects($this->once())
346+
->method('search')
347+
->with($this->callback(static function (array $params): bool {
348+
return $params['body']['query']['bool']['filter']['term']['lang'] === 'en';
349+
}))
350+
->willReturn([
351+
'hits' => [
352+
'total' => ['value' => 1],
353+
'hits' => [
354+
[
355+
'_source' => [
356+
'id' => 42,
357+
'lang' => 'en',
358+
'question' => 'elastic result',
359+
'answer' => 'answer',
360+
'keywords' => 'phpmyfaq',
361+
'category_id' => 1,
362+
],
363+
'_score' => 1.0,
364+
],
365+
],
366+
],
367+
]);
368+
369+
$config = $this->createMock(Configuration::class);
370+
$openSearchConfigFile = tempnam(sys_get_temp_dir(), 'pmf-opensearch-');
371+
file_put_contents(
372+
$openSearchConfigFile,
373+
"<?php\n\$PMF_OS = ['hosts' => ['http://localhost:9200'], 'index' => 'faq-index'];\n",
374+
);
375+
$config
376+
->method('get')
377+
->willReturnCallback(static fn (string $item): mixed => match ($item) {
378+
'search.enableElasticsearch' => false,
379+
'search.enableOpenSearch' => true,
380+
default => null,
381+
});
382+
$config->method('getLanguage')->willReturn($language);
383+
$config->method('getOpenSearch')->willReturn($client);
384+
$config
385+
->method('getOpenSearchConfig')
386+
->willReturn(new OpenSearchConfiguration($openSearchConfigFile));
387+
388+
$search = new Search($config);
389+
$search->setCategory($category);
390+
391+
$results = $search->autoComplete('elastic');
392+
393+
$this->assertCount(1, $results);
394+
$this->assertSame('elastic result', $results[0]->question);
395+
396+
unlink($openSearchConfigFile);
397+
}
398+
399+
/**
400+
* @throws Exception
401+
*/
402+
public function testSearchOpenSearchUsesCategoryAndLanguageFilters(): void
403+
{
404+
$language = $this->createMock(Language::class);
405+
$language->method('getLanguage')->willReturn('en');
406+
407+
$category = $this->createMock(Category::class);
408+
$category->method('getAllCategoryIds')->willReturn([1, 2, 3]);
409+
$category->method('getChildNodes')->with(2)->willReturn([4, 5]);
410+
411+
$client = $this
412+
->getMockBuilder(OpenSearchClient::class)
413+
->disableOriginalConstructor()
414+
->onlyMethods(['search'])
415+
->getMock();
416+
$client
417+
->expects($this->once())
418+
->method('search')
419+
->with($this->callback(static function (array $params): bool {
420+
return $params['body']['query']['bool']['should'][0]['bool']['filter']['terms']['category_id'] === [2, 4, 5];
421+
}))
422+
->willReturn([
423+
'hits' => [
424+
'total' => ['value' => 1],
425+
'hits' => [
426+
[
427+
'_source' => [
428+
'id' => 84,
429+
'lang' => 'en',
430+
'question' => 'open search result',
431+
'answer' => 'answer',
432+
'keywords' => 'phpmyfaq',
433+
'category_id' => 2,
434+
],
435+
'_score' => 1.5,
436+
],
437+
],
438+
],
439+
]);
440+
441+
$config = $this->createMock(Configuration::class);
442+
$openSearchConfigFile = tempnam(sys_get_temp_dir(), 'pmf-opensearch-');
443+
file_put_contents(
444+
$openSearchConfigFile,
445+
"<?php\n\$PMF_OS = ['hosts' => ['http://localhost:9200'], 'index' => 'faq-index'];\n",
446+
);
447+
$config->method('getLanguage')->willReturn($language);
448+
$config->method('getOpenSearch')->willReturn($client);
449+
$config
450+
->method('getOpenSearchConfig')
451+
->willReturn(new OpenSearchConfiguration($openSearchConfigFile));
452+
453+
$search = new Search($config);
454+
$search->setCategory($category);
455+
$search->setCategoryId(2);
456+
457+
$results = $search->searchOpenSearch('elastic', false);
458+
459+
$this->assertCount(1, $results);
460+
$this->assertSame('open search result', $results[0]->question);
461+
462+
unlink($openSearchConfigFile);
463+
}
464+
308465
public function testResolveSearchDatabaseTypeMapsKnownDrivers(): void
309466
{
310467
$driverMap = [

0 commit comments

Comments
 (0)