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