xref: /plugin/statistics/_test/SearchEnginesTest.php (revision 45f4cdff9eeee357a9c7da871bb438b139ad9748)
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
150*45f4cdffSAndreas Gohr            // Ecosia
151*45f4cdffSAndreas Gohr            'ecosia.org' => [
152*45f4cdffSAndreas Gohr                'https://www.ecosia.org/search?method=index&q=eco+friendly+search',
153*45f4cdffSAndreas Gohr                true,
154*45f4cdffSAndreas Gohr                'ecosia',
155*45f4cdffSAndreas Gohr                'Ecosia',
156*45f4cdffSAndreas Gohr                'eco friendly search'
157*45f4cdffSAndreas Gohr            ],
158*45f4cdffSAndreas Gohr
159*45f4cdffSAndreas Gohr            // Qwant
160*45f4cdffSAndreas Gohr            'qwant.com' => [
161*45f4cdffSAndreas Gohr                'https://www.qwant.com/?q=dokuwiki&t=web',
162*45f4cdffSAndreas Gohr                true,
163*45f4cdffSAndreas Gohr                'qwant',
164*45f4cdffSAndreas Gohr                'Qwant',
165*45f4cdffSAndreas Gohr                'dokuwiki'
166*45f4cdffSAndreas Gohr            ],
167*45f4cdffSAndreas 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            ],
176*45f4cdffSAndreas 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
194364ef148SAndreas Gohr            // Google AVG
195364ef148SAndreas Gohr            'avg.com' => [
196364ef148SAndreas Gohr                'https://search.avg.com/search?q=avg+search',
197364ef148SAndreas Gohr                true,
198364ef148SAndreas Gohr                'google_avg',
199364ef148SAndreas Gohr                'Google',
200364ef148SAndreas Gohr                'avg search'
201364ef148SAndreas Gohr            ],
202364ef148SAndreas Gohr        ];
203364ef148SAndreas Gohr    }
204364ef148SAndreas Gohr
205364ef148SAndreas Gohr    /**
206364ef148SAndreas Gohr     * Data provider for testing generic search engines
207364ef148SAndreas Gohr     */
208364ef148SAndreas Gohr    public function genericSearchEnginesProvider(): array
209364ef148SAndreas Gohr    {
210364ef148SAndreas Gohr        return [
211364ef148SAndreas Gohr            'generic with q param' => [
212364ef148SAndreas Gohr                'https://search.example.com/?q=generic+search',
213364ef148SAndreas Gohr                true,
214364ef148SAndreas Gohr                'example',
215364ef148SAndreas Gohr                'Example',
216364ef148SAndreas Gohr                'generic search'
217364ef148SAndreas Gohr            ],
218364ef148SAndreas Gohr            'generic with query param' => [
219364ef148SAndreas Gohr                'https://find.testsite.org/search?query=test+query',
220364ef148SAndreas Gohr                true,
221364ef148SAndreas Gohr                'testsite',
222364ef148SAndreas Gohr                'Testsite',
223364ef148SAndreas Gohr                'test query'
224364ef148SAndreas Gohr            ],
225364ef148SAndreas Gohr            'generic with search param' => [
226364ef148SAndreas Gohr                'https://www.searchengine.net/?search=search+term',
227364ef148SAndreas Gohr                true,
228364ef148SAndreas Gohr                'searchengine',
229364ef148SAndreas Gohr                'Searchengine',
230364ef148SAndreas Gohr                'search term'
231364ef148SAndreas Gohr            ],
232364ef148SAndreas Gohr            'generic with keywords param' => [
233364ef148SAndreas Gohr                'https://lookup.site.com/?keywords=keyword+test',
234364ef148SAndreas Gohr                true,
235364ef148SAndreas Gohr                'site',
236364ef148SAndreas Gohr                'Site',
237364ef148SAndreas Gohr                'keyword test'
238364ef148SAndreas Gohr            ],
239364ef148SAndreas Gohr            'generic with keyword param' => [
240364ef148SAndreas Gohr                'https://engine.co.uk/?keyword=single+keyword',
241364ef148SAndreas Gohr                true,
242364ef148SAndreas Gohr                'engine',
243364ef148SAndreas Gohr                'Engine',
244364ef148SAndreas Gohr                'single keyword'
245364ef148SAndreas Gohr            ],
246364ef148SAndreas Gohr        ];
247364ef148SAndreas Gohr    }
248364ef148SAndreas Gohr
249364ef148SAndreas Gohr    /**
250364ef148SAndreas Gohr     * Data provider for testing non-search engine referers
251364ef148SAndreas Gohr     */
252364ef148SAndreas Gohr    public function nonSearchEngineProvider(): array
253364ef148SAndreas Gohr    {
254364ef148SAndreas Gohr        return [
255364ef148SAndreas Gohr            'regular website' => [
256364ef148SAndreas Gohr                'https://www.example.com/page',
257364ef148SAndreas Gohr                false,
258364ef148SAndreas Gohr                null,
259364ef148SAndreas Gohr                null,
260364ef148SAndreas Gohr                null
261364ef148SAndreas Gohr            ],
262364ef148SAndreas Gohr            'social media' => [
263364ef148SAndreas Gohr                'https://www.facebook.com/share',
264364ef148SAndreas Gohr                false,
265364ef148SAndreas Gohr                null,
266364ef148SAndreas Gohr                null,
267364ef148SAndreas Gohr                null
268364ef148SAndreas Gohr            ],
269364ef148SAndreas Gohr            'search engine without query' => [
270364ef148SAndreas Gohr                'https://www.google.com/',
271364ef148SAndreas Gohr                false,
272364ef148SAndreas Gohr                null,
273364ef148SAndreas Gohr                null,
274364ef148SAndreas Gohr                null
275364ef148SAndreas Gohr            ],
276364ef148SAndreas Gohr            'search engine with empty query' => [
277364ef148SAndreas Gohr                'https://www.google.com/search?q=',
278364ef148SAndreas Gohr                false,
279364ef148SAndreas Gohr                null,
280364ef148SAndreas Gohr                null,
281364ef148SAndreas Gohr                null
282364ef148SAndreas Gohr            ],
283364ef148SAndreas Gohr            'invalid URL' => [
284364ef148SAndreas Gohr                'not-a-url',
285364ef148SAndreas Gohr                false,
286364ef148SAndreas Gohr                null,
287364ef148SAndreas Gohr                null,
288364ef148SAndreas Gohr                null
289364ef148SAndreas Gohr            ],
290364ef148SAndreas Gohr            'URL without host' => [
291364ef148SAndreas Gohr                '/local/path',
292364ef148SAndreas Gohr                false,
293364ef148SAndreas Gohr                null,
294364ef148SAndreas Gohr                null,
295364ef148SAndreas Gohr                null
296364ef148SAndreas Gohr            ],
297364ef148SAndreas Gohr        ];
298364ef148SAndreas Gohr    }
299364ef148SAndreas Gohr
300364ef148SAndreas Gohr    /**
301364ef148SAndreas Gohr     * Data provider for testing query cleaning
302364ef148SAndreas Gohr     */
303364ef148SAndreas Gohr    public function queryCleaningProvider(): array
304364ef148SAndreas Gohr    {
305364ef148SAndreas Gohr        return [
306364ef148SAndreas Gohr            'cache query removed' => [
307364ef148SAndreas Gohr                'https://www.google.com/search?q=cache:example.com+test',
308364ef148SAndreas Gohr                true,
309364ef148SAndreas Gohr                'google',
310364ef148SAndreas Gohr                'Google',
311364ef148SAndreas Gohr                'test'
312364ef148SAndreas Gohr            ],
313364ef148SAndreas Gohr            'related query removed' => [
314364ef148SAndreas Gohr                'https://www.google.com/search?q=related:example.com+search',
315364ef148SAndreas Gohr                true,
316364ef148SAndreas Gohr                'google',
317364ef148SAndreas Gohr                'Google',
318364ef148SAndreas Gohr                'search'
319364ef148SAndreas Gohr            ],
320364ef148SAndreas Gohr            'multiple spaces compacted' => [
321364ef148SAndreas Gohr                'https://www.google.com/search?q=test++multiple+++spaces',
322364ef148SAndreas Gohr                true,
323364ef148SAndreas Gohr                'google',
324364ef148SAndreas Gohr                'Google',
325364ef148SAndreas Gohr                'test multiple spaces'
326364ef148SAndreas Gohr            ],
327364ef148SAndreas Gohr            'whitespace trimmed' => [
328364ef148SAndreas Gohr                'https://www.google.com/search?q=++trimmed++',
329364ef148SAndreas Gohr                true,
330364ef148SAndreas Gohr                'google',
331364ef148SAndreas Gohr                'Google',
332364ef148SAndreas Gohr                'trimmed'
333364ef148SAndreas Gohr            ],
334364ef148SAndreas Gohr        ];
335364ef148SAndreas Gohr    }
336364ef148SAndreas Gohr
337364ef148SAndreas Gohr    /**
338364ef148SAndreas Gohr     * Data provider for testing fragment-based queries
339364ef148SAndreas Gohr     */
340364ef148SAndreas Gohr    public function fragmentQueryProvider(): array
341364ef148SAndreas Gohr    {
342364ef148SAndreas Gohr        return [
343364ef148SAndreas Gohr            'fragment query' => [
344364ef148SAndreas Gohr                'https://www.google.com/search#q=fragment+query',
345364ef148SAndreas Gohr                true,
346364ef148SAndreas Gohr                'google',
347364ef148SAndreas Gohr                'Google',
348364ef148SAndreas Gohr                'fragment query'
349364ef148SAndreas Gohr            ],
350364ef148SAndreas Gohr            'fragment with multiple params' => [
351364ef148SAndreas Gohr                'https://www.bing.com/search#q=fragment+test&other=param',
352364ef148SAndreas Gohr                true,
353364ef148SAndreas Gohr                'bing',
354364ef148SAndreas Gohr                'Bing',
355364ef148SAndreas Gohr                'fragment test'
356364ef148SAndreas Gohr            ],
357364ef148SAndreas Gohr        ];
358364ef148SAndreas Gohr    }
359364ef148SAndreas Gohr
360364ef148SAndreas Gohr    /**
361364ef148SAndreas Gohr     * Test known search engines
362364ef148SAndreas Gohr     * @dataProvider knownSearchEnginesProvider
363364ef148SAndreas Gohr     */
364364ef148SAndreas Gohr    public function testKnownSearchEngines(
365364ef148SAndreas Gohr        string $referer,
366364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
367364ef148SAndreas Gohr        ?string $expectedEngine,
368364ef148SAndreas Gohr        ?string $expectedName,
369364ef148SAndreas Gohr        ?string $expectedQuery
370364ef148SAndreas Gohr    ): void {
371364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
372364ef148SAndreas Gohr
373364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
374364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
375364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
376364ef148SAndreas Gohr
377364ef148SAndreas Gohr        if ($expectedEngine) {
378364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
379364ef148SAndreas Gohr        }
380364ef148SAndreas Gohr    }
381364ef148SAndreas Gohr
382364ef148SAndreas Gohr    /**
383364ef148SAndreas Gohr     * Test generic search engines
384364ef148SAndreas Gohr     * @dataProvider genericSearchEnginesProvider
385364ef148SAndreas Gohr     */
386364ef148SAndreas Gohr    public function testGenericSearchEngines(
387364ef148SAndreas Gohr        string $referer,
388364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
389364ef148SAndreas Gohr        ?string $expectedEngine,
390364ef148SAndreas Gohr        ?string $expectedName,
391364ef148SAndreas Gohr        ?string $expectedQuery
392364ef148SAndreas Gohr    ): void {
393364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
394364ef148SAndreas Gohr
395364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
396364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
397364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
398364ef148SAndreas Gohr
399364ef148SAndreas Gohr        if ($expectedEngine) {
400364ef148SAndreas Gohr            $this->assertEquals($expectedName, SearchEngines::getName($expectedEngine));
401364ef148SAndreas Gohr        }
402364ef148SAndreas Gohr    }
403364ef148SAndreas Gohr
404364ef148SAndreas Gohr    /**
405364ef148SAndreas Gohr     * Test non-search engine referers
406364ef148SAndreas Gohr     * @dataProvider nonSearchEngineProvider
407364ef148SAndreas Gohr     */
408364ef148SAndreas Gohr    public function testNonSearchEngines(
409364ef148SAndreas Gohr        string $referer,
410364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
411364ef148SAndreas Gohr        ?string $expectedEngine,
412364ef148SAndreas Gohr        ?string $expectedName,
413364ef148SAndreas Gohr        ?string $expectedQuery
414364ef148SAndreas Gohr    ): void {
415364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
416364ef148SAndreas Gohr
417364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
418364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
419364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
420364ef148SAndreas Gohr    }
421364ef148SAndreas Gohr
422364ef148SAndreas Gohr    /**
423364ef148SAndreas Gohr     * Test query cleaning functionality
424364ef148SAndreas Gohr     * @dataProvider queryCleaningProvider
425364ef148SAndreas Gohr     */
426364ef148SAndreas Gohr    public function testQueryCleaning(
427364ef148SAndreas Gohr        string $referer,
428364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
429364ef148SAndreas Gohr        ?string $expectedEngine,
430364ef148SAndreas Gohr        ?string $expectedName,
431364ef148SAndreas Gohr        ?string $expectedQuery
432364ef148SAndreas Gohr    ): void {
433364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
434364ef148SAndreas Gohr
435364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
436364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
437364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
438364ef148SAndreas Gohr    }
439364ef148SAndreas Gohr
440364ef148SAndreas Gohr    /**
441364ef148SAndreas Gohr     * Test fragment-based queries
442364ef148SAndreas Gohr     * @dataProvider fragmentQueryProvider
443364ef148SAndreas Gohr     */
444364ef148SAndreas Gohr    public function testFragmentQueries(
445364ef148SAndreas Gohr        string $referer,
446364ef148SAndreas Gohr        bool $expectedIsSearchEngine,
447364ef148SAndreas Gohr        ?string $expectedEngine,
448364ef148SAndreas Gohr        ?string $expectedName,
449364ef148SAndreas Gohr        ?string $expectedQuery
450364ef148SAndreas Gohr    ): void {
451364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
452364ef148SAndreas Gohr
453364ef148SAndreas Gohr        $this->assertEquals($expectedIsSearchEngine, $searchEngine->isSearchEngine());
454364ef148SAndreas Gohr        $this->assertEquals($expectedEngine, $searchEngine->getEngine());
455364ef148SAndreas Gohr        $this->assertEquals($expectedQuery, $searchEngine->getQuery());
456364ef148SAndreas Gohr    }
457364ef148SAndreas Gohr
458364ef148SAndreas Gohr    /**
459364ef148SAndreas Gohr     * Test static getName method with unknown engine
460364ef148SAndreas Gohr     */
461364ef148SAndreas Gohr    public function testGetNameUnknownEngine(): void
462364ef148SAndreas Gohr    {
463364ef148SAndreas Gohr        $unknownEngine = 'unknown_engine';
464c428ec28SAndreas Gohr        $this->assertEquals('Unknown_engine', SearchEngines::getName($unknownEngine));
465364ef148SAndreas Gohr    }
466364ef148SAndreas Gohr
467364ef148SAndreas Gohr    /**
468364ef148SAndreas Gohr     * Test static getUrl method
469364ef148SAndreas Gohr     */
470364ef148SAndreas Gohr    public function testGetUrl(): void
471364ef148SAndreas Gohr    {
472364ef148SAndreas Gohr        $this->assertEquals('http://www.google.com', SearchEngines::getUrl('google'));
473364ef148SAndreas Gohr        $this->assertEquals('http://www.bing.com', SearchEngines::getUrl('bing'));
474364ef148SAndreas Gohr        $this->assertNull(SearchEngines::getUrl('unknown_engine'));
475364ef148SAndreas Gohr    }
476364ef148SAndreas Gohr
477364ef148SAndreas Gohr    /**
478364ef148SAndreas Gohr     * Test DokuWiki internal search detection
479364ef148SAndreas Gohr     */
480364ef148SAndreas Gohr    public function testDokuWikiInternalSearch(): void
481364ef148SAndreas Gohr    {
482364ef148SAndreas Gohr        // Mock DOKU_URL for testing
483364ef148SAndreas Gohr        if (!defined('DOKU_URL')) {
484364ef148SAndreas Gohr            define('DOKU_URL', 'https://wiki.example.com/');
485364ef148SAndreas Gohr        }
486364ef148SAndreas Gohr
487364ef148SAndreas Gohr        $referer = 'https://wiki.example.com/doku.php?do=search&q=internal+search';
488364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
489364ef148SAndreas Gohr
490364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
491364ef148SAndreas Gohr        $this->assertEquals('dokuwiki', $searchEngine->getEngine());
492364ef148SAndreas Gohr        $this->assertEquals('internal search', $searchEngine->getQuery());
493364ef148SAndreas Gohr        $this->assertEquals('DokuWiki Internal Search', SearchEngines::getName('dokuwiki'));
494364ef148SAndreas Gohr    }
495364ef148SAndreas Gohr
496364ef148SAndreas Gohr    /**
497364ef148SAndreas Gohr     * Test case insensitive domain matching
498364ef148SAndreas Gohr     */
499364ef148SAndreas Gohr    public function testCaseInsensitiveDomainMatching(): void
500364ef148SAndreas Gohr    {
501364ef148SAndreas Gohr        $referer = 'https://WWW.GOOGLE.COM/search?q=case+test';
502364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
503364ef148SAndreas Gohr
504364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
505364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
506364ef148SAndreas Gohr        $this->assertEquals('case test', $searchEngine->getQuery());
507364ef148SAndreas Gohr    }
508364ef148SAndreas Gohr
509364ef148SAndreas Gohr    /**
510364ef148SAndreas Gohr     * Test URL encoding in queries
511364ef148SAndreas Gohr     */
512364ef148SAndreas Gohr    public function testUrlEncodedQueries(): void
513364ef148SAndreas Gohr    {
514364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=url%20encoded%20query';
515364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
516364ef148SAndreas Gohr
517364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
518364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
519364ef148SAndreas Gohr        $this->assertEquals('url encoded query', $searchEngine->getQuery());
520364ef148SAndreas Gohr    }
521364ef148SAndreas Gohr
522364ef148SAndreas Gohr    /**
523364ef148SAndreas Gohr     * Test plus encoding in queries
524364ef148SAndreas Gohr     */
525364ef148SAndreas Gohr    public function testPlusEncodedQueries(): void
526364ef148SAndreas Gohr    {
527364ef148SAndreas Gohr        $referer = 'https://www.google.com/search?q=plus+encoded+query';
528364ef148SAndreas Gohr        $searchEngine = new SearchEngines($referer);
529364ef148SAndreas Gohr
530364ef148SAndreas Gohr        $this->assertTrue($searchEngine->isSearchEngine());
531364ef148SAndreas Gohr        $this->assertEquals('google', $searchEngine->getEngine());
532364ef148SAndreas Gohr        $this->assertEquals('plus encoded query', $searchEngine->getQuery());
533364ef148SAndreas Gohr    }
534364ef148SAndreas Gohr
535364ef148SAndreas Gohr    /**
536364ef148SAndreas Gohr     * Test empty constructor behavior
537364ef148SAndreas Gohr     */
538364ef148SAndreas Gohr    public function testEmptyReferer(): void
539364ef148SAndreas Gohr    {
540364ef148SAndreas Gohr        $searchEngine = new SearchEngines('');
541364ef148SAndreas Gohr
542364ef148SAndreas Gohr        $this->assertFalse($searchEngine->isSearchEngine());
543364ef148SAndreas Gohr        $this->assertNull($searchEngine->getEngine());
544364ef148SAndreas Gohr        $this->assertNull($searchEngine->getQuery());
545364ef148SAndreas Gohr    }
546364ef148SAndreas Gohr}
547