1<?php 2/** 3 * Unit Test for inc/common.php - pageinfo() 4 * 5 * @author Christopher Smith <chris@jalakai.co.uk> 6 */ 7class common_pageinfo_test extends DokuWikiTest { 8 9 public function setup() : void { 10 parent::setup(); 11 12 global $USERINFO; 13 $USERINFO = [ 14 'pass' => '179ad45c6ce2cb97cf1029e212046e81', 15 'name' => 'Arthur Dent', 16 'mail' => 'arthur@example.com', 17 'grps' => ['admin', 'user'], 18 ]; 19 $_SERVER['REMOTE_USER'] = 'testuser'; 20 $_SERVER['REMOTE_ADDR'] = '1.2.3.4'; 21 } 22 23 protected function get_expected_pageinfo() { 24 global $USERINFO; 25 $info = [ 26 'isadmin' => true, 27 'ismanager' => true, 28 'userinfo' => $USERINFO, 29 'perm' => 255, 30 'namespace' => false, 31 'ismobile' => false, 32 'client' => 'testuser', 33 ]; 34 $info['rev'] = null; 35 $info['subscribed'] = false; 36 $info['locked'] = false; 37 $info['exists'] = false; 38 $info['writable'] = true; 39 $info['editable'] = true; 40 $info['lastmod'] = false; 41 $info['currentrev'] = false; 42 $info['meta'] = []; 43 $info['ip'] = null; 44 $info['user'] = null; 45 $info['sum'] = null; 46 $info['editor'] = null; 47 48 return $info; 49 } 50 51 /** 52 * check info keys and values for a non-existent page & admin user 53 */ 54 public function test_basic_nonexistentpage() { 55 global $ID,$conf; 56 $ID = 'wiki:start'; 57 58 $info = $this->get_expected_pageinfo(); 59 $info['id'] = 'wiki:start'; 60 $info['namespace'] = 'wiki'; 61 $info['filepath'] = $conf['datadir'].'/wiki/start.txt'; 62 63 $this->assertEquals($info, pageinfo()); 64 } 65 66 /** 67 * check info keys and values for a existing page & admin user 68 */ 69 public function test_basic_existingpage() { 70 global $ID,$conf; 71 $ID = 'wiki:syntax'; 72 $filename = $conf['datadir'].'/wiki/syntax.txt'; 73 $rev = filemtime($filename); 74 75 // pageinfo() adds the meta['last_change'] entry on first access; capture the 76 // result before reading the expected metadata so it reflects that entry 77 $result = pageinfo(); 78 79 $info = $this->get_expected_pageinfo(); 80 $info['id'] = 'wiki:syntax'; 81 $info['namespace'] = 'wiki'; 82 $info['filepath'] = $filename; 83 $info['exists'] = true; 84 $info['lastmod'] = $rev; 85 $info['currentrev'] = $rev; 86 $info['meta'] = p_get_metadata($ID); 87 // set from revinfo, $pagelog->getRevisionInfo($info['lastmod']) 88 $info = array_merge($info, [ 89 'ip' => '127.0.0.1', 90 'user' => '', 91 'sum' => 'created - external edit', 92 ]); 93 $info['editor'] = '127.0.0.1'; 94 95 $this->assertEquals($info, $result); 96 } 97 98 /** 99 * check info keys and values for anonymous user 100 */ 101 public function test_anonymoususer() { 102 global $ID,$conf,$REV; 103 104 unset($_SERVER['REMOTE_USER']); 105 global $USERINFO; $USERINFO = []; 106 107 $ID = 'wiki:syntax'; 108 $filename = $conf['datadir'].'/wiki/syntax.txt'; 109 $rev = filemtime($filename); 110 111 // pageinfo() adds the meta['last_change'] entry on first access; capture the 112 // result before building the expectation so p_get_metadata() sees that entry 113 $result = pageinfo(); 114 115 $info = $this->get_expected_pageinfo(); 116 $info['id'] = 'wiki:syntax'; 117 $info['namespace'] = 'wiki'; 118 $info['filepath'] = $filename; 119 $info['exists'] = true; 120 $info['lastmod'] = $rev; 121 $info['currentrev'] = $rev; 122 $info['meta'] = p_get_metadata($ID); 123 // set from revinfo, $pagelog->getRevisionInfo($info['lastmod']) 124 $info = array_merge($info, [ 125 'ip' => '127.0.0.1', 126 'user' => '', 127 'sum' => 'created - external edit', 128 ]); 129 $info['editor'] = '127.0.0.1'; 130 131 // anonymous user 132 $info = array_merge($info, [ 133 'isadmin' => false, 134 'ismanager' => false, 135 'perm' => 8, 136 'client' => '1.2.3.4', 137 ]); 138 unset($info['userinfo']); 139 140 $this->assertEquals($info, $result); 141 } 142 143 /** 144 * check info keys and values with $REV 145 * (also see $RANGE tests) 146 */ 147 public function test_rev() { 148 global $ID,$conf,$REV; 149 150 $ID = 'wiki:syntax'; 151 $filename = $conf['datadir'].'/wiki/syntax.txt'; 152 $rev = filemtime($filename); 153 $REV = $rev - 100; 154 $ext = '.txt'; 155 if ($conf['compression']) { 156 //compression in $info['filepath'] determined by wikiFN depends also on if the page exist 157 $ext .= "." . $conf['compression']; //.gz or .bz2 158 } 159 160 $info = $this->get_expected_pageinfo(); 161 $info['id'] = 'wiki:syntax'; 162 $info['namespace'] = 'wiki'; 163 $info['meta'] = p_get_metadata($ID); 164 $info['rev'] = $REV; 165 $info['currentrev'] = $rev; 166 $info['filepath'] = str_replace('pages','attic',substr($filename,0,-3).$REV.$ext); 167 168 $this->assertEquals($info, pageinfo()); 169 $this->assertEquals($rev-100, $REV); 170 } 171 172 /** 173 * check info keys and values with $RANGE 174 */ 175 public function test_range() { 176 global $ID,$conf,$REV,$RANGE; 177 178 $ID = 'wiki:syntax'; 179 $filename = $conf['datadir'].'/wiki/syntax.txt'; 180 $rev = filemtime($filename); 181 $range = '1000-2000'; 182 183 $info = $this->get_expected_pageinfo(); 184 $info['id'] = 'wiki:syntax'; 185 $info['namespace'] = 'wiki'; 186 $info['exists'] = true; 187 $info['lastmod'] = $rev; 188 $info['currentrev'] = $rev; 189 $info['filepath'] = $filename; 190 // set from revinfo, $pagelog->getRevisionInfo($info['lastmod']) 191 $info = array_merge($info, [ 192 'ip' => '127.0.0.1', 193 'user' => '', 194 'sum' => 'created - external edit', 195 ]); 196 $info['editor'] = '127.0.0.1'; 197 198 // check $RANGE without $REV 199 // expected result $RANGE unchanged 200 $RANGE = $range; 201 202 // pageinfo() adds the meta['last_change'] entry on first access; capture the 203 // result before reading the expected metadata so it reflects that entry 204 $result = pageinfo(); 205 $info['meta'] = p_get_metadata($ID); 206 207 $this->assertEquals($info, $result); 208 $this->assertFalse(isset($REV)); 209 $this->assertEquals($range, $RANGE); 210 211 // check $RANGE with $REV = current 212 // expected result: $RANGE unchanged, $REV cleared 213 $REV = $rev; 214 $info['rev'] = ''; 215 216 $this->assertEquals($info, pageinfo()); 217 $this->assertEquals('',$REV); 218 $this->assertEquals($range, $RANGE); 219 220 // check with a real $REV 221 // expected result: $REV and $RANGE are cleared 222 $REV = $rev - 100; 223 224 $this->assertEquals($info, pageinfo()); 225 $this->assertEquals('', $REV); 226 $this->assertEquals('', $RANGE); 227 } 228 229 /** 230 * test editor entry and external edit 231 */ 232 public function test_editor_and_externaledits() { 233 global $ID,$conf; 234 // use a dedicated page here: this test mutates the changelog and file mtime 235 // (adds a changelog entry and touch()es the file), so it must not run against 236 // wiki:syntax which the other tests rely on being pristine 237 $ID = 'wiki:dokuwiki'; 238 $filename = $conf['datadir'].'/wiki/dokuwiki.txt'; 239 $rev = filemtime($filename); 240 241 $info = $this->get_expected_pageinfo(); 242 $info['id'] = 'wiki:dokuwiki'; 243 $info['namespace'] = 'wiki'; 244 $info['filepath'] = $filename; 245 $info['exists'] = true; 246 $info['lastmod'] = $rev; 247 $info['currentrev'] = $rev; 248 $info['meta'] = p_get_metadata($ID); // need $INFO set correctly for updateMetadata() 249 250 global $INFO; 251 $INFO = $info; 252 253 // add an editor for the current version of $ID using the PageFile API 254 $pageFile = new \dokuwiki\File\PageFile($ID); 255 $logEntry = $pageFile->changelog->addLogEntry([ 256 'date' => $rev, 257 'ip' => $_SERVER['REMOTE_ADDR'], 258 'type' => DOKU_CHANGE_TYPE_EDIT, 259 'id' => $ID, 260 'user' => $_SERVER['REMOTE_USER'], 261 'sum' => '', 262 'extra' => '', 263 'sizechange' => '', 264 ]); 265 $pageFile->updateMetadata($logEntry); 266 267 $info['meta'] = p_get_metadata($ID); 268 $info['ip'] = $_SERVER['REMOTE_ADDR']; 269 $info['user'] = $_SERVER['REMOTE_USER']; 270 $info['sum'] = ''; 271 $info['editor'] = $info['user']; 272 273 // with an editor ... 274 $this->assertEquals($info, pageinfo()); 275 276 // clear the meta['last_change'] value, pageinfo should restore it 277 p_set_metadata($ID, ['last_change' => false]); 278 279 $this->assertEquals($info, pageinfo()); 280 $this->assertEquals($info['meta']['last_change'], p_get_metadata($ID,'last_change')); 281 282 // fake an external edit, pageinfo should clear the last change from meta data 283 // and not return any editor data 284 $now = time() + 10; 285 touch($filename, $now); 286 287 $info['lastmod'] = $now; 288 $info['currentrev'] = $now; 289 $info['meta']['last_change'] = false; 290 $info['ip'] = null; 291 $info['user'] = null; 292 $info['sum'] = null; 293 $info['editor'] = null; 294 295 $this->assertEquals($info, pageinfo()); 296 $this->assertEquals($info['meta'], p_get_metadata($ID)); // check metadata has been updated correctly 297 } 298 299 /** 300 * check draft 301 */ 302 public function test_draft() { 303 global $ID,$conf; 304 $ID = 'wiki:syntax'; 305 $filename = $conf['datadir'].'/wiki/syntax.txt'; 306 $rev = filemtime($filename); 307 308 $info = $this->get_expected_pageinfo(); 309 $info['id'] = 'wiki:syntax'; 310 $info['namespace'] = 'wiki'; 311 $info['filepath'] = $filename; 312 $info['exists'] = true; 313 $info['lastmod'] = $rev; 314 $info['currentrev'] = $rev; 315 // set from revinfo, $pagelog->getRevisionInfo($info['lastmod']) 316 $info = array_merge($info, [ 317 'ip' => '127.0.0.1', 318 'user' => '', 319 'sum' => 'created - external edit', 320 ]); 321 $info['editor'] = '127.0.0.1'; 322 323 // setup a draft, make it more recent than the current page 324 // - pageinfo should recognise it and keep it 325 326 $draft = getCacheName($info['client']."\n".$ID,'.draft'); 327 touch($draft, $rev + 10); 328 329 $info['draft'] = $draft; 330 331 // pageinfo() adds the meta['last_change'] entry on first access; capture the 332 // result before reading the expected metadata so it reflects that entry 333 $result = pageinfo(); 334 $info['meta'] = p_get_metadata($ID); 335 336 $this->assertEquals($info, $result); 337 $this->assertFileExists($draft); 338 339 // make the draft older than the current page 340 // - pageinfo should remove it and not return the 'draft' key 341 touch($draft,$rev - 10); 342 unset($info['draft']); 343 344 $this->assertEquals($info, pageinfo()); 345 $this->assertFalse(file_exists($draft)); 346 } 347 348 /** 349 * check ismobile 350 */ 351 public function test_ismobile() { 352 global $ID,$conf; 353 $ID = 'wiki:start'; 354 355 $info = $this->get_expected_pageinfo(); 356 $info['id'] = 'wiki:start'; 357 $info['namespace'] = 'wiki'; 358 $info['filepath'] = $conf['datadir'].'/wiki/start.txt'; 359 360 // overkill, ripped from clientismobile() as we aren't testing detection - but forcing it 361 $_SERVER['HTTP_X_WAP_PROFILE'] = 'a fake url'; 362 $_SERVER['HTTP_ACCEPT'] .= ';wap'; 363 $_SERVER['HTTP_USER_AGENT'] = 'blackberry,symbian,hand,mobi,phone'; 364 365 $info['ismobile'] = clientismobile(); 366 367 $this->assertTrue(clientismobile()); // ensure THIS test fails if clientismobile() returns false 368 $this->assertEquals($info, pageinfo()); // it would be a test failure not a pageinfo failure. 369 } 370} 371