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