1<?php 2 3use dokuwiki\ChangeLog\PageChangeLog; 4 5class common_saveWikiText_test extends DokuWikiTest { 6 /** Delay writes of old revisions by a second. */ 7 public function handle_write(Doku_Event $event, $param) { 8 if ($event->data[3] !== false) { 9 $this->waitForTick(); 10 } 11 } 12 13 /** 14 * Execute a whole bunch of saves on the same page and check the results 15 */ 16 function test_savesequence() { 17 global $REV; 18 19 $page = 'page'; 20 $file = wikiFN($page); 21 22 // create the page 23 $this->assertFileNotExists($file); 24 saveWikiText($page, 'teststring', 'first save', false); 25 $this->assertFileExists($file); 26 $lastmod = filemtime($file); 27 28 $pagelog = new PageChangeLog($page); 29 $revisions = $pagelog->getRevisions(-1, 200); 30 $this->assertEquals(1, count($revisions)); 31 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 32 $this->assertEquals('first save', $revinfo['sum']); 33 $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']); 34 $this->assertEquals(10, $revinfo['sizechange']); 35 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 36 37 $this->waitForTick(true); // wait for new revision ID 38 39 // save with same content should be ignored 40 saveWikiText($page, 'teststring', 'second save', false); 41 clearstatcache(false, $file); 42 $this->assertEquals($lastmod, filemtime($file)); 43 44 $pagelog = new PageChangeLog($page); 45 $revisions = $pagelog->getRevisions(-1, 200); 46 $this->assertEquals(1, count($revisions)); 47 48 // update the page with new text 49 saveWikiText($page, 'teststring2long', 'third save', false); 50 clearstatcache(false, $file); 51 $newmod = filemtime($file); 52 $this->assertNotEquals($lastmod, $newmod); 53 $lastmod = $newmod; 54 55 $pagelog = new PageChangeLog($page); 56 $revisions = $pagelog->getRevisions(-1, 200); 57 $this->assertEquals(2, count($revisions)); 58 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 59 $this->assertEquals('third save', $revinfo['sum']); 60 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 61 $this->assertEquals(5, $revinfo['sizechange']); 62 63 $this->waitForTick(); // wait for new revision ID 64 65 // add a minor edit (unauthenticated) 66 saveWikiText($page, 'teststring3long', 'fourth save', true); 67 clearstatcache(false, $file); 68 $newmod = filemtime($file); 69 $this->assertNotEquals($lastmod, $newmod); 70 $lastmod = $newmod; 71 72 $pagelog = new PageChangeLog($page); 73 $revisions = $pagelog->getRevisions(-1, 200); 74 $this->assertEquals(3, count($revisions)); 75 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 76 $this->assertEquals('fourth save', $revinfo['sum']); 77 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 78 $this->assertEquals(0, $revinfo['sizechange']); 79 80 $this->waitForTick(); // wait for new revision ID 81 82 // add a minor edit (authenticated) 83 $_SERVER['REMOTE_USER'] = 'user'; 84 saveWikiText($page, 'teststring4', 'fifth save', true); 85 clearstatcache(false, $file); 86 $newmod = filemtime($file); 87 $this->assertNotEquals($lastmod, $newmod); 88 $lastmod = $newmod; 89 90 $pagelog = new PageChangeLog($page); 91 $revisions = $pagelog->getRevisions(-1, 200); 92 $this->assertEquals(4, count($revisions)); 93 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 94 $this->assertEquals('fifth save', $revinfo['sum']); 95 $this->assertEquals(DOKU_CHANGE_TYPE_MINOR_EDIT, $revinfo['type']); 96 $this->assertEquals(-4, $revinfo['sizechange']); 97 98 $this->waitForTick(); // wait for new revision ID 99 100 // delete 101 saveWikiText($page, '', 'sixth save', false); 102 clearstatcache(false, $file); 103 $this->assertFileNotExists($file); 104 105 $pagelog = new PageChangeLog($page); 106 $revisions = $pagelog->getRevisions(-1, 200); 107 $this->assertEquals(5, count($revisions)); 108 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 109 $this->assertEquals('sixth save', $revinfo['sum']); 110 $this->assertEquals(DOKU_CHANGE_TYPE_DELETE, $revinfo['type']); 111 $this->assertEquals(-11, $revinfo['sizechange']); 112 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 113 114 $this->waitForTick(); // wait for new revision ID 115 116 // restore 117 $REV = $lastmod; 118 saveWikiText($page, 'teststring4', 'seventh save', true); 119 clearstatcache(false, $file); 120 $this->assertFileExists($file); 121 $newmod = filemtime($file); 122 $this->assertNotEquals($lastmod, $newmod); 123 $lastmod = $newmod; 124 125 $pagelog = new PageChangeLog($page); 126 $revisions = $pagelog->getRevisions(-1, 200); 127 $this->assertEquals(6, count($revisions)); 128 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 129 $this->assertEquals('seventh save', $revinfo['sum']); 130 $this->assertEquals(DOKU_CHANGE_TYPE_REVERT, $revinfo['type']); 131 $this->assertEquals($REV, $revinfo['extra']); 132 $this->assertEquals(11, $revinfo['sizechange']); 133 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 134 $REV = ''; 135 136 $this->waitForTick(); // wait for new revision ID 137 138 // create external edit 139 file_put_contents($file, 'teststring5'); 140 141 $this->waitForTick(); // wait for new revision ID 142 143 // save on top of external edit 144 saveWikiText($page, 'teststring6', 'eigth save', false); 145 clearstatcache(false, $file); 146 $newmod = filemtime($file); 147 $this->assertNotEquals($lastmod, $newmod); 148 $lastmod = $newmod; 149 150 $pagelog = new PageChangeLog($page); 151 $revisions = $pagelog->getRevisions(-1, 200); 152 $this->assertEquals(8, count($revisions)); // two more revisions now! 153 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 154 $this->assertEquals('eigth save', $revinfo['sum']); 155 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 156 $this->assertEquals(0, $revinfo['sizechange']); 157 158 $revinfo = $pagelog->getRevisionInfo($revisions[1]); 159 $this->assertEquals('external edit', $revinfo['sum']); 160 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 161 $this->assertEquals(0, $revinfo['sizechange']); 162 163 } 164 165 /** 166 * Execute a whole bunch of saves on the same page and check the results 167 */ 168 function test_savesequencedeleteexternalrevision() { 169 // add an additional delay when saving files to make sure 170 // nobody relies on the saving happening in the same second 171 /** @var $EVENT_HANDLER \dokuwiki\Extension\EventHandler */ 172 global $EVENT_HANDLER; 173 $EVENT_HANDLER->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'handle_write'); 174 175 $page = 'page2'; 176 $file = wikiFN($page); 177 178 // create the page 179 $this->assertFileNotExists($file); 180 saveWikiText($page, 'teststring', 'first save', false); 181 $this->assertFileExists($file); 182 $lastmod = filemtime($file); 183 184 $pagelog = new PageChangeLog($page); 185 $revisions = $pagelog->getRevisions(-1, 200); 186 $this->assertEquals(1, count($revisions)); 187 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 188 $this->assertEquals('first save', $revinfo['sum']); 189 $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']); 190 $this->assertEquals(10, $revinfo['sizechange']); 191 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 192 193 $this->waitForTick(true); // wait for new revision ID 194 195 // delete 196 saveWikiText($page, '', 'second save', false); 197 clearstatcache(false, $file); 198 $this->assertFileNotExists($file); 199 200 $pagelog = new PageChangeLog($page); 201 $revisions = $pagelog->getRevisions(-1, 200); 202 $this->assertEquals(2, count($revisions)); 203 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 204 $this->assertEquals('second save', $revinfo['sum']); 205 $this->assertEquals(DOKU_CHANGE_TYPE_DELETE, $revinfo['type']); 206 $this->assertEquals(-10, $revinfo['sizechange']); 207 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 208 209 $this->waitForTick(); // wait for new revision ID 210 211 // create external edit 212 file_put_contents($file, 'teststring5'); 213 214 $this->waitForTick(); // wait for new revision ID 215 216 // save on top of external edit 217 saveWikiText($page, 'teststring6', 'third save', false); 218 clearstatcache(false, $file); 219 220 $pagelog = new PageChangeLog($page); 221 $revisions = $pagelog->getRevisions(-1, 200); 222 $this->assertEquals(4, count($revisions)); // two more revisions now! 223 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 224 $this->assertEquals('third save', $revinfo['sum']); 225 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 226 $this->assertEquals(0, $revinfo['sizechange']); 227 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 228 229 $revinfo = $pagelog->getRevisionInfo($revisions[1]); 230 $this->assertEquals('external edit', $revinfo['sum']); 231 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 232 $this->assertEquals(11, $revinfo['sizechange']); 233 $this->assertFileExists(wikiFN($page, $revinfo['date'])); 234 235 } 236 237 /** 238 * Execute a whole bunch of saves on the same page and check the results 239 */ 240 function test_saveexternalasfirst() { 241 $page = 'page3'; 242 $file = wikiFN($page); 243 244 // create the page 245 $this->assertFileNotExists($file); 246 247 // create external edit 248 file_put_contents($file, 'teststring'); 249 250 $this->waitForTick(true); // wait for new revision ID 251 252 // save on top of external edit 253 saveWikiText($page, 'teststring6', 'first save', false); 254 clearstatcache(false, $file); 255 256 $pagelog = new PageChangeLog($page); 257 $revisions = $pagelog->getRevisions(-1, 200); 258 $this->assertEquals(2, count($revisions)); // two more revisions now! 259 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 260 $this->assertEquals('first save', $revinfo['sum']); 261 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 262 $this->assertEquals(1, $revinfo['sizechange']); 263 264 $revinfo = $pagelog->getRevisionInfo($revisions[1]); 265 $this->assertEquals('external edit', $revinfo['sum']); 266 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 267 $this->assertEquals(10, $revinfo['sizechange']); 268 269 } 270 271 /** 272 * Execute a whole bunch of saves on the same page and check the results 273 */ 274 function test_savesequenceexternaldeleteedit() { 275 $page = 'page4'; 276 $file = wikiFN($page); 277 278 // create the page 279 $this->assertFileNotExists($file); 280 saveWikiText($page, 'teststring', 'first save', false); 281 $this->assertFileExists($file); 282 $lastmod = filemtime($file); 283 284 $pagelog = new PageChangeLog($page); 285 $revisions = $pagelog->getRevisions(-1, 200); 286 $this->assertEquals(1, count($revisions)); 287 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 288 $this->assertEquals('first save', $revinfo['sum']); 289 $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']); 290 $this->assertEquals(10, $revinfo['sizechange']); 291 292 $this->waitForTick(true); // wait for new revision ID 293 294 295 // create external delete 296 unlink($file); 297 clearstatcache(false, $file); 298 299 $this->waitForTick(); // wait for new revision ID 300 301 // save on top of external delete. save is seen as creation 302 saveWikiText($page, 'teststring6', 'second save', false); 303 clearstatcache(false, $file); 304 305 $pagelog = new PageChangeLog($page); 306 $revisions = $pagelog->getRevisions(-1, 200); 307 $this->assertEquals(2, count($revisions)); // one more revisions now! 308 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 309 $this->assertEquals('second save', $revinfo['sum']); 310 $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']); 311 $this->assertEquals(11, $revinfo['sizechange']); 312 313 $revinfo = $pagelog->getRevisionInfo($revisions[1]); 314 $this->assertEquals('first save', $revinfo['sum']); 315 316 } 317 318 /** 319 * Execute a whole bunch of saves on the same page and check the results 320 */ 321 function test_savesequencerevert() { 322 global $REV; 323 324 $page = 'page5'; 325 $file = wikiFN($page); 326 327 // create the page 328 $this->assertFileNotExists($file); 329 saveWikiText($page, 'teststring', 'first save', false); 330 $this->assertFileExists($file); 331 $lastmod = filemtime($file); 332 333 $pagelog = new PageChangeLog($page); 334 $revisions = $pagelog->getRevisions(-1, 200); 335 $this->assertEquals(1, count($revisions)); 336 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 337 $this->assertEquals('first save', $revinfo['sum']); 338 $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']); 339 $this->assertEquals(10, $revinfo['sizechange']); 340 341 $this->waitForTick(true); // wait for new revision ID 342 343 // save with same content should be ignored 344 saveWikiText($page, 'teststring', 'second save', false); 345 clearstatcache(false, $file); 346 $this->assertEquals($lastmod, filemtime($file)); 347 348 $pagelog = new PageChangeLog($page); 349 $revisions = $pagelog->getRevisions(-1, 200); 350 $this->assertEquals(1, count($revisions)); 351 352 // update the page with new text 353 saveWikiText($page, 'teststring2long', 'third save', false); 354 clearstatcache(false, $file); 355 $newmod = filemtime($file); 356 $this->assertNotEquals($lastmod, $newmod); 357 $lastmod = $newmod; 358 $revertrev = $newmod; 359 360 $pagelog = new PageChangeLog($page); 361 $revisions = $pagelog->getRevisions(-1, 200); 362 $this->assertEquals(2, count($revisions)); 363 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 364 $this->assertEquals('third save', $revinfo['sum']); 365 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 366 $this->assertEquals(5, $revinfo['sizechange']); 367 368 $this->waitForTick(); // wait for new revision ID 369 370 // add a minor edit (unauthenticated) 371 saveWikiText($page, 'teststring3long', 'fourth save', true); 372 clearstatcache(false, $file); 373 $newmod = filemtime($file); 374 $this->assertNotEquals($lastmod, $newmod); 375 $lastmod = $newmod; 376 377 $pagelog = new PageChangeLog($page); 378 $revisions = $pagelog->getRevisions(-1, 200); 379 $this->assertEquals(3, count($revisions)); 380 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 381 $this->assertEquals('fourth save', $revinfo['sum']); 382 $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']); 383 $this->assertEquals(0, $revinfo['sizechange']); 384 385 $this->waitForTick(); // wait for new revision ID 386 387 // add a minor edit (authenticated) 388 $_SERVER['REMOTE_USER'] = 'user'; 389 saveWikiText($page, 'teststring4', 'fifth save', true); 390 clearstatcache(false, $file); 391 $newmod = filemtime($file); 392 $this->assertNotEquals($lastmod, $newmod); 393 $lastmod = $newmod; 394 395 $pagelog = new PageChangeLog($page); 396 $revisions = $pagelog->getRevisions(-1, 200); 397 $this->assertEquals(4, count($revisions)); 398 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 399 $this->assertEquals('fifth save', $revinfo['sum']); 400 $this->assertEquals(DOKU_CHANGE_TYPE_MINOR_EDIT, $revinfo['type']); 401 $this->assertEquals(-4, $revinfo['sizechange']); 402 403 $this->waitForTick(); // wait for new revision ID 404 405 // restore 406 $REV = $revertrev; 407 saveWikiText($page, 'teststring2long', 'sixth save', true); 408 clearstatcache(false, $file); 409 $this->assertFileExists($file); 410 $newmod = filemtime($file); 411 $this->assertNotEquals($lastmod, $newmod); 412 413 $pagelog = new PageChangeLog($page); 414 $revisions = $pagelog->getRevisions(-1, 200); 415 $this->assertEquals(5, count($revisions)); 416 $revinfo = $pagelog->getRevisionInfo($revisions[0]); 417 $this->assertEquals('sixth save', $revinfo['sum']); 418 $this->assertEquals(DOKU_CHANGE_TYPE_REVERT, $revinfo['type']); 419 $this->assertEquals($REV, $revinfo['extra']); 420 $this->assertEquals(4, $revinfo['sizechange']); 421 $REV = ''; 422 } 423 424} 425