1*98640fd3SAndreas Gohr<?php 2*98640fd3SAndreas Gohr 3*98640fd3SAndreas Gohrnamespace dokuwiki\test\File; 4*98640fd3SAndreas Gohr 5*98640fd3SAndreas Gohruse dokuwiki\File\PageResolver; 6*98640fd3SAndreas Gohr 7*98640fd3SAndreas Gohr/** 8*98640fd3SAndreas Gohr * @todo tests that make use of revisions might be wanted 9*98640fd3SAndreas Gohr */ 10*98640fd3SAndreas Gohrclass PageResolverTest extends \DokuWikiTest 11*98640fd3SAndreas Gohr{ 12*98640fd3SAndreas Gohr /** 13*98640fd3SAndreas Gohr * @return \Generator|array 14*98640fd3SAndreas Gohr * @see testResolveID 15*98640fd3SAndreas Gohr */ 16*98640fd3SAndreas Gohr public function provideResolveData() 17*98640fd3SAndreas Gohr { 18*98640fd3SAndreas Gohr $data = [ 19*98640fd3SAndreas Gohr // relative current in root 20*98640fd3SAndreas Gohr ['context', 'page', 'page'], 21*98640fd3SAndreas Gohr ['context', '.page', 'page'], 22*98640fd3SAndreas Gohr ['context', '.:page', 'page'], 23*98640fd3SAndreas Gohr 24*98640fd3SAndreas Gohr // relative current in namespace 25*98640fd3SAndreas Gohr ['lev1:lev2:context', 'page', 'lev1:lev2:page'], 26*98640fd3SAndreas Gohr ['lev1:lev2:context', '.page', 'lev1:lev2:page'], 27*98640fd3SAndreas Gohr ['lev1:lev2:context', '.:page', 'lev1:lev2:page'], 28*98640fd3SAndreas Gohr 29*98640fd3SAndreas Gohr // relative upper in root 30*98640fd3SAndreas Gohr ['context', '..page', 'page'], 31*98640fd3SAndreas Gohr ['context', '..:page', 'page'], 32*98640fd3SAndreas Gohr 33*98640fd3SAndreas Gohr // relative upper in namespace 34*98640fd3SAndreas Gohr ['lev1:lev2:context', '..page', 'lev1:page'], 35*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:page', 'lev1:page'], 36*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:..:page', 'page'], 37*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:..:..:page', 'page'], 38*98640fd3SAndreas Gohr 39*98640fd3SAndreas Gohr // deeper nesting 40*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..page', 'lev1:lev2:page'], 41*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:page', 'lev1:lev2:page'], 42*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..page', 'lev1:page'], 43*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..:page', 'lev1:page'], 44*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..:..page', 'page'], 45*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..:..:page', 'page'], 46*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..:..:..page', 'page'], 47*98640fd3SAndreas Gohr ['lev1:lev2:lev3:context', '..:..:..:..:page', 'page'], 48*98640fd3SAndreas Gohr 49*98640fd3SAndreas Gohr // strange and broken ones 50*98640fd3SAndreas Gohr ['lev1:lev2:context', '....:....:page', 'lev1:lev2:page'], 51*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:..:lev3:page', 'lev3:page'], 52*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:..:lev3:..:page', 'page'], 53*98640fd3SAndreas Gohr ['lev1:lev2:context', '..:..:lev3:..:page:....:...', 'page'], 54*98640fd3SAndreas Gohr 55*98640fd3SAndreas Gohr // relative to current page 56*98640fd3SAndreas Gohr ['context', '~page', 'context:page'], 57*98640fd3SAndreas Gohr ['context', '~:page', 'context:page'], 58*98640fd3SAndreas Gohr ['lev1:lev2:context', '~page', 'lev1:lev2:context:page'], 59*98640fd3SAndreas Gohr ['lev1:lev2:context', '~:page', 'lev1:lev2:context:page'], 60*98640fd3SAndreas Gohr 61*98640fd3SAndreas Gohr // start pages 62*98640fd3SAndreas Gohr ['context', '.:', 'start'], 63*98640fd3SAndreas Gohr ['foo:context', '.:', 'foo:start'], 64*98640fd3SAndreas Gohr ['context', 'foo:', 'foo:start'], 65*98640fd3SAndreas Gohr ['foo:context', 'foo:', 'foo:start'], 66*98640fd3SAndreas Gohr ['context', '~foo:', 'context:foo:start'], 67*98640fd3SAndreas Gohr ['foo:context', '~foo:', 'foo:context:foo:start'], 68*98640fd3SAndreas Gohr 69*98640fd3SAndreas Gohr // empty page links to itself 70*98640fd3SAndreas Gohr ['context', '', 'context'], 71*98640fd3SAndreas Gohr ['foo:context', '', 'foo:context'], 72*98640fd3SAndreas Gohr ]; 73*98640fd3SAndreas Gohr 74*98640fd3SAndreas Gohr // run each test without a hash 75*98640fd3SAndreas Gohr foreach ($data as $row) { 76*98640fd3SAndreas Gohr yield $row; 77*98640fd3SAndreas Gohr } 78*98640fd3SAndreas Gohr 79*98640fd3SAndreas Gohr // run each test with a hash 80*98640fd3SAndreas Gohr foreach ($data as $row) { 81*98640fd3SAndreas Gohr $row[1] .= '#somehash'; 82*98640fd3SAndreas Gohr $row[2] .= '#somehash'; 83*98640fd3SAndreas Gohr yield $row; 84*98640fd3SAndreas Gohr } 85*98640fd3SAndreas Gohr } 86*98640fd3SAndreas Gohr 87*98640fd3SAndreas Gohr /** 88*98640fd3SAndreas Gohr * @dataProvider provideResolveData 89*98640fd3SAndreas Gohr * @param string $context 90*98640fd3SAndreas Gohr * @param string $id 91*98640fd3SAndreas Gohr * @param string $expected 92*98640fd3SAndreas Gohr */ 93*98640fd3SAndreas Gohr public function testResolveID($context, $id, $expected) 94*98640fd3SAndreas Gohr { 95*98640fd3SAndreas Gohr $resolver = new PageResolver($context); 96*98640fd3SAndreas Gohr $this->assertEquals($expected, $resolver->resolveId($id)); 97*98640fd3SAndreas Gohr } 98*98640fd3SAndreas Gohr 99*98640fd3SAndreas Gohr /** 100*98640fd3SAndreas Gohr * Tilde start page bahaviour 101*98640fd3SAndreas Gohr * 102*98640fd3SAndreas Gohr * Please note that a ~ alone is the same as ~: 103*98640fd3SAndreas Gohr */ 104*98640fd3SAndreas Gohr public function testTildeStartPage() 105*98640fd3SAndreas Gohr { 106*98640fd3SAndreas Gohr $context = 'foo:context'; 107*98640fd3SAndreas Gohr $resolver = new PageResolver($context); 108*98640fd3SAndreas Gohr 109*98640fd3SAndreas Gohr // the $context page itself does not exist 110*98640fd3SAndreas Gohr // a link like that is usually not possible, but we fall back to standard start 111*98640fd3SAndreas Gohr // page behaviour 112*98640fd3SAndreas Gohr $this->assertEquals("$context:start", $resolver->resolveId('~:')); 113*98640fd3SAndreas Gohr $this->assertEquals("$context:start", $resolver->resolveId('~')); 114*98640fd3SAndreas Gohr 115*98640fd3SAndreas Gohr // now $context has become the start page 116*98640fd3SAndreas Gohr saveWikiText($context, 'test', 'test'); 117*98640fd3SAndreas Gohr $this->assertEquals($context, $resolver->resolveId('~:')); 118*98640fd3SAndreas Gohr 119*98640fd3SAndreas Gohr // now we have a startpage named like the namespace 120*98640fd3SAndreas Gohr saveWikiText("$context:context", 'test', 'test'); 121*98640fd3SAndreas Gohr $this->assertEquals("$context:context", $resolver->resolveId('~:')); 122*98640fd3SAndreas Gohr $this->assertEquals("$context:context", $resolver->resolveId('~')); 123*98640fd3SAndreas Gohr 124*98640fd3SAndreas Gohr // now we have a dedicated start page 125*98640fd3SAndreas Gohr saveWikiText("$context:start", 'test', 'test'); 126*98640fd3SAndreas Gohr $this->assertEquals("$context:start", $resolver->resolveId('~:')); 127*98640fd3SAndreas Gohr $this->assertEquals("$context:start", $resolver->resolveId('~')); 128*98640fd3SAndreas Gohr } 129*98640fd3SAndreas Gohr 130*98640fd3SAndreas Gohr public function testResolveStartPage() 131*98640fd3SAndreas Gohr { 132*98640fd3SAndreas Gohr 133*98640fd3SAndreas Gohr $resolver = new PageResolver('arbitrary'); 134*98640fd3SAndreas Gohr 135*98640fd3SAndreas Gohr $expect = 'foo:start'; 136*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]); 137*98640fd3SAndreas Gohr $this->assertEquals($expect, $actual, 'default non-existing'); 138*98640fd3SAndreas Gohr 139*98640fd3SAndreas Gohr saveWikiText('foo', 'test', 'test'); 140*98640fd3SAndreas Gohr $expect = 'foo'; 141*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]); 142*98640fd3SAndreas Gohr $this->assertEquals($expect, $actual, 'page like namespace outside'); 143*98640fd3SAndreas Gohr 144*98640fd3SAndreas Gohr saveWikiText('foo:foo', 'test', 'test'); 145*98640fd3SAndreas Gohr $expect = 'foo:foo'; 146*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]); 147*98640fd3SAndreas Gohr $this->assertEquals($expect, $actual, 'page like namespace inside'); 148*98640fd3SAndreas Gohr 149*98640fd3SAndreas Gohr saveWikiText('foo:start', 'test', 'test'); 150*98640fd3SAndreas Gohr $expect = 'foo:start'; 151*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveStartPage', ['foo:', false, false]); 152*98640fd3SAndreas Gohr $this->assertEquals($expect, $actual, 'default existing'); 153*98640fd3SAndreas Gohr } 154*98640fd3SAndreas Gohr 155*98640fd3SAndreas Gohr /** 156*98640fd3SAndreas Gohr * @return array 157*98640fd3SAndreas Gohr * @see testResolveRelatives 158*98640fd3SAndreas Gohr */ 159*98640fd3SAndreas Gohr public function provideResolveRelatives() 160*98640fd3SAndreas Gohr { 161*98640fd3SAndreas Gohr return [ 162*98640fd3SAndreas Gohr ['foo', 'foo'], 163*98640fd3SAndreas Gohr ['foo:bar', 'foo:bar'], 164*98640fd3SAndreas Gohr ['foo:..:bar', 'bar'], 165*98640fd3SAndreas Gohr ['foo:..:..:bar', 'bar'], 166*98640fd3SAndreas Gohr ['foo:.:bar', 'foo:bar'], 167*98640fd3SAndreas Gohr ['foo:.:..:.:bar', 'bar'], 168*98640fd3SAndreas Gohr ['foo:.:.:.:bar', 'foo:bar'], 169*98640fd3SAndreas Gohr ['foo::::bar', 'foo:bar'], 170*98640fd3SAndreas Gohr ['foo::::bar:', 'foo:bar:'], 171*98640fd3SAndreas Gohr ['foo:bar:', 'foo:bar:'], 172*98640fd3SAndreas Gohr ]; 173*98640fd3SAndreas Gohr } 174*98640fd3SAndreas Gohr 175*98640fd3SAndreas Gohr /** 176*98640fd3SAndreas Gohr * @dataProvider provideResolveRelatives 177*98640fd3SAndreas Gohr * @param string $input 178*98640fd3SAndreas Gohr * @param string $expected 179*98640fd3SAndreas Gohr */ 180*98640fd3SAndreas Gohr public function testResolveRelatives($input, $expected) 181*98640fd3SAndreas Gohr { 182*98640fd3SAndreas Gohr $resolver = new PageResolver('arbitrary'); 183*98640fd3SAndreas Gohr 184*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveRelatives', [$input]); 185*98640fd3SAndreas Gohr $this->assertEquals($expected, $actual); 186*98640fd3SAndreas Gohr } 187*98640fd3SAndreas Gohr 188*98640fd3SAndreas Gohr public function testAutoPlural() 189*98640fd3SAndreas Gohr { 190*98640fd3SAndreas Gohr $resolver = new PageResolver('arbitrary'); 191*98640fd3SAndreas Gohr 192*98640fd3SAndreas Gohr $singular = 'some:page'; 193*98640fd3SAndreas Gohr $plural = 'some:pages'; 194*98640fd3SAndreas Gohr 195*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]); 196*98640fd3SAndreas Gohr $this->assertEquals($singular, $actual); // no pages exist 197*98640fd3SAndreas Gohr 198*98640fd3SAndreas Gohr saveWikiText($plural, 'plural', 'plural'); 199*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]); 200*98640fd3SAndreas Gohr $this->assertEquals($plural, $actual); // plural exists 201*98640fd3SAndreas Gohr 202*98640fd3SAndreas Gohr saveWikiText($singular, 'singular', 'singular'); 203*98640fd3SAndreas Gohr $actual = $this->callInaccessibleMethod($resolver, 'resolveAutoPlural', [$singular, '', false]); 204*98640fd3SAndreas Gohr $this->assertEquals($singular, $actual); // requested singular has preference 205*98640fd3SAndreas Gohr } 206*98640fd3SAndreas Gohr} 207