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