xref: /dokuwiki/_test/tests/inc/common_saveWikiText.test.php (revision 4a52f4c5cfc509a8021ea9c21ba739e9bb09edf7)
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