xref: /plugin/struct/_test/action/EditTest.php (revision 8fed17f342cc190557a6ce94d1787f9e2f63cb6c)
1<?php
2
3namespace dokuwiki\plugin\struct\test\action;
4
5use dokuwiki\plugin\struct\meta;
6use dokuwiki\plugin\struct\test\mock\action_plugin_struct_edit;
7use dokuwiki\plugin\struct\test\mock\Assignments;
8use dokuwiki\plugin\struct\test\StructTest;
9
10/**
11 * @group plugin_struct
12 * @group plugins
13 *
14 * @covers action_plugin_struct_revert
15 * @covers action_plugin_struct_edit
16 */
17class EditTest extends StructTest
18{
19
20    public function setUp(): void
21    {
22        parent::setUp();
23
24        $this->loadSchemaJSON('schema1');
25        $this->loadSchemaJSON('schema2', 'schema2int');
26        $this->saveData(
27            'page01',
28            'schema1',
29            [
30                'first' => 'first data',
31                'second' => ['second data', 'more data', 'even more'],
32                'third' => 'third data',
33                'fourth' => 'fourth data'
34            ],
35            time()
36        );
37    }
38
39    protected function checkField(\phpQueryObject $pq, $schema, $name, $value)
40    {
41        $this->assertEquals(1, $pq->find("span.label:contains('$name')")->length, "Field $schema.$name not found");
42        $this->assertEquals($value, $pq->find("input[name='struct_schema_data[$schema][$name]']")->val(), "Field $schema.$name has wrong value");
43    }
44
45    public function test_createForm_storedData()
46    {
47        $edit = new action_plugin_struct_edit();
48        global $ID;
49        $ID = 'page01';
50        $test_html = $edit->createForm('schema1');
51
52        $pq = \phpQuery::newDocument($test_html);
53        $this->assertEquals('schema1', $pq->find('legend')->text());
54        $this->checkField($pq, 'schema1', 'first', 'first data');
55        $this->checkField($pq, 'schema1', 'second', 'second data, more data, even more');
56        $this->checkField($pq, 'schema1', 'third', 'third data');
57        $this->checkField($pq, 'schema1', 'fourth', 'fourth data');
58    }
59
60    public function test_createForm_emptyData()
61    {
62        $edit = new action_plugin_struct_edit();
63        global $ID;
64        $ID = 'page02';
65        $test_html = $edit->createForm('schema1');
66
67        $pq = \phpQuery::newDocument($test_html);
68        $this->assertEquals('schema1', $pq->find('legend')->text());
69        $this->checkField($pq, 'schema1', 'first', '');
70        $this->checkField($pq, 'schema1', 'second', '');
71        $this->checkField($pq, 'schema1', 'third', '');
72        $this->checkField($pq, 'schema1', 'fourth', '');
73    }
74
75    public function test_createForm_postData()
76    {
77        global $INPUT, $ID;
78        $ID = 'page01';
79        $structdata = [
80            'schema1' => [
81                'first' => 'first post data',
82                'second' => ['second post data', 'more post data', 'even more post data'],
83                'third' => 'third post data',
84                'fourth' => 'fourth post data'
85            ]
86        ];
87        $INPUT->set(action_plugin_struct_edit::getVAR(), $structdata);
88
89        $edit = new action_plugin_struct_edit();
90        $test_html = $edit->createForm('schema1');
91
92        $pq = \phpQuery::newDocument($test_html);
93        $this->assertEquals('schema1', $pq->find('legend')->text());
94        $this->checkField($pq, 'schema1', 'first', 'first post data');
95        $this->checkField($pq, 'schema1', 'second', 'second post data, more post data, even more post data');
96        $this->checkField($pq, 'schema1', 'third', 'third post data');
97        $this->checkField($pq, 'schema1', 'fourth', 'fourth post data');
98    }
99
100    public function test_edit_page_wo_schema()
101    {
102        $page = 'test_edit_page_wo_schema';
103
104        $request = new \TestRequest();
105        $response = $request->get(['id' => $page, 'do' => 'edit'], '/doku.php');
106        $structElement = $response->queryHTML('.struct_entry_form');
107
108        $this->assertCount(1, $structElement);
109        $this->assertEquals($structElement->html(), '');
110    }
111
112    public function test_edit_page_with_schema()
113    {
114        $page = 'test_edit_page_with_schema';
115        $assignment = Assignments::getInstance();
116        $schema = 'schema2';
117        $assignment->addPattern($page, $schema);
118
119        $request = new \TestRequest();
120        $response = $request->get(['id' => $page, 'do' => 'edit'], '/doku.php');
121        $test_html = trim($response->queryHTML('.struct_entry_form')->html());
122
123        $pq = \phpQuery::newDocument($test_html);
124        $this->assertEquals('schema2', $pq->find('legend')->text());
125        $this->checkField($pq, 'schema2', 'afirst', '');
126        $this->checkField($pq, 'schema2', 'asecond', '');
127        $this->checkField($pq, 'schema2', 'athird', '');
128        $this->checkField($pq, 'schema2', 'afourth', '');
129    }
130
131    public function test_preview_page_invaliddata()
132    {
133        $page = 'test_preview_page_invaliddata';
134        $assignment = Assignments::getInstance();
135        $schema = 'schema2';
136        $assignment->addPattern($page, $schema);
137
138        $request = new \TestRequest();
139        $structData = [
140            $schema => [
141                'afirst' => 'foo',
142                'asecond' => 'bar, baz',
143                'athird' => 'foobar',
144                'afourth' => 'Eve'
145            ]
146        ];
147        $request->setPost('struct_schema_data', $structData);
148        $response = $request->post(['id' => $page, 'do' => 'preview'], '/doku.php');
149        $expected_errormsg = sprintf($this->getLang('validation_prefix') . $this->getLang('Validation Exception Decimal needed'), 'afourth');
150        $actual_errormsg = $response->queryHTML('.error')->html();
151        $test_html = trim($response->queryHTML('.struct_entry_form')->html());
152
153        $this->assertEquals($expected_errormsg, $actual_errormsg, 'If there is invalid data, then there should be an error message.');
154
155        $pq = \phpQuery::newDocument($test_html);
156        $this->assertEquals('schema2', $pq->find('legend')->text());
157        $this->checkField($pq, 'schema2', 'afirst', 'foo');
158        $this->checkField($pq, 'schema2', 'asecond', 'bar, baz');
159        $this->checkField($pq, 'schema2', 'athird', 'foobar');
160        $this->checkField($pq, 'schema2', 'afourth', 'Eve');
161    }
162
163    public function test_preview_page_validdata()
164    {
165        $page = 'test_preview_page_validdata';
166        $assignment = Assignments::getInstance();
167        $schema = 'schema2';
168        $assignment->addPattern($page, $schema);
169
170        $request = new \TestRequest();
171        $structData = [
172            $schema => [
173                'afirst' => 'foo',
174                'asecond' => 'bar, baz',
175                'athird' => 'foobar',
176                'afourth' => '42'
177            ]
178        ];
179        $request->setPost('struct_schema_data', $structData);
180        $response = $request->post(['id' => $page, 'do' => 'preview'], '/doku.php');
181        $actual_errormsg = $response->queryHTML('.error')->get();
182        $test_html = trim($response->queryHTML('.struct_entry_form')->html());
183
184        $this->assertEquals($actual_errormsg, [], "If all data is valid, then there should be no error message.");
185
186        $pq = \phpQuery::newDocument($test_html);
187        $this->assertEquals('schema2', $pq->find('legend')->text());
188        $this->checkField($pq, 'schema2', 'afirst', 'foo');
189        $this->checkField($pq, 'schema2', 'asecond', 'bar, baz');
190        $this->checkField($pq, 'schema2', 'athird', 'foobar');
191        $this->checkField($pq, 'schema2', 'afourth', '42');
192    }
193
194    public function test_fail_saving_empty_page()
195    {
196        $page = 'test_fail_saving_empty_page';
197        $assignment = Assignments::getInstance();
198        $schema = 'schema2';
199        $assignment->addPattern($page, $schema);
200
201        $request = new \TestRequest();
202        $structData = [
203            $schema => [
204                'afirst' => 'foo',
205                'asecond' => 'bar, baz',
206                'athird' => 'foobar',
207                'afourth' => '42'
208            ]
209        ];
210        $request->setPost('struct_schema_data', $structData);
211        $request->setPost('summary', 'only struct data saved');
212        $response = $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
213        $expected_errormsg = $this->getLang('emptypage');
214        $actual_errormsg = $response->queryHTML('.error')->html();
215        $pagelog = new \PageChangelog($page);
216        $revisions = $pagelog->getRevisions(-1, 200);
217
218        $this->assertCount(0, $revisions);
219        $this->assertEquals($expected_errormsg, $actual_errormsg, "An empty page should not be saved.");
220    }
221
222    public function test_fail_saveing_page_with_invaliddata()
223    {
224        $page = 'test_fail_saveing_page_with_invaliddata';
225        $assignment = Assignments::getInstance();
226        $schema = 'schema2';
227        $assignment->addPattern($page, $schema);
228
229        $wikitext = 'teststring';
230        $request = new \TestRequest();
231        $structData = [
232            $schema => [
233                'afirst' => 'foo',
234                'asecond' => 'bar, baz',
235                'athird' => 'foobar',
236                'afourth' => 'Eve'
237            ]
238        ];
239        $request->setPost('struct_schema_data', $structData);
240        $request->setPost('wikitext', $wikitext);
241        $request->setPost('summary', 'content and struct data saved');
242        $response = $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
243        $actual_wikitext = trim($response->queryHTML('#wiki__text')->html());
244        $expected_wikitext = $wikitext;
245
246        $actual_errormsg = $response->queryHTML('.error')->html();
247        $expected_errormsg = sprintf($this->getLang('validation_prefix') . $this->getLang('Validation Exception Decimal needed'), 'afourth');
248
249        $test_html = trim($response->queryHTML('.struct_entry_form')->html());
250
251        $pagelog = new \PageChangelog($page);
252        $revisions = $pagelog->getRevisions(-1, 200);
253
254        // assert
255        $this->assertCount(0, $revisions);
256        $this->assertEquals($expected_errormsg, $actual_errormsg, 'If there is invalid data, then there should be an error message.');
257        $this->assertEquals($expected_wikitext, $actual_wikitext);
258
259        $pq = \phpQuery::newDocument($test_html);
260        $this->assertEquals('schema2', $pq->find('legend')->text());
261        $this->checkField($pq, 'schema2', 'afirst', 'foo');
262        $this->checkField($pq, 'schema2', 'asecond', 'bar, baz');
263        $this->checkField($pq, 'schema2', 'athird', 'foobar');
264        $this->checkField($pq, 'schema2', 'afourth', 'Eve');
265
266        // todo: assert that no struct data has been saved
267    }
268
269    public function test_save_page()
270    {
271        $page = 'test_save_page';
272        $assignment = Assignments::getInstance();
273        $schema = 'schema2';
274        $assignment->addPattern($page, $schema);
275
276        $request = new \TestRequest();
277        $structData = [
278            $schema => [
279                'afirst' => 'foo',
280                'asecond' => 'bar, baz',
281                'athird' => 'foobar',
282                'afourth' => '42'
283            ]
284        ];
285        $request->setPost('struct_schema_data', $structData);
286        $request->setPost('wikitext', 'teststring');
287        $request->setPost('summary', 'content and struct data saved');
288        $request->post(array('id' => $page, 'do' => 'save'), '/doku.php');
289
290        $pagelog = new \PageChangelog($page);
291        $revisions = $pagelog->getRevisions(-1, 200);
292        $revinfo = $pagelog->getRevisionInfo($revisions[0]);
293        $schemaData = meta\AccessTable::getPageAccess($schema, $page, $revisions[0]);
294        $actual_struct_data = $schemaData->getDataArray();
295        $expected_struct_data = [
296            'afirst' => 'foo',
297            'asecond' => ['bar', 'baz'],
298            'athird' => 'foobar',
299            'afourth' => 42
300        ];
301
302        $this->assertCount(1, $revisions);
303        $this->assertEquals('content and struct data saved', $revinfo['sum']);
304        $this->assertEquals(DOKU_CHANGE_TYPE_CREATE, $revinfo['type']);
305        $this->assertEquals($expected_struct_data, $actual_struct_data);
306        // todo: assert that pagerevision and struct data have the same timestamp
307    }
308
309    /**
310     * @group slow
311     */
312    public function test_save_page_without_new_text()
313    {
314        $page = 'test_save_page_without_new_text';
315        $assignment = Assignments::getInstance();
316        $schema = 'schema2';
317        $assignment->addPattern($page, $schema);
318        $wikitext = 'teststring';
319
320        // first save;
321        $request = new \TestRequest();
322        $structData = [
323            $schema => [
324                'afirst' => 'foo',
325                'asecond' => 'bar, baz',
326                'athird' => 'foobar',
327                'afourth' => '42'
328            ]
329        ];
330        $request->setPost('struct_schema_data', $structData);
331        $request->setPost('wikitext', $wikitext);
332        $request->setPost('summary', 'content and struct data saved');
333        $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
334
335        $this->waitForTick(true);
336
337        // second save - only struct data
338        $request = new \TestRequest();
339        $structData = [
340            $schema => [
341                'afirst' => 'foo2',
342                'asecond' => 'bar2, baz2',
343                'athird' => 'foobar2',
344                'afourth' => '43'
345            ]
346        ];
347        $request->setPost('struct_schema_data', $structData);
348        $request->setPost('wikitext', $wikitext);
349        $request->setPost('summary', '2nd revision');
350        $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
351
352        // assert
353        $pagelog = new \PageChangelog($page);
354        $revisions = $pagelog->getRevisions(-1, 200);
355        $revinfo = $pagelog->getRevisionInfo($revisions[0]);
356        $schemaData = meta\AccessTable::getPageAccess($schema, $page, $revisions[0]);
357        $actual_struct_data = $schemaData->getDataArray();
358        $expected_struct_data = [
359            'afirst' => 'foo2',
360            'asecond' => ['bar2', 'baz2'],
361            'athird' => 'foobar2',
362            'afourth' => 43
363        ];
364
365        $this->assertCount(2, $revisions, 'there should be 2 (two) revisions');
366        $this->assertEquals('2nd revision', $revinfo['sum']);
367        $this->assertEquals(DOKU_CHANGE_TYPE_EDIT, $revinfo['type']);
368        $this->assertEquals($expected_struct_data, $actual_struct_data);
369        // todo: assert that pagerevisions and struct entries have the same timestamps
370    }
371
372    /**
373     * @group slow
374     */
375    public function test_delete_page()
376    {
377        $page = 'test_delete_page';
378        $assignment = Assignments::getInstance();
379        $schema = 'schema2';
380        $assignment->addPattern($page, $schema);
381        $wikitext = 'teststring';
382
383        // first save;
384        $request = new \TestRequest();
385        $structData = [
386            $schema => [
387                'afirst' => 'foo',
388                'asecond' => 'bar, baz',
389                'athird' => 'foobar',
390                'afourth' => '42'
391            ]
392        ];
393        $request->setPost('struct_schema_data', $structData);
394        $request->setPost('wikitext', $wikitext);
395        $request->setPost('summary', 'content and struct data saved');
396        $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
397
398        $this->waitForTick(true);
399
400        // delete
401        $request = new \TestRequest();
402        $structData = [
403            $schema => [
404                'afirst' => 'foo2',
405                'asecond' => 'bar2, baz2',
406                'athird' => 'foobar2',
407                'afourth' => '43'
408            ]
409        ];
410        $request->setPost('struct_schema_data', $structData);
411        $request->setPost('wikitext', '');
412        $request->setPost('summary', 'delete page');
413        $request->post(['id' => $page, 'do' => 'save'], '/doku.php');
414
415        // assert
416        $pagelog = new \PageChangelog($page);
417        $revisions = $pagelog->getRevisions(-1, 200);
418        $revinfo = $pagelog->getRevisionInfo($revisions[0]);
419        $schemaData = meta\AccessTable::getPageAccess($schema, $page, $revisions[0]);
420        $actual_struct_data = $schemaData->getDataArray();
421        $expected_struct_data = [
422            'afirst' => '',
423            'asecond' => [],
424            'athird' => '',
425            'afourth' => ''
426        ];
427
428        $this->assertCount(2, $revisions, 'there should be 2 (two) revisions');
429        $this->assertEquals('delete page', $revinfo['sum']);
430        $this->assertEquals(DOKU_CHANGE_TYPE_DELETE, $revinfo['type']);
431        $this->assertEquals($expected_struct_data, $actual_struct_data);
432        // todo: timestamps?
433    }
434
435    /**
436     * @group slow
437     */
438    public function test_revert_page()
439    {
440        $page = 'test_revert_page';
441        $assignment = Assignments::getInstance();
442        $schema = 'schema2';
443        $assignment->addPattern($page, $schema);
444        $wikitext = 'teststring';
445
446        global $conf;
447        $conf['useacl'] = 1;
448        $conf['superuser'] = 'admin';
449        $_SERVER['REMOTE_USER'] = 'admin'; //now it's testing as admin
450        global $default_server_vars;
451        $default_server_vars['REMOTE_USER'] = 'admin';  //Hack until Issue #1099 is fixed
452        global $USERINFO;
453        $USERINFO['name'] = 'admin';
454        $USERINFO['mail'] = 'admin@example.com';
455        $USERINFO['grps'] = ['admin', 'user'];
456
457        // first save;
458        $request = new \TestRequest();
459        $structData = [
460            $schema => [
461                'afirst' => 'foo',
462                'asecond' => 'bar, baz',
463                'athird' => 'foobar',
464                'afourth' => '42'
465            ]
466        ];
467        $request->setPost('struct_schema_data', $structData);
468        $request->setPost('wikitext', $wikitext);
469        $request->setPost('summary', 'content and struct data saved');
470        $request->post(['id' => $page, 'do' => 'save', 'sectok' => getSecurityToken()], '/doku.php');
471
472        $this->waitForTick(true);
473
474        // second save
475        $request = new \TestRequest();
476        $structData = [
477            $schema => [
478                'afirst' => 'foo2',
479                'asecond' => 'bar2, baz2',
480                'athird' => 'foobar2',
481                'afourth' => '43'
482            ]
483        ];
484        $request->setPost('struct_schema_data', $structData);
485        $request->setPost('wikitext', $wikitext . $wikitext);
486        $request->setPost('summary', 'delete page');
487        $request->post(['id' => $page, 'do' => 'save', 'sectok' => getSecurityToken()], '/doku.php');
488
489        $this->waitForTick(true);
490
491        // revert to first save
492        $actpagelog = new \PageChangelog($page);
493        $actrevisions = $actpagelog->getRevisions(0, 200);
494
495        $actrevinfo = $actpagelog->getRevisionInfo($actrevisions[0]);
496        $request = new \TestRequest();
497        $request->setPost('summary', 'revert page');
498        $request->post(['id' => $page, 'do' => 'revert', 'rev' => $actrevinfo['date'], 'sectok' => getSecurityToken()], '/doku.php');
499
500        // assert
501        $pagelog = new \PageChangelog($page);
502        $revisions = $pagelog->getRevisions(-1, 200);
503        $revinfo = $pagelog->getRevisionInfo($revisions[0]);
504        $schemaData = meta\AccessTable::getPageAccess($schema, $page, $revisions[0]);
505        $actual_struct_data = $schemaData->getDataArray();
506        $expected_struct_data = [
507            'afirst' => 'foo',
508            'asecond' => ['bar', 'baz'],
509            'athird' => 'foobar',
510            'afourth' => '42'
511        ];
512
513        $this->assertCount(3, $revisions, 'there should be 3 (three) revisions');
514        $this->assertStringContainsString('restored', $revinfo['sum']);
515        $this->assertEquals(DOKU_CHANGE_TYPE_REVERT, $revinfo['type']);
516        $this->assertEquals($expected_struct_data, $actual_struct_data);
517        // todo: timestamps?
518    }
519
520}
521