xref: /plugin/farmer/_test/core.test.php (revision c609f1dcc91a56df760d51ba92f6e25b7289002c)
1<?php
2
3namespace plugin\farmer\test;
4
5require_once(__DIR__ . '/../DokuWikiFarmCore.php');
6
7class DokuWikiFarmCore extends \DokuWikiFarmCore
8{
9    /** @noinspection PhpMissingParentConstructorInspection */
10    public function __construct()
11    {
12        $this->loadConfig();
13        // we do not intitialize anyting else here because it's already too late and DOKU_INC is already set
14    }
15
16    public function getAnimalNamesForHost($host)
17    {
18        return parent::getAnimalNamesForHost($host);
19    }
20
21    public function detectAnimal($sapi = null)
22    {
23        parent::detectAnimal($sapi);
24    }
25
26    public function setConfig($config)
27    {
28        $this->config = $config;
29    }
30
31    public function getAnimal()
32    {
33        return $this->animal;
34    }
35
36    public function wasNotfound()
37    {
38        return $this->notfound;
39    }
40
41    public function isHostbased()
42    {
43        return $this->hostbased;
44    }
45
46    public function resetState()
47    {
48        $this->animal = false;
49        $this->notfound = false;
50        $this->hostbased = false;
51    }
52
53    public function injectServerEnvironment(array $urlparts)
54    {
55        parent::injectServerEnvironment($urlparts);
56    }
57}
58
59
60/**
61 * @group plugin_farmer
62 * @group plugins
63 */
64class core_plugin_farmer_test extends \DokuWikiTest
65{
66
67    protected $pluginsEnabled = ['farmer'];
68
69
70    /**
71     * Test the getAnimalNamesForHost method
72     */
73    public function test_hostsAnimals()
74    {
75        $core = new DokuWikiFarmCore();
76
77        $input = 'www.foobar.example.com:8000';
78        $expect = [
79            'www.foobar.example.com.8000',
80            'foobar.example.com.8000',
81            'www.foobar.example.com',
82            'foobar.example.com',
83            'www.foobar.example',
84            'foobar.example',
85            'www.foobar',
86            'foobar',
87            'www',
88        ];
89
90        $this->assertEquals($expect, $core->getAnimalNamesForHost($input));
91    }
92
93    /**
94     * Data provider for detectAnimal tests
95     */
96    public function detectAnimalProvider()
97    {
98        return [
99            'animal via GET parameter - exists' => [
100                'get_params' => ['animal' => 'testanimal'],
101                'server_params' => [],
102                'sapi' => 'apache2handler',
103                'expected_animal' => 'testanimal',
104                'expected_notfound' => false,
105                'expected_hostbased' => false,
106                'create_dirs' => ['/tmp/farm/testanimal/conf'],
107            ],
108            'animal via GET parameter - not found' => [
109                'get_params' => ['animal' => 'nonexistent'],
110                'server_params' => [],
111                'sapi' => 'apache2handler',
112                'expected_animal' => false,
113                'expected_notfound' => true,
114                'expected_hostbased' => false,
115            ],
116            'animal via GET parameter - invalid path' => [
117                'get_params' => ['animal' => '../badpath'],
118                'server_params' => [],
119                'sapi' => 'apache2handler',
120                'expected_animal' => false,
121                'expected_notfound' => true,
122                'expected_hostbased' => false,
123            ],
124            'farmer host' => [
125                'get_params' => [],
126                'server_params' => ['HTTP_HOST' => 'farm.example.com'],
127                'sapi' => 'apache2handler',
128                'expected_animal' => false,
129                'expected_notfound' => false,
130                'expected_hostbased' => false,
131            ],
132            'host-based animal - exists' => [
133                'get_params' => [],
134                'server_params' => ['HTTP_HOST' => 'sub.example.com'],
135                'sapi' => 'apache2handler',
136                'expected_animal' => 'sub.example.com',
137                'expected_notfound' => false,
138                'expected_hostbased' => true,
139                'create_dirs' => ['/tmp/farm/sub.example.com/conf'],
140            ],
141            'host-based animal - not found' => [
142                'get_params' => [],
143                'server_params' => ['HTTP_HOST' => 'unknown.example.com'],
144                'sapi' => 'apache2handler',
145                'expected_animal' => false,
146                'expected_notfound' => true,
147                'expected_hostbased' => true,
148            ],
149            'CLI animal parameter - name only' => [
150                'get_params' => [],
151                'server_params' => ['animal' => 'clianimal'],
152                'sapi' => 'cli',
153                'expected_animal' => 'clianimal',
154                'expected_notfound' => false,
155                'expected_hostbased' => false,
156                'create_dirs' => ['/tmp/farm/clianimal/conf'],
157            ],
158            'CLI animal parameter - URL with query' => [
159                'get_params' => [],
160                'server_params' => ['animal' => 'https://example.com/path?animal=urlanimal&other=param'],
161                'sapi' => 'cli',
162                'expected_animal' => 'urlanimal',
163                'expected_notfound' => false,
164                'expected_hostbased' => false,
165                'create_dirs' => ['/tmp/farm/urlanimal/conf'],
166            ],
167            'CLI animal parameter - URL with bang path' => [
168                'get_params' => [],
169                'server_params' => ['animal' => 'https://example.com/!banganimal/page'],
170                'sapi' => 'cli',
171                'expected_animal' => 'banganimal',
172                'expected_notfound' => false,
173                'expected_hostbased' => false,
174                'create_dirs' => ['/tmp/farm/banganimal/conf'],
175            ],
176            'CLI animal parameter - URL with bang path in subdir' => [
177                'get_params' => [],
178                'server_params' => ['animal' => 'https://example.com/dokuwiki/!banganimal/page'],
179                'sapi' => 'cli',
180                'expected_animal' => 'banganimal',
181                'expected_notfound' => false,
182                'expected_hostbased' => false,
183                'create_dirs' => ['/tmp/farm/banganimal/conf'],
184            ],
185            'CLI animal parameter - URL with hostname' => [
186                'get_params' => [],
187                'server_params' => ['animal' => 'https://hostanimal.example.com/page'],
188                'sapi' => 'cli',
189                'expected_animal' => 'hostanimal.example.com',
190                'expected_notfound' => false,
191                'expected_hostbased' => true,
192                'create_dirs' => ['/tmp/farm/hostanimal.example.com/conf'],
193            ],
194            'CLI no animal parameter' => [
195                'get_params' => [],
196                'server_params' => [],
197                'sapi' => 'cli',
198                'expected_animal' => false,
199                'expected_notfound' => false,
200                'expected_hostbased' => false,
201            ],
202            'CLI animal parameter - URL with bang and query' => [
203                'get_params' => [],
204                'server_params' => ['animal' => 'https://example.com/!bangquery/page?param=value'],
205                'sapi' => 'cli',
206                'expected_animal' => 'bangquery',
207                'expected_notfound' => false,
208                'expected_hostbased' => false,
209                'create_dirs' => ['/tmp/farm/bangquery/conf'],
210            ],
211            'HTTP no host header' => [
212                'get_params' => [],
213                'server_params' => ['HTTP_HOST' => ''], // our test environment sets one
214                'sapi' => 'apache2handler',
215                'expected_animal' => false,
216                'expected_notfound' => false,
217                'expected_hostbased' => false,
218            ],
219        ];
220    }
221
222    /**
223     * @dataProvider detectAnimalProvider
224     * @param array $get_params GET parameters to set in $_GET
225     * @param array $server_params SERVER parameters to set in $_SERVER
226     * @param string $sapi SAPI to simulate
227     * @param string|false $expected_animal Expected animal name or false
228     * @param bool $expected_notfound Expected notfound state
229     * @param bool $expected_hostbased Expected hostbased state
230     * @param array $create_dirs Directories to create for the test
231     */
232    public function test_detectAnimal($get_params, $server_params, $sapi, $expected_animal, $expected_notfound, $expected_hostbased, $create_dirs = [])
233    {
234        // Create temporary directories if needed
235        foreach ($create_dirs as $dir) {
236            if (!is_dir($dir)) {
237                mkdir($dir, 0755, true);
238            }
239        }
240
241        // Backup original values
242        $original_get = $_GET;
243        $original_server = $_SERVER;
244        $original_query_string = $_SERVER['QUERY_STRING'] ?? '';
245
246        try {
247            // Set up test environment
248            $_GET = array_merge($_GET, $get_params);
249            $_SERVER = array_merge($_SERVER, $server_params);
250            if (!empty($get_params)) {
251                $_SERVER['QUERY_STRING'] = http_build_query($get_params);
252            }
253
254            $config = ['base' => ['farmdir' => '/tmp/farm', 'farmhost' => 'farm.example.com']];
255            $core = new DokuWikiFarmCore();
256            $core->setConfig($config);
257            $core->resetState();
258            $core->detectAnimal($sapi);
259
260            $this->assertEquals($expected_animal, $core->getAnimal(), 'Animal detection failed');
261            $this->assertEquals($expected_notfound, $core->wasNotfound(), 'Notfound state incorrect');
262            $this->assertEquals($expected_hostbased, $core->isHostbased(), 'Hostbased state incorrect');
263
264        } finally {
265            // Restore original values
266            $_GET = $original_get;
267            $_SERVER = $original_server;
268            $_SERVER['QUERY_STRING'] = $original_query_string;
269
270            // Clean up created directories
271            foreach ($create_dirs as $dir) {
272                if (is_dir($dir)) {
273                    rmdir($dir);
274                    // Also remove parent directories if they're empty
275                    $parent = dirname($dir);
276                    while ($parent !== '/' && $parent !== '.' && is_dir($parent) && count(scandir($parent)) === 2) {
277                        rmdir($parent);
278                        $parent = dirname($parent);
279                    }
280                }
281            }
282        }
283    }
284
285    /**
286     * Data provider for injectServerEnvironment tests
287     */
288    public function injectServerEnvironmentProvider()
289    {
290        return [
291            'HTTPS URL with port' => [
292                'url' => 'https://example.com:8443/dokuwiki/doku.php',
293                'expected_baseurl' => 'https://example.com:8443',
294                'expected_basedir' => '/dokuwiki/',
295            ],
296            'HTTP URL with default port' => [
297                'url' => 'http://test.example.com/doku.php',
298                'expected_baseurl' => 'http://test.example.com',
299                'expected_basedir' => '/',
300            ],
301            'HTTPS URL with bang path' => [
302                'url' => 'https://farm.example.com/!animal/doku.php',
303                'expected_baseurl' => 'https://farm.example.com',
304                'expected_basedir' => '/',
305            ],
306            'HTTP URL with subdirectory and bang path' => [
307                'url' => 'http://wiki.example.com/dokuwiki/!testanimal/start',
308                'expected_baseurl' => 'http://wiki.example.com',
309                'expected_basedir' => '/dokuwiki/',
310            ],
311            'HTTPS URL with custom port and path' => [
312                'url' => 'https://secure.example.com:9443/wiki',
313                'expected_baseurl' => 'https://secure.example.com:9443',
314                'expected_basedir' => '/wiki/',
315            ],
316            'HTTP URL with root path' => [
317                'url' => 'http://simple.example.com/',
318                'expected_baseurl' => 'http://simple.example.com',
319                'expected_basedir' => '/',
320            ],
321            'HTTP URL with no path' => [
322                'url' => 'http://simple.example.com',
323                'expected_baseurl' => 'http://simple.example.com',
324                'expected_basedir' => '/',
325            ],
326        ];
327    }
328
329    /**
330     * @dataProvider injectServerEnvironmentProvider
331     * @param string $url The URL to parse and inject
332     * @param string $expected_baseurl Expected base URL after injection
333     * @param string $expected_basedir Expected base directory after injection
334     */
335    public function test_injectServerEnvironment($url, $expected_baseurl, $expected_basedir)
336    {
337        // Clear relevant server variables
338        unset($_SERVER['HTTPS'], $_SERVER['HTTP_HOST'], $_SERVER['SCRIPT_NAME']);
339
340        $core = new DokuWikiFarmCore();
341        $urlparts = parse_url($url);
342        $core->injectServerEnvironment($urlparts);
343
344        $base_dir = getBaseURL(false);
345        $base_url = getBaseURL(true);
346
347        // first check that the directory was detected correctly…
348        $this->assertEquals($expected_basedir, $base_dir, 'Base directory does not match expected value');
349        // …then check that the expected base URL plus the directory matches the absolute URL
350        $this->assertEquals($expected_baseurl . $base_dir, $base_url, 'Absolute URL does not match expected value');
351
352
353    }
354}
355