xref: /dokuwiki/_test/tests/File/PageResolverTest.php (revision 42411fe91871199e19a856156edc4b3187205715)
198640fd3SAndreas Gohr<?php
298640fd3SAndreas Gohr
398640fd3SAndreas Gohrnamespace dokuwiki\test\File;
498640fd3SAndreas Gohr
598640fd3SAndreas Gohruse dokuwiki\File\PageResolver;
698640fd3SAndreas Gohr
798640fd3SAndreas Gohr/**
898640fd3SAndreas Gohr * @todo tests that make use of revisions might be wanted
998640fd3SAndreas Gohr */
1098640fd3SAndreas Gohrclass PageResolverTest extends \DokuWikiTest
1198640fd3SAndreas Gohr{
1298640fd3SAndreas Gohr    /**
1398640fd3SAndreas Gohr     * @return \Generator|array
1498640fd3SAndreas Gohr     * @see testResolveID
1598640fd3SAndreas Gohr     */
1698640fd3SAndreas Gohr    public function provideResolveData()
1798640fd3SAndreas Gohr    {
1898640fd3SAndreas Gohr        $data = [
1998640fd3SAndreas Gohr            // relative current in root
2098640fd3SAndreas Gohr            ['context', 'page', 'page'],
2198640fd3SAndreas Gohr            ['context', '.page', 'page'],
2298640fd3SAndreas Gohr            ['context', '.:page', 'page'],
2398640fd3SAndreas Gohr
2498640fd3SAndreas Gohr            // relative current in namespace
2598640fd3SAndreas Gohr            ['lev1:lev2:context', 'page', 'lev1:lev2:page'],
2698640fd3SAndreas Gohr            ['lev1:lev2:context', '.page', 'lev1:lev2:page'],
2798640fd3SAndreas Gohr            ['lev1:lev2:context', '.:page', 'lev1:lev2:page'],
2898640fd3SAndreas Gohr
2998640fd3SAndreas Gohr            // relative upper in root
3098640fd3SAndreas Gohr            ['context', '..page', 'page'],
3198640fd3SAndreas Gohr            ['context', '..:page', 'page'],
3298640fd3SAndreas Gohr
3398640fd3SAndreas Gohr            // relative upper in namespace
3498640fd3SAndreas Gohr            ['lev1:lev2:context', '..page', 'lev1:page'],
3598640fd3SAndreas Gohr            ['lev1:lev2:context', '..:page', 'lev1:page'],
3698640fd3SAndreas Gohr            ['lev1:lev2:context', '..:..:page', 'page'],
3798640fd3SAndreas Gohr            ['lev1:lev2:context', '..:..:..:page', 'page'],
3898640fd3SAndreas Gohr
3998640fd3SAndreas Gohr            // deeper nesting
4098640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..page', 'lev1:lev2:page'],
4198640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:page', 'lev1:lev2:page'],
4298640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..page', 'lev1:page'],
4398640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..:page', 'lev1:page'],
4498640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..:..page', 'page'],
4598640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..:..:page', 'page'],
4698640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..:..:..page', 'page'],
4798640fd3SAndreas Gohr            ['lev1:lev2:lev3:context', '..:..:..:..:page', 'page'],
4898640fd3SAndreas Gohr
4998640fd3SAndreas Gohr            // strange and broken ones
5098640fd3SAndreas Gohr            ['lev1:lev2:context', '....:....:page', 'lev1:lev2:page'],
5198640fd3SAndreas Gohr            ['lev1:lev2:context', '..:..:lev3:page', 'lev3:page'],
5298640fd3SAndreas Gohr            ['lev1:lev2:context', '..:..:lev3:..:page', 'page'],
53*42411fe9SAndreas Gohr            ['lev1:lev2:context', '..:..:lev3:..:page:....:...', 'page:start'],
5498640fd3SAndreas Gohr
5598640fd3SAndreas Gohr            // relative to current page
5698640fd3SAndreas Gohr            ['context', '~page', 'context:page'],
5798640fd3SAndreas Gohr            ['context', '~:page', 'context:page'],
5898640fd3SAndreas Gohr            ['lev1:lev2:context', '~page', 'lev1:lev2:context:page'],
5998640fd3SAndreas Gohr            ['lev1:lev2:context', '~:page', 'lev1:lev2:context:page'],
6098640fd3SAndreas Gohr
6198640fd3SAndreas Gohr            // start pages
6298640fd3SAndreas Gohr            ['context', '.:', 'start'],
6398640fd3SAndreas Gohr            ['foo:context', '.:', 'foo:start'],
6498640fd3SAndreas Gohr            ['context', 'foo:', 'foo:start'],
6598640fd3SAndreas Gohr            ['foo:context', 'foo:', 'foo:start'],
6698640fd3SAndreas Gohr            ['context', '~foo:', 'context:foo:start'],
6798640fd3SAndreas Gohr            ['foo:context', '~foo:', 'foo:context:foo:start'],
6898640fd3SAndreas Gohr
6998640fd3SAndreas Gohr            // empty page links to itself
7098640fd3SAndreas Gohr            ['context', '', 'context'],
7198640fd3SAndreas Gohr            ['foo:context', '', 'foo:context'],
72*42411fe9SAndreas Gohr
73*42411fe9SAndreas Gohr            // issue 4072
74*42411fe9SAndreas Gohr            ['context', ':..', 'start'],
75*42411fe9SAndreas Gohr            ['context', ':foo:bar:..', 'foo:bar:start'],
7698640fd3SAndreas Gohr        ];
7798640fd3SAndreas Gohr
7898640fd3SAndreas Gohr        // run each test without a hash
7998640fd3SAndreas Gohr        foreach ($data as $row) {
8098640fd3SAndreas Gohr            yield $row;
8198640fd3SAndreas Gohr        }
8298640fd3SAndreas Gohr
8398640fd3SAndreas Gohr        // run each test with a hash
8498640fd3SAndreas Gohr        foreach ($data as $row) {
8598640fd3SAndreas Gohr            $row[1] .= '#somehash';
8698640fd3SAndreas Gohr            $row[2] .= '#somehash';
8798640fd3SAndreas Gohr            yield $row;
8898640fd3SAndreas Gohr        }
8998640fd3SAndreas Gohr    }
9098640fd3SAndreas Gohr
9198640fd3SAndreas Gohr    /**
9298640fd3SAndreas Gohr     * @dataProvider provideResolveData
9398640fd3SAndreas Gohr     * @param string $context
9498640fd3SAndreas Gohr     * @param string $id
9598640fd3SAndreas Gohr     * @param string $expected
9698640fd3SAndreas Gohr     */
9798640fd3SAndreas Gohr    public function testResolveID($context, $id, $expected)
9898640fd3SAndreas Gohr    {
9998640fd3SAndreas Gohr        $resolver = new PageResolver($context);
10098640fd3SAndreas Gohr        $this->assertEquals($expected, $resolver->resolveId($id));
10198640fd3SAndreas Gohr    }
10298640fd3SAndreas Gohr
10398640fd3SAndreas Gohr    /**
104*42411fe9SAndreas Gohr     * Tilde start page behaviour
10598640fd3SAndreas Gohr     *
10698640fd3SAndreas Gohr     * Please note that a ~ alone is the same as ~:
10798640fd3SAndreas Gohr     */
10898640fd3SAndreas Gohr    public function testTildeStartPage()
10998640fd3SAndreas Gohr    {
11098640fd3SAndreas Gohr        $context = 'foo:context';
11198640fd3SAndreas Gohr        $resolver = new PageResolver($context);
11298640fd3SAndreas Gohr
11398640fd3SAndreas Gohr        // the $context page itself does not exist
11498640fd3SAndreas Gohr        // a link like that is usually not possible, but we fall back to standard start
11598640fd3SAndreas Gohr        // page behaviour
11698640fd3SAndreas Gohr        $this->assertEquals("$context:start", $resolver->resolveId('~:'));
11798640fd3SAndreas Gohr        $this->assertEquals("$context:start", $resolver->resolveId('~'));
11898640fd3SAndreas Gohr
11998640fd3SAndreas Gohr        // now $context has become the start page
12098640fd3SAndreas Gohr        saveWikiText($context, 'test', 'test');
12198640fd3SAndreas Gohr        $this->assertEquals($context, $resolver->resolveId('~:'));
12298640fd3SAndreas Gohr
12398640fd3SAndreas Gohr        // now we have a startpage named like the namespace
12498640fd3SAndreas Gohr        saveWikiText("$context:context", 'test', 'test');
12598640fd3SAndreas Gohr        $this->assertEquals("$context:context", $resolver->resolveId('~:'));
12698640fd3SAndreas Gohr        $this->assertEquals("$context:context", $resolver->resolveId('~'));
12798640fd3SAndreas Gohr
12898640fd3SAndreas Gohr        // now we have a dedicated start page
12998640fd3SAndreas Gohr        saveWikiText("$context:start", 'test', 'test');
13098640fd3SAndreas Gohr        $this->assertEquals("$context:start", $resolver->resolveId('~:'));
13198640fd3SAndreas Gohr        $this->assertEquals("$context:start", $resolver->resolveId('~'));
13298640fd3SAndreas Gohr    }
13398640fd3SAndreas Gohr
13498640fd3SAndreas Gohr    public function testResolveStartPage()
13598640fd3SAndreas Gohr    {
13698640fd3SAndreas Gohr
13798640fd3SAndreas Gohr        $resolver = new PageResolver('arbitrary');
13898640fd3SAndreas Gohr
13998640fd3SAndreas Gohr        $expect = 'foo:start';
14098640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]);
14198640fd3SAndreas Gohr        $this->assertEquals($expect, $actual, 'default non-existing');
14298640fd3SAndreas Gohr
14398640fd3SAndreas Gohr        saveWikiText('foo', 'test', 'test');
14498640fd3SAndreas Gohr        $expect = 'foo';
14598640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]);
14698640fd3SAndreas Gohr        $this->assertEquals($expect, $actual, 'page like namespace outside');
14798640fd3SAndreas Gohr
14898640fd3SAndreas Gohr        saveWikiText('foo:foo', 'test', 'test');
14998640fd3SAndreas Gohr        $expect = 'foo:foo';
15098640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]);
15198640fd3SAndreas Gohr        $this->assertEquals($expect, $actual, 'page like namespace inside');
15298640fd3SAndreas Gohr
15398640fd3SAndreas Gohr        saveWikiText('foo:start', 'test', 'test');
15498640fd3SAndreas Gohr        $expect = 'foo:start';
15598640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]);
15698640fd3SAndreas Gohr        $this->assertEquals($expect, $actual, 'default existing');
15798640fd3SAndreas Gohr    }
15898640fd3SAndreas Gohr
15998640fd3SAndreas Gohr    /**
16098640fd3SAndreas Gohr     * @return array
16198640fd3SAndreas Gohr     * @see testResolveRelatives
16298640fd3SAndreas Gohr     */
16398640fd3SAndreas Gohr    public function provideResolveRelatives()
16498640fd3SAndreas Gohr    {
16598640fd3SAndreas Gohr        return [
16698640fd3SAndreas Gohr            ['foo', 'foo'],
16798640fd3SAndreas Gohr            ['foo:bar', 'foo:bar'],
16898640fd3SAndreas Gohr            ['foo:..:bar', 'bar'],
16998640fd3SAndreas Gohr            ['foo:..:..:bar', 'bar'],
17098640fd3SAndreas Gohr            ['foo:.:bar', 'foo:bar'],
17198640fd3SAndreas Gohr            ['foo:.:..:.:bar', 'bar'],
17298640fd3SAndreas Gohr            ['foo:.:.:.:bar', 'foo:bar'],
17398640fd3SAndreas Gohr            ['foo::::bar', 'foo:bar'],
17498640fd3SAndreas Gohr            ['foo::::bar:', 'foo:bar:'],
17598640fd3SAndreas Gohr            ['foo:bar:', 'foo:bar:'],
17698640fd3SAndreas Gohr        ];
17798640fd3SAndreas Gohr    }
17898640fd3SAndreas Gohr
17998640fd3SAndreas Gohr    /**
18098640fd3SAndreas Gohr     * @dataProvider provideResolveRelatives
18198640fd3SAndreas Gohr     * @param string $input
18298640fd3SAndreas Gohr     * @param string $expected
18398640fd3SAndreas Gohr     */
18498640fd3SAndreas Gohr    public function testResolveRelatives($input, $expected)
18598640fd3SAndreas Gohr    {
18698640fd3SAndreas Gohr        $resolver = new PageResolver('arbitrary');
18798640fd3SAndreas Gohr
18898640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveRelatives', [$input]);
18998640fd3SAndreas Gohr        $this->assertEquals($expected, $actual);
19098640fd3SAndreas Gohr    }
19198640fd3SAndreas Gohr
19298640fd3SAndreas Gohr    public function testAutoPlural()
19398640fd3SAndreas Gohr    {
19498640fd3SAndreas Gohr        $resolver = new PageResolver('arbitrary');
19598640fd3SAndreas Gohr
19698640fd3SAndreas Gohr        $singular = 'some:page';
19798640fd3SAndreas Gohr        $plural = 'some:pages';
19898640fd3SAndreas Gohr
19998640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]);
20098640fd3SAndreas Gohr        $this->assertEquals($singular, $actual); // no pages exist
20198640fd3SAndreas Gohr
20298640fd3SAndreas Gohr        saveWikiText($plural, 'plural', 'plural');
20398640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]);
20498640fd3SAndreas Gohr        $this->assertEquals($plural, $actual); // plural exists
20598640fd3SAndreas Gohr
20698640fd3SAndreas Gohr        saveWikiText($singular, 'singular', 'singular');
20798640fd3SAndreas Gohr        $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]);
20898640fd3SAndreas Gohr        $this->assertEquals($singular, $actual); // requested singular has preference
20998640fd3SAndreas Gohr    }
21098640fd3SAndreas Gohr}
211