xref: /plugin/statistics/_test/SearchEnginesTest.php (revision 6811247a0bc8a9bcfa5be848932c2907af4329fc)
1364ef148SAndreas Gohr<?php
2364ef148SAndreas Gohr
3364ef148SAndreas Gohrnamespace dokuwiki\plugin\statistics\test;
4364ef148SAndreas Gohr
5364ef148SAndreas Gohruse DokuWikiTest;
6364ef148SAndreas Gohruse dokuwiki\plugin\statistics\SearchEngines;
7364ef148SAndreas Gohr
8364ef148SAndreas Gohr/**
9364ef148SAndreas Gohr * Tests for the SearchEngines class
10364ef148SAndreas Gohr *
11364ef148SAndreas Gohr * @group plugin_statistics
12364ef148SAndreas Gohr * @group plugins
13364ef148SAndreas Gohr */
14364ef148SAndreas Gohrclass SearchEnginesTest extends DokuWikiTest
15364ef148SAndreas Gohr{
16364ef148SAndreas Gohr    /**
17364ef148SAndreas Gohr     * Data provider for testing known search engines
18364ef148SAndreas Gohr     */
19364ef148SAndreas Gohr    public function knownSearchEnginesProvider(): array
20364ef148SAndreas Gohr    {
21364ef148SAndreas Gohr        return [
22364ef148SAndreas Gohr            // Google variants
23364ef148SAndreas Gohr            'google.com' => [
24364ef148SAndreas Gohr                'https://www.google.com/search?q=dokuwiki+test',
25364ef148SAndreas Gohr                true,
26364ef148SAndreas Gohr                'google',
27364ef148SAndreas Gohr                'Google',
28364ef148SAndreas Gohr                'dokuwiki test'
29364ef148SAndreas Gohr            ],
30364ef148SAndreas Gohr            'google.co.uk' => [
31364ef148SAndreas Gohr                'https://www.google.co.uk/search?q=php+framework',
32364ef148SAndreas Gohr                true,
33364ef148SAndreas Gohr                'google',
34364ef148SAndreas Gohr                'Google',
35364ef148SAndreas Gohr                'php framework'
36364ef148SAndreas Gohr            ],
37364ef148SAndreas Gohr            'google.de' => [
38364ef148SAndreas Gohr                'https://www.google.de/search?q=test+query',
39364ef148SAndreas Gohr                true,
40364ef148SAndreas Gohr                'google',
41364ef148SAndreas Gohr                'Google',
42364ef148SAndreas Gohr                'test query'
43364ef148SAndreas Gohr            ],
44364ef148SAndreas Gohr
45364ef148SAndreas Gohr            // Bing
46364ef148SAndreas Gohr            'bing.com' => [
47364ef148SAndreas Gohr                'https://www.bing.com/search?q=dokuwiki+plugin',
48364ef148SAndreas Gohr                true,
49364ef148SAndreas Gohr                'bing',
50364ef148SAndreas Gohr                'Bing',
51364ef148SAndreas Gohr                'dokuwiki plugin'
52364ef148SAndreas Gohr            ],
53364ef148SAndreas Gohr            'bing.co.uk' => [
54364ef148SAndreas Gohr                'https://www.bing.co.uk/search?q=search+test',
55364ef148SAndreas Gohr                true,
56364ef148SAndreas Gohr                'bing',
57364ef148SAndreas Gohr                'Bing',
58364ef148SAndreas Gohr                'search test'
59364ef148SAndreas Gohr            ],
60364ef148SAndreas Gohr
61364ef148SAndreas Gohr            // Yahoo
62364ef148SAndreas Gohr            'yahoo.com' => [
63364ef148SAndreas Gohr                'https://search.yahoo.com/search?p=test+search',
64364ef148SAndreas Gohr                true,
65364ef148SAndreas Gohr                'yahoo',
66364ef148SAndreas Gohr                'Yahoo!',
67364ef148SAndreas Gohr                'test search'
68364ef148SAndreas Gohr            ],
69364ef148SAndreas Gohr
70364ef148SAndreas Gohr            // Yandex
71364ef148SAndreas Gohr            'yandex.ru' => [
72364ef148SAndreas Gohr                'https://yandex.ru/search/?query=test+query',
73364ef148SAndreas Gohr                true,
74364ef148SAndreas Gohr                'yandex',
75364ef148SAndreas Gohr                'Яндекс (Yandex)',
76364ef148SAndreas Gohr                'test query'
77364ef148SAndreas Gohr            ],
78364ef148SAndreas Gohr            'yandex.com' => [
79364ef148SAndreas Gohr                'https://yandex.com/search/?query=another+test',
80364ef148SAndreas Gohr                true,
81364ef148SAndreas Gohr                'yandex',
82364ef148SAndreas Gohr                'Яндекс (Yandex)',
83364ef148SAndreas Gohr                'another test'
84364ef148SAndreas Gohr            ],
85364ef148SAndreas Gohr
86364ef148SAndreas Gohr            // Naver
87364ef148SAndreas Gohr            'naver.com' => [
88364ef148SAndreas Gohr                'https://search.naver.com/search.naver?query=korean+search',
89364ef148SAndreas Gohr                true,
90364ef148SAndreas Gohr                'naver',
91364ef148SAndreas Gohr                '네이버 (Naver)',
92364ef148SAndreas Gohr                'korean search'
93364ef148SAndreas Gohr            ],
94364ef148SAndreas Gohr
95364ef148SAndreas Gohr            // Baidu
96364ef148SAndreas Gohr            'baidu.com' => [
97364ef148SAndreas Gohr                'https://www.baidu.com/s?wd=chinese+search',
98364ef148SAndreas Gohr                true,
99364ef148SAndreas Gohr                'baidu',
100364ef148SAndreas Gohr                '百度 (Baidu)',
101364ef148SAndreas Gohr                'chinese search'
102364ef148SAndreas Gohr            ],
103364ef148SAndreas Gohr            'baidu.com word param' => [
104364ef148SAndreas Gohr                'https://www.baidu.com/s?word=test+word',
105364ef148SAndreas Gohr                true,
106364ef148SAndreas Gohr                'baidu',
107364ef148SAndreas Gohr                '百度 (Baidu)',
108364ef148SAndreas Gohr                'test word'
109364ef148SAndreas Gohr            ],
110364ef148SAndreas Gohr            'baidu.com kw param' => [
111364ef148SAndreas Gohr                'https://www.baidu.com/s?kw=keyword+test',
112364ef148SAndreas Gohr                true,
113364ef148SAndreas Gohr                'baidu',
114364ef148SAndreas Gohr                '百度 (Baidu)',
115364ef148SAndreas Gohr                'keyword test'
116364ef148SAndreas Gohr            ],
117364ef148SAndreas Gohr
118364ef148SAndreas Gohr            // Ask
119364ef148SAndreas Gohr            'ask.com' => [
120364ef148SAndreas Gohr                'https://www.ask.com/web?q=ask+search',
121364ef148SAndreas Gohr                true,
122364ef148SAndreas Gohr                'ask',
123364ef148SAndreas Gohr                'Ask',
124364ef148SAndreas Gohr                'ask search'
125364ef148SAndreas Gohr            ],
126364ef148SAndreas Gohr            'ask.com ask param' => [
127364ef148SAndreas Gohr                'https://www.ask.com/web?ask=test+ask',
128364ef148SAndreas Gohr                true,
129364ef148SAndreas Gohr                'ask',
130364ef148SAndreas Gohr                'Ask',
131364ef148SAndreas Gohr                'test ask'
132364ef148SAndreas Gohr            ],
133364ef148SAndreas Gohr            'search-results.com' => [
134364ef148SAndreas Gohr                'https://www.search-results.com/web?q=search+results',
135364ef148SAndreas Gohr                true,
136364ef148SAndreas Gohr                'ask_search_results',
137364ef148SAndreas Gohr                'Ask',
138364ef148SAndreas Gohr                'search results'
139364ef148SAndreas Gohr            ],
140364ef148SAndreas Gohr
141364ef148SAndreas Gohr            // DuckDuckGo
142364ef148SAndreas Gohr            'duckduckgo.com' => [
143364ef148SAndreas Gohr                'https://duckduckgo.com/?q=privacy+search',
144364ef148SAndreas Gohr                true,
145364ef148SAndreas Gohr                'duckduckgo',
146364ef148SAndreas Gohr                'DuckDuckGo',
147364ef148SAndreas Gohr                'privacy search'
148364ef148SAndreas Gohr            ],
149364ef148SAndreas Gohr
15045f4cdffSAndreas Gohr            // Ecosia
15145f4cdffSAndreas Gohr            'ecosia.org' => [
15245f4cdffSAndreas Gohr                'https://www.ecosia.org/search?method=index&q=eco+friendly+search',
15345f4cdffSAndreas Gohr                true,
15445f4cdffSAndreas Gohr                'ecosia',
15545f4cdffSAndreas Gohr                'Ecosia',
15645f4cdffSAndreas Gohr                'eco friendly search'
15745f4cdffSAndreas Gohr            ],
15845f4cdffSAndreas Gohr
15945f4cdffSAndreas Gohr            // Qwant
16045f4cdffSAndreas Gohr            'qwant.com' => [
16145f4cdffSAndreas Gohr                'https://www.qwant.com/?q=dokuwiki&t=web',
16245f4cdffSAndreas Gohr                true,
16345f4cdffSAndreas Gohr                'qwant',
16445f4cdffSAndreas Gohr                'Qwant',
16545f4cdffSAndreas Gohr                'dokuwiki'
16645f4cdffSAndreas Gohr            ],
16745f4cdffSAndreas Gohr
168364ef148SAndreas Gohr            // AOL
169364ef148SAndreas Gohr            'aol.com' => [
170364ef148SAndreas Gohr                'https://search.aol.com/aol/search?query=aol+search',
171364ef148SAndreas Gohr                true,
172364ef148SAndreas Gohr                'aol',
173364ef148SAndreas Gohr                'AOL Search',
174364ef148SAndreas Gohr                'aol search'
175364ef148SAndreas Gohr            ],
17645f4cdffSAndreas Gohr
177364ef148SAndreas Gohr            'aol.co.uk' => [
178364ef148SAndreas Gohr                'https://search.aol.co.uk/aol/search?q=uk+search',
179364ef148SAndreas Gohr                true,
180364ef148SAndreas Gohr                'aol',
181364ef148SAndreas Gohr                'AOL Search',
182364ef148SAndreas Gohr                'uk search'
183364ef148SAndreas Gohr            ],
184364ef148SAndreas Gohr
185364ef148SAndreas Gohr            // Babylon
186364ef148SAndreas Gohr            'babylon.com' => [
187364ef148SAndreas Gohr                'https://search.babylon.com/?q=babylon+search',
188364ef148SAndreas Gohr                true,
189364ef148SAndreas Gohr                'babylon',
190364ef148SAndreas Gohr                'Babylon',
191364ef148SAndreas Gohr                'babylon search'
192364ef148SAndreas Gohr            ],
193364ef148SAndreas Gohr
194*6811247aSAndreas Gohr            // AVG
195364ef148SAndreas Gohr            'avg.com' => [
196364ef148SAndreas Gohr                'https://search.avg.com/search?q=avg+search',
197364ef148SAndreas Gohr                true,
198*6811247aSAndreas Gohr                'avg',
199*6811247aSAndreas Gohr                'AVG Safe Search',
200364ef148SAndreas Gohr                'avg search'
201364ef148SAndreas Gohr            ],
202*6811247aSAndreas Gohr
203*6811247aSAndreas Gohr            // Brave
204*6811247aSAndreas Gohr            'brave.com' => [
205*6811247aSAndreas Gohr                'https://search.brave.com/search?q=brave+search',
206*6811247aSAndreas Gohr                true,
207*6811247aSAndreas Gohr                'brave',
208*6811247aSAndreas Gohr                'Brave Search',
209*6811247aSAndreas Gohr                'brave search'
210*6811247aSAndreas Gohr            ],
211364ef148SAndreas Gohr        ];
212364ef148SAndreas Gohr    }
213364ef148SAndreas Gohr
214364ef148SAndreas Gohr    /**
215364ef148SAndreas Gohr     * Data provider for testing generic search engines
216364ef148SAndreas Gohr     */
217364ef148SAndreas Gohr    public function genericSearchEnginesProvider(): array
218364ef148SAndreas Gohr    {
219364ef148SAndreas Gohr        return [
220364ef148SAndreas Gohr            'generic with q param' => [
221364ef148SAndreas Gohr                'https://search.example.com/?q=generic+search',
222364ef148SAndreas Gohr                true,
223364ef148SAndreas Gohr                'example',
224364ef148SAndreas Gohr                'Example',
225364ef148SAndreas Gohr                'generic search'
226364ef148SAndreas Gohr            ],
227364ef148SAndreas Gohr            'generic with query param' => [
228364ef148SAndreas Gohr                'https://find.testsite.org/search?query=test+query',
229364ef148SAndreas Gohr                true,
230364ef148SAndreas Gohr                'testsite',
231364ef148SAndreas Gohr                'Testsite',
232364ef148SAndreas Gohr                'test query'
233364ef148SAndreas Gohr            ],
234364ef148SAndreas Gohr            'generic with search param' => [
235364ef148SAndreas Gohr                'https://www.searchengine.net/?search=search+term',
236364ef148SAndreas Gohr                true,
237364ef148SAndreas Gohr                'searchengine',
238364ef148SAndreas Gohr                'Searchengine',
239364ef148SAndreas Gohr                'search term'
240364ef148SAndreas Gohr            ],
241364ef148SAndreas Gohr            'generic with keywords param' => [
242364ef148SAndreas Gohr                'https://lookup.site.com/?keywords=keyword+test',
243364ef148SAndreas Gohr                true,
244364ef148SAndreas Gohr                'site',
245364ef148SAndreas Gohr                'Site',
246364ef148SAndreas Gohr                'keyword test'
247364ef148SAndreas Gohr            ],
248364ef148SAndreas Gohr            'generic with keyword param' => [
249364ef148SAndreas Gohr                'https://engine.co.uk/?keyword=single+keyword',
250364ef148SAndreas Gohr                true,
251364ef148SAndreas Gohr                'engine',
252364ef148SAndreas Gohr                'Engine',
253364ef148SAndreas Gohr                'single keyword'
254364ef148SAndreas Gohr            ],
255364ef148SAndreas Gohr        ];
256364ef148SAndreas Gohr    }
257364ef148SAndreas Gohr
258364ef148SAndreas Gohr    /**
259364ef148SAndreas Gohr     * Data provider for testing non-search engine referers
260364ef148SAndreas Gohr     */
261364ef148SAndreas Gohr    public function nonSearchEngineProvider(): array
262364ef148SAndreas Gohr    {
263364ef148SAndreas Gohr        return [
264364ef148SAndreas Gohr            'regular website' => [
265364ef148SAndreas Gohr                'https://www.example.com/page',
266364ef148SAndreas Gohr                false,
267364ef148SAndreas Gohr                null,
268364ef148SAndreas Gohr                null,
269364ef148SAndreas Gohr                null
270364ef148SAndreas Gohr            ],
271364ef148SAndreas Gohr            'social media' => [
272364ef148SAndreas Gohr                'https://www.facebook.com/share',
273364ef148SAndreas Gohr                false,
274364ef148SAndreas Gohr                null,
275364ef148SAndreas Gohr                null,
276364ef148SAndreas Gohr                null
277364ef148SAndreas Gohr            ],
278364ef148SAndreas Gohr            'invalid URL' => [
279364ef148SAndreas Gohr                'not-a-url',
280364ef148SAndreas Gohr                false,
281364ef148SAndreas Gohr                null,
282364ef148SAndreas Gohr                null,
283364ef148SAndreas Gohr                null
284364ef148SAndreas Gohr            ],
285364ef148SAndreas Gohr            'URL without host' => [
286364ef148SAndreas Gohr                '/local/path',
287364ef148SAndreas Gohr                false,
288364ef148SAndreas Gohr                null,
289364ef148SAndreas Gohr                null,
290364ef148SAndreas Gohr                null
291364ef148SAndreas Gohr            ],
292364ef148SAndreas Gohr        ];
293364ef148SAndreas Gohr    }
294364ef148SAndreas Gohr
295364ef148SAndreas Gohr    /**
296364ef148SAndreas Gohr     * Data provider for testing query cleaning
297364ef148SAndreas Gohr     */
298364ef148SAndreas Gohr    public function queryCleaningProvider(): array
299364ef148SAndreas Gohr    {
300364ef148SAndreas Gohr        return [
301364ef148SAndreas Gohr            'cache query removed' => [
302364ef148SAndreas Gohr                'https://www.google.com/search?q=cache:example.com+test',
303364ef148SAndreas Gohr                true,
304364ef148SAndreas Gohr                'google',
305364ef148SAndreas Gohr                'Google',
306364ef148SAndreas Gohr                'test'
307364ef148SAndreas Gohr            ],
308364ef148SAndreas Gohr            'related query removed' => [
309364ef148SAndreas Gohr                'https://www.google.com/search?q=related:example.com+search',
310364ef148SAndreas Gohr                true,
311364ef148SAndreas Gohr                'google',
312364ef148SAndreas Gohr                'Google',
313364ef148SAndreas Gohr                'search'
314364ef148SAndreas Gohr            ],
315364ef148SAndreas Gohr            'multiple spaces compacted' => [
316364ef148SAndreas Gohr                'https://www.google.com/search?q=test++multiple+++spaces',
317364ef148SAndreas Gohr                true,
318364ef148SAndreas Gohr                'google',
319364ef148SAndreas Gohr                'Google',
320364ef148SAndreas Gohr                'test multiple spaces'
321364ef148SAndreas Gohr            ],
322364ef148SAndreas Gohr            'whitespace trimmed' => [
323364ef148SAndreas Gohr                'https://www.google.com/search?q=++trimmed++',
324364ef148SAndreas Gohr                true,
325364ef148SAndreas Gohr                'google',
326364ef148SAndreas Gohr                'Google',
327364ef148SAndreas Gohr                'trimmed'
328364ef148SAndreas Gohr            ],
329364ef148SAndreas Gohr        ];
330364ef148SAndreas Gohr    }
331364ef148SAndreas Gohr
332364ef148SAndreas Gohr    /**
333364ef148SAndreas Gohr     * Data provider for testing fragment-based queries
334364ef148SAndreas Gohr     */
335364ef148SAndreas Gohr    public function fragmentQueryProvider(): array
336364ef148SAndreas Gohr    {
337364ef148SAndreas Gohr        return [
338364ef148SAndreas Gohr            'fragment query' => [
339364ef148SAndreas Gohr                'https://www.google.com/search#q=fragment+query',
340364ef148SAndreas Gohr                true,
341364ef148SAndreas Gohr                'google',
342364ef148SAndreas Gohr                'Google',
343364ef148SAndreas Gohr                'fragment query'
344364ef148SAndreas Gohr            ],
345364ef148SAndreas Gohr            'fragment with multiple params' => [
346364ef148SAndreas Gohr                'https://www.bing.com/search#q=fragment+test&other=param',
347364ef148SAndreas Gohr                true,
348364ef148SAndreas Gohr                'bing',
349364ef148SAndreas Gohr                'Bing',
350364ef148SAndreas Gohr                'fragment test'
351364ef148SAndreas Gohr            ],
352364ef148SAndreas Gohr        ];
353364ef148SAndreas Gohr    }
354364ef148SAndreas Gohr
355364ef148SAndreas Gohr    /**
356364ef148SAndreas Gohr     * Test known search engines
357364ef148SAndreas Gohr     * @dataProvider knownSearchEnginesProvider
358364ef148SAndreas Gohr     */
359364ef148SAndreas Gohr    public function testKnownSearchEngines(
360364ef148SAndreas Gohr        string $referer,
361364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
362364ef148SAndreas Gohr        ?string $expectedEngine,
363364ef148SAndreas Gohr        ?string $expectedName,
364364ef148SAndreas Gohr        ?string $expectedQuery
365364ef148SAndreas Gohr    ): void {
366364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
367364ef148SAndreas Gohr
368364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
369364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
370364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
371364ef148SAndreas Gohr
372364ef148SAndreas Gohr        if ($expectedEngine) {
373364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
374364ef148SAndreas Gohr        }
375364ef148SAndreas Gohr    }
376364ef148SAndreas Gohr
377364ef148SAndreas Gohr    /**
378364ef148SAndreas Gohr     * Test generic search engines
379364ef148SAndreas Gohr     * @dataProvider genericSearchEnginesProvider
380364ef148SAndreas Gohr     */
381364ef148SAndreas Gohr    public function testGenericSearchEngines(
382364ef148SAndreas Gohr        string $referer,
383364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
384364ef148SAndreas Gohr        ?string $expectedEngine,
385364ef148SAndreas Gohr        ?string $expectedName,
386364ef148SAndreas Gohr        ?string $expectedQuery
387364ef148SAndreas Gohr    ): void {
388364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
389364ef148SAndreas Gohr
390364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
391364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
392364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
393364ef148SAndreas Gohr
394364ef148SAndreas Gohr        if ($expectedEngine) {
395364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
396364ef148SAndreas Gohr        }
397364ef148SAndreas Gohr    }
398364ef148SAndreas Gohr
399364ef148SAndreas Gohr    /**
400364ef148SAndreas Gohr     * Test non-search engine referers
401364ef148SAndreas Gohr     * @dataProvider nonSearchEngineProvider
402364ef148SAndreas Gohr     */
403364ef148SAndreas Gohr    public function testNonSearchEngines(
404364ef148SAndreas Gohr        string $referer,
405364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
406364ef148SAndreas Gohr        ?string $expectedEngine,
407364ef148SAndreas Gohr        ?string $expectedName,
408364ef148SAndreas Gohr        ?string $expectedQuery
409364ef148SAndreas Gohr    ): void {
410364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
411364ef148SAndreas Gohr
412364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
413364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
414364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
415364ef148SAndreas Gohr    }
416364ef148SAndreas Gohr
417364ef148SAndreas Gohr    /**
418364ef148SAndreas Gohr     * Test query cleaning functionality
419364ef148SAndreas Gohr     * @dataProvider queryCleaningProvider
420364ef148SAndreas Gohr     */
421364ef148SAndreas Gohr    public function testQueryCleaning(
422364ef148SAndreas Gohr        string $referer,
423364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
424364ef148SAndreas Gohr        ?string $expectedEngine,
425364ef148SAndreas Gohr        ?string $expectedName,
426364ef148SAndreas Gohr        ?string $expectedQuery
427364ef148SAndreas Gohr    ): void {
428364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
429364ef148SAndreas Gohr
430364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
431364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
432364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
433364ef148SAndreas Gohr    }
434364ef148SAndreas Gohr
435364ef148SAndreas Gohr    /**
436364ef148SAndreas Gohr     * Test fragment-based queries
437364ef148SAndreas Gohr     * @dataProvider fragmentQueryProvider
438364ef148SAndreas Gohr     */
439364ef148SAndreas Gohr    public function testFragmentQueries(
440364ef148SAndreas Gohr        string $referer,
441364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
442364ef148SAndreas Gohr        ?string $expectedEngine,
443364ef148SAndreas Gohr        ?string $expectedName,
444364ef148SAndreas Gohr        ?string $expectedQuery
445364ef148SAndreas Gohr    ): void {
446364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
447364ef148SAndreas Gohr
448364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
449364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
450364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
451364ef148SAndreas Gohr    }
452364ef148SAndreas Gohr
453364ef148SAndreas Gohr    /**
454364ef148SAndreas Gohr     * Test static getName method with unknown engine
455364ef148SAndreas Gohr     */
456364ef148SAndreas Gohr    public function testGetNameUnknownEngine(): void
457364ef148SAndreas Gohr    {
458364ef148SAndreas Gohr        $unknownEngine = 'unknown_engine';
459c428ec28SAndreas Gohr        $this->assertEquals('Unknown_engine', SearchEngines::getName($unknownEngine));
460364ef148SAndreas Gohr    }
461364ef148SAndreas Gohr
462364ef148SAndreas Gohr    /**
463364ef148SAndreas Gohr     * Test static getUrl method
464364ef148SAndreas Gohr     */
465364ef148SAndreas Gohr    public function testGetUrl(): void
466364ef148SAndreas Gohr    {
467*6811247aSAndreas Gohr        $this->assertEquals('https://www.google.com', SearchEngines::getUrl('google'));
468*6811247aSAndreas Gohr        $this->assertEquals('https://www.bing.com', SearchEngines::getUrl('bing'));
469364ef148SAndreas Gohr        $this->assertNull(SearchEngines::getUrl('unknown_engine'));
470364ef148SAndreas Gohr    }
471364ef148SAndreas Gohr
472364ef148SAndreas Gohr    /**
473364ef148SAndreas Gohr     * Test case insensitive domain matching
474364ef148SAndreas Gohr     */
475364ef148SAndreas Gohr    public function testCaseInsensitiveDomainMatching(): void
476364ef148SAndreas Gohr    {
477364ef148SAndreas Gohr        $referer = 'https://WWW.GOOGLE.COM/search?q=case+test';
478364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
479364ef148SAndreas Gohr
480364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
481364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
482364ef148SAndreas Gohr        $this->assertEquals('case test', $searchEngine->getQuery());
483364ef148SAndreas Gohr    }
484364ef148SAndreas Gohr
485364ef148SAndreas Gohr    /**
486364ef148SAndreas Gohr     * Test URL encoding in queries
487364ef148SAndreas Gohr     */
488364ef148SAndreas Gohr    public function testUrlEncodedQueries(): void
489364ef148SAndreas Gohr    {
490364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=url%20encoded%20query';
491364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
492364ef148SAndreas Gohr
493364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
494364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
495364ef148SAndreas Gohr        $this->assertEquals('url encoded query', $searchEngine->getQuery());
496364ef148SAndreas Gohr    }
497364ef148SAndreas Gohr
498364ef148SAndreas Gohr    /**
499364ef148SAndreas Gohr     * Test plus encoding in queries
500364ef148SAndreas Gohr     */
501364ef148SAndreas Gohr    public function testPlusEncodedQueries(): void
502364ef148SAndreas Gohr    {
503364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=plus+encoded+query';
504364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
505364ef148SAndreas Gohr
506364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
507364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
508364ef148SAndreas Gohr        $this->assertEquals('plus encoded query', $searchEngine->getQuery());
509364ef148SAndreas Gohr    }
510364ef148SAndreas Gohr
511364ef148SAndreas Gohr    /**
512364ef148SAndreas Gohr     * Test empty constructor behavior
513364ef148SAndreas Gohr     */
514364ef148SAndreas Gohr    public function testEmptyReferer(): void
515364ef148SAndreas Gohr    {
516364ef148SAndreas Gohr        $searchEngine = new SearchEngines('');
517364ef148SAndreas Gohr
518364ef148SAndreas Gohr        $this->assertFalse($searchEngine->isSearchEngine());
519364ef148SAndreas Gohr        $this->assertNull($searchEngine->getEngine());
520364ef148SAndreas Gohr        $this->assertNull($searchEngine->getQuery());
521364ef148SAndreas Gohr    }
522364ef148SAndreas Gohr}
523