xref: /plugin/statistics/_test/SearchEnginesTest.php (revision 364ef1485a22ee5c4e8c7d7939c19319e4ba1519)
1*364ef148SAndreas Gohr<?php
2*364ef148SAndreas Gohr
3*364ef148SAndreas Gohrnamespace dokuwiki\plugin\statistics\test;
4*364ef148SAndreas Gohr
5*364ef148SAndreas Gohruse DokuWikiTest;
6*364ef148SAndreas Gohruse dokuwiki\plugin\statistics\SearchEngines;
7*364ef148SAndreas Gohr
8*364ef148SAndreas Gohr/**
9*364ef148SAndreas Gohr * Tests for the SearchEngines class
10*364ef148SAndreas Gohr *
11*364ef148SAndreas Gohr * @group plugin_statistics
12*364ef148SAndreas Gohr * @group plugins
13*364ef148SAndreas Gohr */
14*364ef148SAndreas Gohrclass SearchEnginesTest extends DokuWikiTest
15*364ef148SAndreas Gohr{
16*364ef148SAndreas Gohr    /**
17*364ef148SAndreas Gohr     * Data provider for testing known search engines
18*364ef148SAndreas Gohr     */
19*364ef148SAndreas Gohr    public function knownSearchEnginesProvider(): array
20*364ef148SAndreas Gohr    {
21*364ef148SAndreas Gohr        return [
22*364ef148SAndreas Gohr            // Google variants
23*364ef148SAndreas Gohr            'google.com' => [
24*364ef148SAndreas Gohr                'https://www.google.com/search?q=dokuwiki+test',
25*364ef148SAndreas Gohr                true,
26*364ef148SAndreas Gohr                'google',
27*364ef148SAndreas Gohr                'Google',
28*364ef148SAndreas Gohr                'dokuwiki test'
29*364ef148SAndreas Gohr            ],
30*364ef148SAndreas Gohr            'google.co.uk' => [
31*364ef148SAndreas Gohr                'https://www.google.co.uk/search?q=php+framework',
32*364ef148SAndreas Gohr                true,
33*364ef148SAndreas Gohr                'google',
34*364ef148SAndreas Gohr                'Google',
35*364ef148SAndreas Gohr                'php framework'
36*364ef148SAndreas Gohr            ],
37*364ef148SAndreas Gohr            'google.de' => [
38*364ef148SAndreas Gohr                'https://www.google.de/search?q=test+query',
39*364ef148SAndreas Gohr                true,
40*364ef148SAndreas Gohr                'google',
41*364ef148SAndreas Gohr                'Google',
42*364ef148SAndreas Gohr                'test query'
43*364ef148SAndreas Gohr            ],
44*364ef148SAndreas Gohr
45*364ef148SAndreas Gohr            // Bing
46*364ef148SAndreas Gohr            'bing.com' => [
47*364ef148SAndreas Gohr                'https://www.bing.com/search?q=dokuwiki+plugin',
48*364ef148SAndreas Gohr                true,
49*364ef148SAndreas Gohr                'bing',
50*364ef148SAndreas Gohr                'Bing',
51*364ef148SAndreas Gohr                'dokuwiki plugin'
52*364ef148SAndreas Gohr            ],
53*364ef148SAndreas Gohr            'bing.co.uk' => [
54*364ef148SAndreas Gohr                'https://www.bing.co.uk/search?q=search+test',
55*364ef148SAndreas Gohr                true,
56*364ef148SAndreas Gohr                'bing',
57*364ef148SAndreas Gohr                'Bing',
58*364ef148SAndreas Gohr                'search test'
59*364ef148SAndreas Gohr            ],
60*364ef148SAndreas Gohr
61*364ef148SAndreas Gohr            // Yahoo
62*364ef148SAndreas Gohr            'yahoo.com' => [
63*364ef148SAndreas Gohr                'https://search.yahoo.com/search?p=test+search',
64*364ef148SAndreas Gohr                true,
65*364ef148SAndreas Gohr                'yahoo',
66*364ef148SAndreas Gohr                'Yahoo!',
67*364ef148SAndreas Gohr                'test search'
68*364ef148SAndreas Gohr            ],
69*364ef148SAndreas Gohr
70*364ef148SAndreas Gohr            // Yandex
71*364ef148SAndreas Gohr            'yandex.ru' => [
72*364ef148SAndreas Gohr                'https://yandex.ru/search/?query=test+query',
73*364ef148SAndreas Gohr                true,
74*364ef148SAndreas Gohr                'yandex',
75*364ef148SAndreas Gohr                'Яндекс (Yandex)',
76*364ef148SAndreas Gohr                'test query'
77*364ef148SAndreas Gohr            ],
78*364ef148SAndreas Gohr            'yandex.com' => [
79*364ef148SAndreas Gohr                'https://yandex.com/search/?query=another+test',
80*364ef148SAndreas Gohr                true,
81*364ef148SAndreas Gohr                'yandex',
82*364ef148SAndreas Gohr                'Яндекс (Yandex)',
83*364ef148SAndreas Gohr                'another test'
84*364ef148SAndreas Gohr            ],
85*364ef148SAndreas Gohr
86*364ef148SAndreas Gohr            // Naver
87*364ef148SAndreas Gohr            'naver.com' => [
88*364ef148SAndreas Gohr                'https://search.naver.com/search.naver?query=korean+search',
89*364ef148SAndreas Gohr                true,
90*364ef148SAndreas Gohr                'naver',
91*364ef148SAndreas Gohr                '네이버 (Naver)',
92*364ef148SAndreas Gohr                'korean search'
93*364ef148SAndreas Gohr            ],
94*364ef148SAndreas Gohr
95*364ef148SAndreas Gohr            // Baidu
96*364ef148SAndreas Gohr            'baidu.com' => [
97*364ef148SAndreas Gohr                'https://www.baidu.com/s?wd=chinese+search',
98*364ef148SAndreas Gohr                true,
99*364ef148SAndreas Gohr                'baidu',
100*364ef148SAndreas Gohr                '百度 (Baidu)',
101*364ef148SAndreas Gohr                'chinese search'
102*364ef148SAndreas Gohr            ],
103*364ef148SAndreas Gohr            'baidu.com word param' => [
104*364ef148SAndreas Gohr                'https://www.baidu.com/s?word=test+word',
105*364ef148SAndreas Gohr                true,
106*364ef148SAndreas Gohr                'baidu',
107*364ef148SAndreas Gohr                '百度 (Baidu)',
108*364ef148SAndreas Gohr                'test word'
109*364ef148SAndreas Gohr            ],
110*364ef148SAndreas Gohr            'baidu.com kw param' => [
111*364ef148SAndreas Gohr                'https://www.baidu.com/s?kw=keyword+test',
112*364ef148SAndreas Gohr                true,
113*364ef148SAndreas Gohr                'baidu',
114*364ef148SAndreas Gohr                '百度 (Baidu)',
115*364ef148SAndreas Gohr                'keyword test'
116*364ef148SAndreas Gohr            ],
117*364ef148SAndreas Gohr
118*364ef148SAndreas Gohr            // Ask
119*364ef148SAndreas Gohr            'ask.com' => [
120*364ef148SAndreas Gohr                'https://www.ask.com/web?q=ask+search',
121*364ef148SAndreas Gohr                true,
122*364ef148SAndreas Gohr                'ask',
123*364ef148SAndreas Gohr                'Ask',
124*364ef148SAndreas Gohr                'ask search'
125*364ef148SAndreas Gohr            ],
126*364ef148SAndreas Gohr            'ask.com ask param' => [
127*364ef148SAndreas Gohr                'https://www.ask.com/web?ask=test+ask',
128*364ef148SAndreas Gohr                true,
129*364ef148SAndreas Gohr                'ask',
130*364ef148SAndreas Gohr                'Ask',
131*364ef148SAndreas Gohr                'test ask'
132*364ef148SAndreas Gohr            ],
133*364ef148SAndreas Gohr            'search-results.com' => [
134*364ef148SAndreas Gohr                'https://www.search-results.com/web?q=search+results',
135*364ef148SAndreas Gohr                true,
136*364ef148SAndreas Gohr                'ask_search_results',
137*364ef148SAndreas Gohr                'Ask',
138*364ef148SAndreas Gohr                'search results'
139*364ef148SAndreas Gohr            ],
140*364ef148SAndreas Gohr
141*364ef148SAndreas Gohr            // DuckDuckGo
142*364ef148SAndreas Gohr            'duckduckgo.com' => [
143*364ef148SAndreas Gohr                'https://duckduckgo.com/?q=privacy+search',
144*364ef148SAndreas Gohr                true,
145*364ef148SAndreas Gohr                'duckduckgo',
146*364ef148SAndreas Gohr                'DuckDuckGo',
147*364ef148SAndreas Gohr                'privacy search'
148*364ef148SAndreas Gohr            ],
149*364ef148SAndreas Gohr
150*364ef148SAndreas Gohr            // AOL
151*364ef148SAndreas Gohr            'aol.com' => [
152*364ef148SAndreas Gohr                'https://search.aol.com/aol/search?query=aol+search',
153*364ef148SAndreas Gohr                true,
154*364ef148SAndreas Gohr                'aol',
155*364ef148SAndreas Gohr                'AOL Search',
156*364ef148SAndreas Gohr                'aol search'
157*364ef148SAndreas Gohr            ],
158*364ef148SAndreas Gohr            'aol.co.uk' => [
159*364ef148SAndreas Gohr                'https://search.aol.co.uk/aol/search?q=uk+search',
160*364ef148SAndreas Gohr                true,
161*364ef148SAndreas Gohr                'aol',
162*364ef148SAndreas Gohr                'AOL Search',
163*364ef148SAndreas Gohr                'uk search'
164*364ef148SAndreas Gohr            ],
165*364ef148SAndreas Gohr
166*364ef148SAndreas Gohr            // Babylon
167*364ef148SAndreas Gohr            'babylon.com' => [
168*364ef148SAndreas Gohr                'https://search.babylon.com/?q=babylon+search',
169*364ef148SAndreas Gohr                true,
170*364ef148SAndreas Gohr                'babylon',
171*364ef148SAndreas Gohr                'Babylon',
172*364ef148SAndreas Gohr                'babylon search'
173*364ef148SAndreas Gohr            ],
174*364ef148SAndreas Gohr
175*364ef148SAndreas Gohr            // Google AVG
176*364ef148SAndreas Gohr            'avg.com' => [
177*364ef148SAndreas Gohr                'https://search.avg.com/search?q=avg+search',
178*364ef148SAndreas Gohr                true,
179*364ef148SAndreas Gohr                'google_avg',
180*364ef148SAndreas Gohr                'Google',
181*364ef148SAndreas Gohr                'avg search'
182*364ef148SAndreas Gohr            ],
183*364ef148SAndreas Gohr        ];
184*364ef148SAndreas Gohr    }
185*364ef148SAndreas Gohr
186*364ef148SAndreas Gohr    /**
187*364ef148SAndreas Gohr     * Data provider for testing generic search engines
188*364ef148SAndreas Gohr     */
189*364ef148SAndreas Gohr    public function genericSearchEnginesProvider(): array
190*364ef148SAndreas Gohr    {
191*364ef148SAndreas Gohr        return [
192*364ef148SAndreas Gohr            'generic with q param' => [
193*364ef148SAndreas Gohr                'https://search.example.com/?q=generic+search',
194*364ef148SAndreas Gohr                true,
195*364ef148SAndreas Gohr                'example',
196*364ef148SAndreas Gohr                'Example',
197*364ef148SAndreas Gohr                'generic search'
198*364ef148SAndreas Gohr            ],
199*364ef148SAndreas Gohr            'generic with query param' => [
200*364ef148SAndreas Gohr                'https://find.testsite.org/search?query=test+query',
201*364ef148SAndreas Gohr                true,
202*364ef148SAndreas Gohr                'testsite',
203*364ef148SAndreas Gohr                'Testsite',
204*364ef148SAndreas Gohr                'test query'
205*364ef148SAndreas Gohr            ],
206*364ef148SAndreas Gohr            'generic with search param' => [
207*364ef148SAndreas Gohr                'https://www.searchengine.net/?search=search+term',
208*364ef148SAndreas Gohr                true,
209*364ef148SAndreas Gohr                'searchengine',
210*364ef148SAndreas Gohr                'Searchengine',
211*364ef148SAndreas Gohr                'search term'
212*364ef148SAndreas Gohr            ],
213*364ef148SAndreas Gohr            'generic with keywords param' => [
214*364ef148SAndreas Gohr                'https://lookup.site.com/?keywords=keyword+test',
215*364ef148SAndreas Gohr                true,
216*364ef148SAndreas Gohr                'site',
217*364ef148SAndreas Gohr                'Site',
218*364ef148SAndreas Gohr                'keyword test'
219*364ef148SAndreas Gohr            ],
220*364ef148SAndreas Gohr            'generic with keyword param' => [
221*364ef148SAndreas Gohr                'https://engine.co.uk/?keyword=single+keyword',
222*364ef148SAndreas Gohr                true,
223*364ef148SAndreas Gohr                'engine',
224*364ef148SAndreas Gohr                'Engine',
225*364ef148SAndreas Gohr                'single keyword'
226*364ef148SAndreas Gohr            ],
227*364ef148SAndreas Gohr        ];
228*364ef148SAndreas Gohr    }
229*364ef148SAndreas Gohr
230*364ef148SAndreas Gohr    /**
231*364ef148SAndreas Gohr     * Data provider for testing non-search engine referers
232*364ef148SAndreas Gohr     */
233*364ef148SAndreas Gohr    public function nonSearchEngineProvider(): array
234*364ef148SAndreas Gohr    {
235*364ef148SAndreas Gohr        return [
236*364ef148SAndreas Gohr            'regular website' => [
237*364ef148SAndreas Gohr                'https://www.example.com/page',
238*364ef148SAndreas Gohr                false,
239*364ef148SAndreas Gohr                null,
240*364ef148SAndreas Gohr                null,
241*364ef148SAndreas Gohr                null
242*364ef148SAndreas Gohr            ],
243*364ef148SAndreas Gohr            'social media' => [
244*364ef148SAndreas Gohr                'https://www.facebook.com/share',
245*364ef148SAndreas Gohr                false,
246*364ef148SAndreas Gohr                null,
247*364ef148SAndreas Gohr                null,
248*364ef148SAndreas Gohr                null
249*364ef148SAndreas Gohr            ],
250*364ef148SAndreas Gohr            'search engine without query' => [
251*364ef148SAndreas Gohr                'https://www.google.com/',
252*364ef148SAndreas Gohr                false,
253*364ef148SAndreas Gohr                null,
254*364ef148SAndreas Gohr                null,
255*364ef148SAndreas Gohr                null
256*364ef148SAndreas Gohr            ],
257*364ef148SAndreas Gohr            'search engine with empty query' => [
258*364ef148SAndreas Gohr                'https://www.google.com/search?q=',
259*364ef148SAndreas Gohr                false,
260*364ef148SAndreas Gohr                null,
261*364ef148SAndreas Gohr                null,
262*364ef148SAndreas Gohr                null
263*364ef148SAndreas Gohr            ],
264*364ef148SAndreas Gohr            'invalid URL' => [
265*364ef148SAndreas Gohr                'not-a-url',
266*364ef148SAndreas Gohr                false,
267*364ef148SAndreas Gohr                null,
268*364ef148SAndreas Gohr                null,
269*364ef148SAndreas Gohr                null
270*364ef148SAndreas Gohr            ],
271*364ef148SAndreas Gohr            'URL without host' => [
272*364ef148SAndreas Gohr                '/local/path',
273*364ef148SAndreas Gohr                false,
274*364ef148SAndreas Gohr                null,
275*364ef148SAndreas Gohr                null,
276*364ef148SAndreas Gohr                null
277*364ef148SAndreas Gohr            ],
278*364ef148SAndreas Gohr        ];
279*364ef148SAndreas Gohr    }
280*364ef148SAndreas Gohr
281*364ef148SAndreas Gohr    /**
282*364ef148SAndreas Gohr     * Data provider for testing query cleaning
283*364ef148SAndreas Gohr     */
284*364ef148SAndreas Gohr    public function queryCleaningProvider(): array
285*364ef148SAndreas Gohr    {
286*364ef148SAndreas Gohr        return [
287*364ef148SAndreas Gohr            'cache query removed' => [
288*364ef148SAndreas Gohr                'https://www.google.com/search?q=cache:example.com+test',
289*364ef148SAndreas Gohr                true,
290*364ef148SAndreas Gohr                'google',
291*364ef148SAndreas Gohr                'Google',
292*364ef148SAndreas Gohr                'test'
293*364ef148SAndreas Gohr            ],
294*364ef148SAndreas Gohr            'related query removed' => [
295*364ef148SAndreas Gohr                'https://www.google.com/search?q=related:example.com+search',
296*364ef148SAndreas Gohr                true,
297*364ef148SAndreas Gohr                'google',
298*364ef148SAndreas Gohr                'Google',
299*364ef148SAndreas Gohr                'search'
300*364ef148SAndreas Gohr            ],
301*364ef148SAndreas Gohr            'multiple spaces compacted' => [
302*364ef148SAndreas Gohr                'https://www.google.com/search?q=test++multiple+++spaces',
303*364ef148SAndreas Gohr                true,
304*364ef148SAndreas Gohr                'google',
305*364ef148SAndreas Gohr                'Google',
306*364ef148SAndreas Gohr                'test multiple spaces'
307*364ef148SAndreas Gohr            ],
308*364ef148SAndreas Gohr            'whitespace trimmed' => [
309*364ef148SAndreas Gohr                'https://www.google.com/search?q=++trimmed++',
310*364ef148SAndreas Gohr                true,
311*364ef148SAndreas Gohr                'google',
312*364ef148SAndreas Gohr                'Google',
313*364ef148SAndreas Gohr                'trimmed'
314*364ef148SAndreas Gohr            ],
315*364ef148SAndreas Gohr        ];
316*364ef148SAndreas Gohr    }
317*364ef148SAndreas Gohr
318*364ef148SAndreas Gohr    /**
319*364ef148SAndreas Gohr     * Data provider for testing fragment-based queries
320*364ef148SAndreas Gohr     */
321*364ef148SAndreas Gohr    public function fragmentQueryProvider(): array
322*364ef148SAndreas Gohr    {
323*364ef148SAndreas Gohr        return [
324*364ef148SAndreas Gohr            'fragment query' => [
325*364ef148SAndreas Gohr                'https://www.google.com/search#q=fragment+query',
326*364ef148SAndreas Gohr                true,
327*364ef148SAndreas Gohr                'google',
328*364ef148SAndreas Gohr                'Google',
329*364ef148SAndreas Gohr                'fragment query'
330*364ef148SAndreas Gohr            ],
331*364ef148SAndreas Gohr            'fragment with multiple params' => [
332*364ef148SAndreas Gohr                'https://www.bing.com/search#q=fragment+test&other=param',
333*364ef148SAndreas Gohr                true,
334*364ef148SAndreas Gohr                'bing',
335*364ef148SAndreas Gohr                'Bing',
336*364ef148SAndreas Gohr                'fragment test'
337*364ef148SAndreas Gohr            ],
338*364ef148SAndreas Gohr        ];
339*364ef148SAndreas Gohr    }
340*364ef148SAndreas Gohr
341*364ef148SAndreas Gohr    /**
342*364ef148SAndreas Gohr     * Test known search engines
343*364ef148SAndreas Gohr     * @dataProvider knownSearchEnginesProvider
344*364ef148SAndreas Gohr     */
345*364ef148SAndreas Gohr    public function testKnownSearchEngines(
346*364ef148SAndreas Gohr        string $referer,
347*364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
348*364ef148SAndreas Gohr        ?string $expectedEngine,
349*364ef148SAndreas Gohr        ?string $expectedName,
350*364ef148SAndreas Gohr        ?string $expectedQuery
351*364ef148SAndreas Gohr    ): void {
352*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
353*364ef148SAndreas Gohr
354*364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
355*364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
356*364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
357*364ef148SAndreas Gohr
358*364ef148SAndreas Gohr        if ($expectedEngine) {
359*364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
360*364ef148SAndreas Gohr        }
361*364ef148SAndreas Gohr    }
362*364ef148SAndreas Gohr
363*364ef148SAndreas Gohr    /**
364*364ef148SAndreas Gohr     * Test generic search engines
365*364ef148SAndreas Gohr     * @dataProvider genericSearchEnginesProvider
366*364ef148SAndreas Gohr     */
367*364ef148SAndreas Gohr    public function testGenericSearchEngines(
368*364ef148SAndreas Gohr        string $referer,
369*364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
370*364ef148SAndreas Gohr        ?string $expectedEngine,
371*364ef148SAndreas Gohr        ?string $expectedName,
372*364ef148SAndreas Gohr        ?string $expectedQuery
373*364ef148SAndreas Gohr    ): void {
374*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
375*364ef148SAndreas Gohr
376*364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
377*364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
378*364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
379*364ef148SAndreas Gohr
380*364ef148SAndreas Gohr        if ($expectedEngine) {
381*364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
382*364ef148SAndreas Gohr        }
383*364ef148SAndreas Gohr    }
384*364ef148SAndreas Gohr
385*364ef148SAndreas Gohr    /**
386*364ef148SAndreas Gohr     * Test non-search engine referers
387*364ef148SAndreas Gohr     * @dataProvider nonSearchEngineProvider
388*364ef148SAndreas Gohr     */
389*364ef148SAndreas Gohr    public function testNonSearchEngines(
390*364ef148SAndreas Gohr        string $referer,
391*364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
392*364ef148SAndreas Gohr        ?string $expectedEngine,
393*364ef148SAndreas Gohr        ?string $expectedName,
394*364ef148SAndreas Gohr        ?string $expectedQuery
395*364ef148SAndreas Gohr    ): void {
396*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
397*364ef148SAndreas Gohr
398*364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
399*364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
400*364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
401*364ef148SAndreas Gohr    }
402*364ef148SAndreas Gohr
403*364ef148SAndreas Gohr    /**
404*364ef148SAndreas Gohr     * Test query cleaning functionality
405*364ef148SAndreas Gohr     * @dataProvider queryCleaningProvider
406*364ef148SAndreas Gohr     */
407*364ef148SAndreas Gohr    public function testQueryCleaning(
408*364ef148SAndreas Gohr        string $referer,
409*364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
410*364ef148SAndreas Gohr        ?string $expectedEngine,
411*364ef148SAndreas Gohr        ?string $expectedName,
412*364ef148SAndreas Gohr        ?string $expectedQuery
413*364ef148SAndreas Gohr    ): void {
414*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
415*364ef148SAndreas Gohr
416*364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
417*364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
418*364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
419*364ef148SAndreas Gohr    }
420*364ef148SAndreas Gohr
421*364ef148SAndreas Gohr    /**
422*364ef148SAndreas Gohr     * Test fragment-based queries
423*364ef148SAndreas Gohr     * @dataProvider fragmentQueryProvider
424*364ef148SAndreas Gohr     */
425*364ef148SAndreas Gohr    public function testFragmentQueries(
426*364ef148SAndreas Gohr        string $referer,
427*364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
428*364ef148SAndreas Gohr        ?string $expectedEngine,
429*364ef148SAndreas Gohr        ?string $expectedName,
430*364ef148SAndreas Gohr        ?string $expectedQuery
431*364ef148SAndreas Gohr    ): void {
432*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
433*364ef148SAndreas Gohr
434*364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
435*364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
436*364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
437*364ef148SAndreas Gohr    }
438*364ef148SAndreas Gohr
439*364ef148SAndreas Gohr    /**
440*364ef148SAndreas Gohr     * Test static getName method with unknown engine
441*364ef148SAndreas Gohr     */
442*364ef148SAndreas Gohr    public function testGetNameUnknownEngine(): void
443*364ef148SAndreas Gohr    {
444*364ef148SAndreas Gohr        $unknownEngine = 'unknown_engine';
445*364ef148SAndreas Gohr        $this->assertEquals($unknownEngine, SearchEngines::getName($unknownEngine));
446*364ef148SAndreas Gohr    }
447*364ef148SAndreas Gohr
448*364ef148SAndreas Gohr    /**
449*364ef148SAndreas Gohr     * Test static getUrl method
450*364ef148SAndreas Gohr     */
451*364ef148SAndreas Gohr    public function testGetUrl(): void
452*364ef148SAndreas Gohr    {
453*364ef148SAndreas Gohr        $this->assertEquals('http://www.google.com', SearchEngines::getUrl('google'));
454*364ef148SAndreas Gohr        $this->assertEquals('http://www.bing.com', SearchEngines::getUrl('bing'));
455*364ef148SAndreas Gohr        $this->assertNull(SearchEngines::getUrl('unknown_engine'));
456*364ef148SAndreas Gohr    }
457*364ef148SAndreas Gohr
458*364ef148SAndreas Gohr    /**
459*364ef148SAndreas Gohr     * Test DokuWiki internal search detection
460*364ef148SAndreas Gohr     */
461*364ef148SAndreas Gohr    public function testDokuWikiInternalSearch(): void
462*364ef148SAndreas Gohr    {
463*364ef148SAndreas Gohr        // Mock DOKU_URL for testing
464*364ef148SAndreas Gohr        if (!defined('DOKU_URL')) {
465*364ef148SAndreas Gohr            define('DOKU_URL', 'https://wiki.example.com/');
466*364ef148SAndreas Gohr        }
467*364ef148SAndreas Gohr
468*364ef148SAndreas Gohr        $referer = 'https://wiki.example.com/doku.php?do=search&q=internal+search';
469*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
470*364ef148SAndreas Gohr
471*364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
472*364ef148SAndreas Gohr        $this->assertEquals('dokuwiki', $searchEngine->getEngine());
473*364ef148SAndreas Gohr        $this->assertEquals('internal search', $searchEngine->getQuery());
474*364ef148SAndreas Gohr        $this->assertEquals('DokuWiki Internal Search', SearchEngines::getName('dokuwiki'));
475*364ef148SAndreas Gohr    }
476*364ef148SAndreas Gohr
477*364ef148SAndreas Gohr    /**
478*364ef148SAndreas Gohr     * Test case insensitive domain matching
479*364ef148SAndreas Gohr     */
480*364ef148SAndreas Gohr    public function testCaseInsensitiveDomainMatching(): void
481*364ef148SAndreas Gohr    {
482*364ef148SAndreas Gohr        $referer = 'https://WWW.GOOGLE.COM/search?q=case+test';
483*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
484*364ef148SAndreas Gohr
485*364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
486*364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
487*364ef148SAndreas Gohr        $this->assertEquals('case test', $searchEngine->getQuery());
488*364ef148SAndreas Gohr    }
489*364ef148SAndreas Gohr
490*364ef148SAndreas Gohr    /**
491*364ef148SAndreas Gohr     * Test URL encoding in queries
492*364ef148SAndreas Gohr     */
493*364ef148SAndreas Gohr    public function testUrlEncodedQueries(): void
494*364ef148SAndreas Gohr    {
495*364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=url%20encoded%20query';
496*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
497*364ef148SAndreas Gohr
498*364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
499*364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
500*364ef148SAndreas Gohr        $this->assertEquals('url encoded query', $searchEngine->getQuery());
501*364ef148SAndreas Gohr    }
502*364ef148SAndreas Gohr
503*364ef148SAndreas Gohr    /**
504*364ef148SAndreas Gohr     * Test plus encoding in queries
505*364ef148SAndreas Gohr     */
506*364ef148SAndreas Gohr    public function testPlusEncodedQueries(): void
507*364ef148SAndreas Gohr    {
508*364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=plus+encoded+query';
509*364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
510*364ef148SAndreas Gohr
511*364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
512*364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
513*364ef148SAndreas Gohr        $this->assertEquals('plus encoded query', $searchEngine->getQuery());
514*364ef148SAndreas Gohr    }
515*364ef148SAndreas Gohr
516*364ef148SAndreas Gohr    /**
517*364ef148SAndreas Gohr     * Test empty constructor behavior
518*364ef148SAndreas Gohr     */
519*364ef148SAndreas Gohr    public function testEmptyReferer(): void
520*364ef148SAndreas Gohr    {
521*364ef148SAndreas Gohr        $searchEngine = new SearchEngines('');
522*364ef148SAndreas Gohr
523*364ef148SAndreas Gohr        $this->assertFalse($searchEngine->isSearchEngine());
524*364ef148SAndreas Gohr        $this->assertNull($searchEngine->getEngine());
525*364ef148SAndreas Gohr        $this->assertNull($searchEngine->getQuery());
526*364ef148SAndreas Gohr    }
527*364ef148SAndreas Gohr}
528