xref: /dokuwiki/_test/tests/inc/common_saveWikiText.test.php (revision 8fb3ff96577de597f80427aa9e8e6748f7ced775)
1<?php
2
3use dokuwiki\ChangeLog\PageChangeLog;
4
5/**
6 * saveWikiText() stores files in pages/, attic/ and adds entries to changelog
7 */
8class common_saveWikiText_test extends DokuWikiTest {
9
10    /** Delay writes of old revisions by a second. */
11    public function handle_write(Doku_Event $event, $param) {
12        if ($event->data[3] !== false) {
13            $this->waitForTick();
14        }
15    }
16
17    /**
18     * assertions against changelog entries and attic after saveWikiText()
19     */
20    private function checkChangeLogAfterNormalSave(
21        PageChangeLog $pagelog,
22        $expectedRevs,          // @param int
23        &$expectedLastEntry     // @param array, pass by reference
24    ) {
25        $revisions = $pagelog->getRevisions(-1, 200);
26        $this->assertCount($expectedRevs, $revisions);
27        $this->assertCount($expectedRevs, array_unique($revisions), 'date duplicated in changelog');
28        // last revision
29        $lastRevInfo = $pagelog->getRevisionInfo($revisions[0]);
30        $expectedLastEntry += $lastRevInfo;
31        $this->assertEquals($expectedLastEntry, $lastRevInfo);
32        // current revision
33        $currentRevInfo = $pagelog->getCurrentRevisionInfo();
34        $this->assertEquals($currentRevInfo, $lastRevInfo, 'current & last revs should be identical');
35        // attic
36        $attic = wikiFN($lastRevInfo['id'], $lastRevInfo['date']);
37        $this->assertFileExists($attic, 'file missing in attic');
38        $files = count(glob(dirname($attic).'/'.noNS($lastRevInfo['id']).'.*'));
39        $this->assertLessThanOrEqual($expectedRevs, $files, 'detectExternalEdit() should not add too often old revs');
40    }
41
42    /**
43     * assertions against changelog entries and attic after external edit, create or deletion of page
44     */
45    private function checkChangeLogAfterExternalEdit(
46        PageChangeLog $pagelog,
47        $expectedRevs,          // @param int
48        $expectedLastEntry,     // @param array
49        &$expectedCurrentEntry  // @param array, pass by reference
50    ) {
51        $revisions = $pagelog->getRevisions(-1, 200);
52        $this->assertCount($expectedRevs, $revisions);
53        $this->assertCount($expectedRevs, array_unique($revisions), 'date duplicated in changelog');
54        // last revision
55        if ($expectedRevs > 0) {
56            $lastRevInfo = $pagelog->getRevisionInfo($revisions[0]);
57            $expectedLastEntry += $lastRevInfo;
58            $this->assertEquals($expectedLastEntry, $lastRevInfo);
59        } else {
60            $this->assertFalse($pagelog->lastRevision(), 'changelog file does not yet exist');
61        }
62        // current revision
63        $currentRevInfo = $pagelog->getCurrentRevisionInfo();
64        $this->assertArrayHasKey('timestamp', $currentRevInfo, 'should be external revision');
65        $expectedCurrentEntry += $currentRevInfo;
66        if ($expectedRevs > 0) {
67            $this->assertEquals($expectedCurrentEntry, $currentRevInfo);
68
69        }
70        // attic
71        $attic = wikiFN($currentRevInfo['id'], $currentRevInfo['date']);
72        $this->assertFileNotExists($attic, 'page does not yet exist in attic');
73    }
74
75
76    /**
77     * Execute a whole bunch of saves on the same page and check the results
78     * TEST 1
79     *  1.1 create a page
80     *  1.2 save with same content should be ignored
81     *  1.3 update the page with new text
82     *  1.4 add a minor edit (unauthenticated, minor not allowable)
83     *  1.5 add a minor edit (authenticated)
84     *  1.6 delete
85     *  1.7 restore
86     *  1.8 external edit
87     *  1.9 edit and save on top of external edit
88     */
89    function test_savesequence1() {
90        global $REV;
91
92        $page = 'page';
93        $file = wikiFN($page);
94        $this->assertFileNotExists($file);
95
96        // 1.1 create a page
97        saveWikiText($page, 'teststring', '1st save', false);
98        clearstatcache(false, $file);
99        $this->assertFileExists($file);
100        $lastmod = filemtime($file);
101        $expectedRevs = 1;
102        $expect = array(
103            'date' => $lastmod,
104            'type' => DOKU_CHANGE_TYPE_CREATE,
105            'sum'  => '1st save',
106            'sizechange' => 10, // = strlen('teststring')
107        );
108
109        $pagelog = new PageChangeLog($page);
110        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
111
112        $this->waitForTick(true); // wait for new revision ID
113
114        // 1.2 save with same content should be ignored
115        saveWikiText($page, 'teststring', '2nd save', false);
116        clearstatcache(false, $file);
117        $this->assertEquals($lastmod, filemtime($file));
118
119        $pagelog = new PageChangeLog($page);
120        $revisions = $pagelog->getRevisions(-1, 200);
121        $this->assertCount(1, $revisions);
122
123        // 1.3 update the page with new text
124        saveWikiText($page, 'teststring2long', '3rd save', false);
125        clearstatcache(false, $file);
126        $newmod = filemtime($file);
127        $this->assertNotEquals($lastmod, $newmod);
128        $lastmod = $newmod;
129        $expectedRevs = 2;
130        $expect = array(
131            'date' => $lastmod,
132            'type' => DOKU_CHANGE_TYPE_EDIT,
133            'sum'  => '3rd save',
134            'sizechange' => 5,
135        );
136
137        $pagelog = new PageChangeLog($page);
138        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
139
140        $this->waitForTick(); // wait for new revision ID
141
142        // 1.4 add a minor edit (unauthenticated, minor not allowable)
143        saveWikiText($page, 'teststring3long', '4th save', true);
144        clearstatcache(false, $file);
145        $newmod = filemtime($file);
146        $this->assertNotEquals($lastmod, $newmod);
147        $lastmod = $newmod;
148        $expectedRevs = 3;
149        $expect = array(
150            'date' => $lastmod,
151            'type' => DOKU_CHANGE_TYPE_EDIT,
152            'sum'  => '4th save',
153            'sizechange' => 0,
154        );
155
156        $pagelog = new PageChangeLog($page);
157        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
158
159        $this->waitForTick(); // wait for new revision ID
160
161        // 1.5 add a minor edit (authenticated)
162        $_SERVER['REMOTE_USER'] = 'user';
163        saveWikiText($page, 'teststring4', '5th save', true);
164        clearstatcache(false, $file);
165        $newmod = filemtime($file);
166        $this->assertNotEquals($lastmod, $newmod);
167        $lastmod = $newmod;
168        $expectedRevs = 4;
169        $expect = array(
170            'date' => $lastmod,
171            'type' => DOKU_CHANGE_TYPE_MINOR_EDIT,
172            'sum'  => '5th save',
173            'sizechange' => -4,
174        );
175
176        $pagelog = new PageChangeLog($page);
177        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
178
179        $this->waitForTick(); // wait for new revision ID
180
181        // 1.6 delete
182        saveWikiText($page, '', '6th save', false);
183        clearstatcache(false, $file);
184        $this->assertFileNotExists($file);
185        $expectedRevs = 5;
186        $expect = array(
187          //'date' => $lastmod, // ignore from lastRev assertion, but confirm attic file existence
188            'type' => DOKU_CHANGE_TYPE_DELETE,
189            'sum'  => '6th save',
190            'sizechange' => -11,
191        );
192
193        $pagelog = new PageChangeLog($page);
194        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
195
196        $this->waitForTick(); // wait for new revision ID
197
198        // 1.7 restore
199        $REV = $lastmod;
200        saveWikiText($page, 'teststring4', '7th save', true);
201        clearstatcache(false, $file);
202        $this->assertFileExists($file);
203        $newmod = filemtime($file);
204        $this->assertNotEquals($lastmod, $newmod);
205        $lastmod = $newmod;
206        $expectedRevs = 6;
207        $expect = array(
208            'date' => $lastmod,
209            'type' => DOKU_CHANGE_TYPE_REVERT,
210            'sum'  => '7th save',
211            'sizechange' => 11,
212        );
213
214        $pagelog = new PageChangeLog($page);
215        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
216        $REV = '';
217
218        $this->waitForTick(); // wait for new revision ID
219
220        // 1.8 external edit
221        file_put_contents($file, 'teststring5 external edit');
222        clearstatcache(false, $file);
223        $newmod = filemtime($file);
224        $this->assertNotEquals($lastmod, $newmod);
225        $lastmod = $newmod;
226        $expectedRevs = 6; // external edit is not yet in changelog
227        $expectExternal = array(
228            'date' => $lastmod,
229            'type' => DOKU_CHANGE_TYPE_EDIT,
230            'sum'  => 'external edit',
231            'sizechange' => 14,
232        );
233
234        $pagelog = new PageChangeLog($page);
235        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
236
237        $this->waitForTick(); // wait for new revision ID
238
239        // 1.9 save on top of external edit
240        saveWikiText($page, 'teststring6', '8th save', false);
241        clearstatcache(false, $file);
242        $newmod = filemtime($file);
243        $this->assertNotEquals($lastmod, $newmod);
244        $lastmod = $newmod;
245        $expectedRevs = 8;
246        $expect = array(
247            'date' => $lastmod,
248            'type' => DOKU_CHANGE_TYPE_EDIT,
249            'sum'  => '8th save',
250            'sizechange' => -14,
251        );
252
253        $pagelog = new PageChangeLog($page);
254        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
255    }
256
257    /**
258     * Execute a whole bunch of saves on the same page and check the results
259     * using $this->handle_write() in event IO_WIKIPAGE_WRITE
260     * TEST 2 - create a page externally in 2.3, while external edit in Test 1.8
261     *  2.1 create a page
262     *  2.2 delete
263     *  2.3 externally create the page
264     *  2.4 edit and save on top of external edit
265     *  2.5 external edit
266     *  2.6 edit and save on top of external edit, again
267     */
268    function test_savesequence2() {
269        // add an additional delay when saving files to make sure
270        // nobody relies on the saving happening in the same second
271        /** @var $EVENT_HANDLER \dokuwiki\Extension\EventHandler */
272        global $EVENT_HANDLER;
273        $EVENT_HANDLER->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'handle_write');
274
275        $page = 'page2';
276        $file = wikiFN($page);
277        $this->assertFileNotExists($file);
278
279        // 2.1 create a page
280        saveWikiText($page, 'teststring', 'Test 2, 1st save', false);
281        clearstatcache(false, $file);
282        $this->assertFileExists($file);
283        $lastmod = filemtime($file);
284        $expectedRevs = 1;
285        $expect = array(
286            'date' => $lastmod,
287            'type' => DOKU_CHANGE_TYPE_CREATE,
288            'sum'  => 'Test 2, 1st save',
289            'sizechange' => 10, // = strlen('teststring')
290        );
291
292        $pagelog = new PageChangeLog($page);
293        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
294
295        $this->waitForTick(true); // wait for new revision ID
296
297        // 2.2 delete
298        saveWikiText($page, '', 'Test 2, 2nd save', false);
299        clearstatcache(false, $file);
300        $this->assertFileNotExists($file);
301        $expectedRevs = 2;
302        $expect = array(
303          //'date' => $lastmod, // ignore from lastRev assertion, but confirm attic file existence
304            'type' => DOKU_CHANGE_TYPE_DELETE,
305            'sum'  => 'Test 2, 2nd save',
306            'sizechange' => -10,
307        );
308
309        $pagelog = new PageChangeLog($page);
310        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
311
312        $this->waitForTick(); // wait for new revision ID
313
314        // 2.3 externally create the page
315        file_put_contents($file, 'teststring5');
316        clearstatcache(false, $file);
317        $lastmod = filemtime($file);
318        $expectedRevs = 2; // external edit is not yet in changelog
319        $expectExternal = array(
320            'date' => $lastmod,
321            'type' => DOKU_CHANGE_TYPE_CREATE,
322            'sum'  => 'created - external edit',
323            'sizechange' => 11,
324        );
325
326        $pagelog = new PageChangeLog($page);
327        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
328
329        $this->waitForTick(); // wait for new revision ID
330
331        // 2.4 save on top of external edit
332        saveWikiText($page, 'teststring6', 'Test 2, 3rd save', false);
333        clearstatcache(false, $file);
334        $newmod = filemtime($file);
335        $this->assertNotEquals($lastmod, $newmod);
336        $lastmod = $newmod;
337        $expectedRevs = 4; // two more revisions now!
338        $expect = array(
339            'date' => $lastmod,
340            'type' => DOKU_CHANGE_TYPE_EDIT,
341            'sum'  => 'Test 2, 3rd save',
342            'sizechange' => 0,
343        );
344
345        $pagelog = new PageChangeLog($page);
346        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
347
348        $this->waitForTick(); // wait for new revision ID
349
350         // 2.5 external edit
351        file_put_contents($file, 'teststring7 external edit2');
352        clearstatcache(false, $file);
353        $newmod = filemtime($file);
354        $this->assertNotEquals($lastmod, $newmod);
355        $lastmod = $newmod;
356        $expectedRevs = 4; // external edit is not yet in changelog
357        $expectExternal = array(
358            'date' => $lastmod,
359            'type' => DOKU_CHANGE_TYPE_EDIT,
360            'sum'  => 'external edit',
361            'sizechange' => 15,
362        );
363
364        $pagelog = new PageChangeLog($page);
365        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
366
367        $this->waitForTick(); // wait for new revision ID
368
369        // 2.6 save on top of external edit, again
370        saveWikiText($page, 'teststring8', 'Test 2, 4th save', false);
371        clearstatcache(false, $file);
372        $newmod = filemtime($file);
373        $this->assertNotEquals($lastmod, $newmod);
374        $lastmod = $newmod;
375        $expectedRevs = 6; // two more revisions now!
376        $expect = array(
377            'date' => $lastmod,
378            'type' => DOKU_CHANGE_TYPE_EDIT,
379            'sum'  => 'Test 2, 4th save',
380            'sizechange' => -15,
381        );
382
383        $pagelog = new PageChangeLog($page);
384        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
385    }
386
387    /**
388     * Execute a whole bunch of saves on the same page and check the results
389     * TEST 3 - typical page life of bundled page such as wiki:syntax
390     *  3.1 externally create a page
391     *  3.2 external edit
392     *  3.3 edit and save on top of external edit
393     *  3.4 externally delete the page
394     */
395    function test_savesequence3() {
396        $page = 'page3';
397        $file = wikiFN($page);
398
399        // 3.1 externally create a page
400        $this->assertFileNotExists($file);
401        file_put_contents($file, 'teststring');
402        clearstatcache(false, $file);
403        $lastmod = filemtime($file);
404        $expectedRevs = 0; // external edit is not yet in changelog
405        $expect = false;
406        $expectExternal = array(
407            'date' => $lastmod,
408            'type' => DOKU_CHANGE_TYPE_CREATE,
409            'sum'  => 'created - external edit',
410            'sizechange' => 10,
411        );
412
413        $pagelog = new PageChangeLog($page);
414        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
415
416        $this->waitForTick(true); // wait for new revision ID
417
418        // 3.2 external edit (repeated, still no changelog exists)
419        file_put_contents($file, 'teststring external edit');
420        clearstatcache(false, $file);
421        $newmod = filemtime($file);
422        $this->assertNotEquals($lastmod, $newmod);
423        $lastmod = $newmod;
424        $expectedRevs = 0; // external edit is not yet in changelog
425        $expectExternal = array(
426            'date' => $lastmod,
427            'type' => DOKU_CHANGE_TYPE_CREATE,  // not DOKU_CHANGE_TYPE_EDIT
428            'sum'  => 'created - external edit',
429            'sizechange' => 24,
430        );
431
432        $pagelog = new PageChangeLog($page);
433        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
434
435        $this->waitForTick(true); // wait for new revision ID
436
437        // 3.3 save on top of external edit
438        saveWikiText($page, 'teststring1', 'Test 3, first save', false);
439        clearstatcache(false, $file);
440        $newmod = filemtime($file);
441        $this->assertNotEquals($lastmod, $newmod);
442        $lastmod = $newmod;
443        $expectedRevs = 2; // two more revisions now!
444        $expect = array(
445            'date' => $lastmod,
446            'type' => DOKU_CHANGE_TYPE_EDIT,
447            'sum'  => 'Test 3, first save',
448            'sizechange' => -13,
449        );
450
451        $pagelog = new PageChangeLog($page);
452        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
453
454        // second to last revision record that corresponds to step 3.2 external edit
455        $revs = $pagelog->getRevisions(-1, $expectedRevs);
456        $prevRevInfo = $pagelog->getRevisionInfo($revs[$expectedRevs -1]);
457        unset($expectExternal['timestamp']); // drop timestamp key
458        $this->assertEquals($expectExternal, $prevRevInfo);
459
460        $this->waitForTick(true); // wait for new revision ID
461
462        // 3.4 externally delete the page
463        unlink($file);
464        $expectedRevs = 2;
465        $expectExternal = array(
466          //'date' => $lastmod,
467            'type' => DOKU_CHANGE_TYPE_DELETE,
468            'sum'  => 'removed - external edit (Unknown date)',
469            'sizechange' => -11,
470        );
471
472        $pagelog = new PageChangeLog($page);
473        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
474    }
475
476    /**
477     * Execute a whole bunch of saves on the same page and check the results
478     * TEST 4 - typical page life of bundled page such as wiki:syntax
479     *  4.1 externally create a page
480     *  4.2 edit and save
481     *  4.3 externally edit as a result of a file which has older timestamp than last revision
482     */
483    function test_savesequence4() {
484        $page = 'page4';
485        $file = wikiFN($page);
486
487        // 4.1 externally create a page
488        $this->assertFileNotExists($file);
489        file_put_contents($file, 'teststring');
490        clearstatcache(false, $file);
491        $lastmod = filemtime($file);
492        $expectedRevs = 0; // external edit is not yet in changelog
493        $expect = false;
494        $expectExternal = array(
495            'date' => $lastmod,
496            'type' => DOKU_CHANGE_TYPE_CREATE,
497            'sum'  => 'created - external edit',
498            'sizechange' => 10,
499        );
500
501        $pagelog = new PageChangeLog($page);
502        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
503
504        $this->waitForTick(true); // wait for new revision ID
505
506        // 4.2 edit and save
507        saveWikiText($page, 'teststring1', 'Test 4, first save', false);
508        clearstatcache(false, $file);
509        $newmod = filemtime($file);
510        $this->assertNotEquals($lastmod, $newmod);
511        $lastmod = $newmod;
512        $expectedRevs = 2; // two more revisions now!
513        $expect = array(
514            'date' => $lastmod,
515            'type' => DOKU_CHANGE_TYPE_EDIT,
516            'sum'  => 'Test 4, first save',
517            'sizechange' => 1,
518        );
519
520        $pagelog = new PageChangeLog($page);
521        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
522
523        $this->waitForTick(true); // wait for new revision ID
524
525        // 4.3 externally edit as a result of a file which has older timestamp than last revision
526        unlink($file);
527        file_put_contents($file, 'teststring fake 1 hout past');
528        touch($file, filemtime($file) -3600); // change file modification time to 1 hour past
529        clearstatcache();
530        $newmod = filemtime($file);
531        $this->assertLessThan($lastmod, $newmod); // file must be older than previous for this test
532        $expectedRevs = 2; // external edit is not yet in changelog
533        $expectExternal = array(
534            'date' => $lastmod + 1,
535            'type' => DOKU_CHANGE_TYPE_EDIT,
536            'sum'  => 'external edit (Unknown date)',
537            'sizechange' => 16,
538        );
539
540        $pagelog = new PageChangeLog($page);
541        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
542    }
543
544    /**
545     * Execute a whole bunch of saves on the same page and check the results
546     * TEST 5 - page creation and deletion
547     *  5.1 create a page
548     *  5.2 external edit
549     *  5.3 edit and save on top of external edit
550     *  5.4 delete
551     *  5.5 create a page, second time
552     *  5.6 externally delete
553     *  5.7 create a page, third time
554     */
555    function test_savesequence5() {
556        $page = 'page5';
557        $file = wikiFN($page);
558        $this->assertFileNotExists($file);
559
560        // 5.1 create a page
561        saveWikiText($page, 'teststring', 'Test 5, 1st save', false);
562        $this->assertFileExists($file);
563        $lastmod = filemtime($file);
564        $expectedRevs = 1;
565        $expect = array(
566            'date' => $lastmod,
567            'type' => DOKU_CHANGE_TYPE_CREATE,
568            'sum'  => 'Test 5, 1st save',
569            'sizechange' => 10, // = strlen('teststring')
570        );
571
572        $pagelog = new PageChangeLog($page);
573        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
574
575        $this->waitForTick(true); // wait for new revision ID
576
577        // 5.2 external edit
578        file_put_contents($file, 'teststring external edit');
579        clearstatcache(false, $file);
580        $newmod = filemtime($file);
581        $this->assertNotEquals($lastmod, $newmod);
582        $lastmod = $newmod;
583        $expectedRevs = 1; // external edit is not yet in changelog
584        $expectExternal = array(
585            'date' => $lastmod,
586            'type' => DOKU_CHANGE_TYPE_EDIT,
587            'sum'  => 'external edit',
588            'sizechange' => 14,
589        );
590
591        $pagelog = new PageChangeLog($page);
592        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
593
594        $this->waitForTick(); // wait for new revision ID
595
596        // 5.3 edit and save on top of external edit
597        saveWikiText($page, 'teststring normal edit', 'Test 5, 2nd save', false);
598        clearstatcache(false, $file);
599        $newmod = filemtime($file);
600        $this->assertNotEquals($lastmod, $newmod);
601        $lastmod = $newmod;
602        $expectedRevs = 3; // two more revisions now!
603        $expect = array(
604            'date' => $lastmod,
605            'type' => DOKU_CHANGE_TYPE_EDIT,
606            'sum'  => 'Test 5, 2nd save',
607            'sizechange' => -2,
608        );
609
610        $pagelog = new PageChangeLog($page);
611        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
612
613        $this->waitForTick(); // wait for new revision ID
614
615        // 5.4 delete
616        saveWikiText($page, '', 'Test 5 3rd save', false);
617        clearstatcache(false, $file);
618        $this->assertFileNotExists($file);
619        $expectedRevs = 4;
620        $expect = array(
621          //'date' => $lastmod, // ignore from lastRev assertion, but confirm attic file existence
622            'type' => DOKU_CHANGE_TYPE_DELETE,
623            'sum'  => 'Test 5 3rd save',
624            'sizechange' => -22,
625        );
626
627        $pagelog = new PageChangeLog($page);
628        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
629
630        $this->waitForTick(); // wait for new revision ID
631
632        // 5.5 create a page, second time
633        $this->assertFileNotExists($file);
634        saveWikiText($page, 'teststring revived', 'Test 5, 4th save', false);
635        $this->assertFileExists($file);
636        $lastmod = filemtime($file);
637        $expectedRevs = 5;
638        $expect = array(
639            'date' => $lastmod,
640            'type' => DOKU_CHANGE_TYPE_CREATE,
641            'sum'  => 'Test 5, 4th save',
642            'sizechange' => 18, // = strlen('teststring revived')
643        );
644
645        $pagelog = new PageChangeLog($page);
646        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
647
648        $this->waitForTick(true); // wait for new revision ID
649
650        // 5.6 externally delete
651        unlink($file);
652        $this->assertFileNotExists($file);
653        $expectedRevs = 5;
654        $expectExternal = array(
655          //'date' => $lastmod,
656            'type' => DOKU_CHANGE_TYPE_DELETE,
657            'sum'  => 'removed - external edit (Unknown date)',
658            'sizechange' => -18,
659        );
660
661        $pagelog = new PageChangeLog($page);
662        $this->checkChangeLogAfterExternalEdit($pagelog, $expectedRevs, $expect, $expectExternal);
663
664        $this->waitForTick(true); // wait for new revision ID
665
666        // 5.7 create a page, third time
667        $this->assertFileNotExists($file);
668        saveWikiText($page, 'teststring revived 2', 'Test 5, 5th save', false);
669        clearstatcache(false, $file);
670        $this->assertFileExists($file);
671        $lastmod = filemtime($file);
672        $expectedRevs = 7;
673        $expect = array(
674            'date' => $lastmod,
675            'type' => DOKU_CHANGE_TYPE_CREATE,
676            'sum'  => 'Test 5, 5th save',
677            'sizechange' => 20, // = strlen('teststring revived 2')
678        );
679
680        $pagelog = new PageChangeLog($page);
681        $this->checkChangeLogAfterNormalSave($pagelog, $expectedRevs, $expect);
682    }
683
684}
685