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