1<?php
2
3namespace dokuwiki\plugin\struct\test;
4
5use dokuwiki\plugin\struct\meta;
6use dokuwiki\plugin\struct\meta\Search;
7
8/**
9 * Tests to the DB for the struct plugin
10 *
11 * @group plugin_struct
12 * @group plugins
13 *
14 */
15class AccessTableDataDB_struct_test extends StructTest
16{
17
18    /** @var \helper_plugin_sqlite $sqlite */
19    protected $sqlite;
20
21    public function setUp(): void
22    {
23        parent::setUp();
24
25        /** @var \helper_plugin_struct_db $sqlite */
26        $sqlite = plugin_load('helper', 'struct_db');
27        $this->sqlite = $sqlite->getDB();
28
29        $this->loadSchemaJSON('testtable', '', 100);
30
31        // revision 1
32        $this->saveData(
33            'testpage',
34            'testtable',
35            array(
36                'testcolumn' => 'value1',
37                'testMulitColumn' => array('value2.1', 'value2.2')
38            ),
39            123
40        );
41
42        // revision 2
43        $this->saveData(
44            'testpage',
45            'testtable',
46            array(
47                'testcolumn' => 'value1a',
48                'testMulitColumn' => array('value2.1a', 'value2.2a')
49            ),
50            789
51        );
52
53        // revision 1 of different page
54        $this->saveData(
55            'testpage2',
56            'testtable',
57            array(
58                'testcolumn' => 'value1a',
59                'testMulitColumn' => array('value2.1a')
60            ),
61            789
62        );
63    }
64
65    public function test_getDataFromDB_currentRev()
66    {
67
68        // act
69        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
70        $actual_data = $schemaData->getDataFromDb();
71
72        $expected_data = array(
73            array(
74                'out1' => 'value1a',
75                'out2' => 'value2.1a' . Search::CONCAT_SEPARATOR . 'value2.2a',
76                'PID' => 'testpage',
77            ),
78        );
79
80        $this->assertEquals($expected_data, $actual_data);
81    }
82
83    public function test_getDataFromDB_oldRev()
84    {
85
86        // act
87        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage', 200);
88        $actual_data = $schemaData->getDataFromDB();
89
90        $expected_data = array(
91            array(
92                'out1' => 'value1',
93                'out2' => 'value2.1' . Search::CONCAT_SEPARATOR . 'value2.2',
94                'PID' => 'testpage',
95            ),
96        );
97
98        $this->assertEquals($expected_data, $actual_data, '');
99    }
100
101    public function test_getData_currentRev()
102    {
103
104        // act
105        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
106        $actual_data = $schemaData->getData();
107
108        $expected_data = array(
109            'testMulitColumn' => array('value2.1a', 'value2.2a'),
110            'testcolumn' => 'value1a',
111        );
112
113        // assert
114        foreach ($expected_data as $key => $value) {
115            $this->assertEquals($value, $actual_data[$key]->getValue());
116        }
117    }
118
119    public function test_getDataArray_currentRev()
120    {
121
122        // act
123        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
124        $actual_data = $schemaData->getDataArray();
125
126        $expected_data = array(
127            'testMulitColumn' => array('value2.1a', 'value2.2a'),
128            'testcolumn' => 'value1a'
129        );
130
131        // assert
132        $this->assertEquals($expected_data, $actual_data, '');
133    }
134
135    public function test_getData_currentRev2()
136    {
137
138        // act
139        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage2');
140        $actual_data = $schemaData->getData();
141
142        $expected_data = array(
143            'testMulitColumn' => array('value2.1a'),
144            'testcolumn' => 'value1a',
145        );
146
147        // assert
148        foreach ($expected_data as $index => $value) {
149            $this->assertEquals($value, $actual_data[$index]->getValue());
150        }
151    }
152
153    public function test_getData_oldRev()
154    {
155
156        // act
157        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage', 200);
158        $actual_data = $schemaData->getData();
159
160        $expected_data = array(
161            'testMulitColumn' => array('value2.1', 'value2.2'),
162            'testcolumn' => 'value1',
163        );
164
165        // assert
166        foreach ($expected_data as $index => $value) {
167            $this->assertEquals($value, $actual_data[$index]->getValue());
168        }
169    }
170
171    public function test_saveData()
172    {
173        // arrange
174        $testdata = array(
175            'testcolumn' => 'value1_saved',
176            'testMulitColumn' => array(
177                "value2.1_saved",
178                "value2.2_saved",
179                "value2.3_saved",
180            )
181        );
182
183        // act
184        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
185        $result = $schemaData->saveData($testdata);
186
187        // assert
188        /** @noinspection SqlResolve */
189        $res = $this->sqlite->query("SELECT pid, col1, col2 FROM data_testtable WHERE pid = ? ORDER BY rev DESC LIMIT 1", array('testpage'));
190        $actual_saved_single = $this->sqlite->res2row($res);
191        $expected_saved_single = array(
192            'pid' => 'testpage',
193            'col1' => 'value1_saved',
194            'col2' => 'value2.1_saved' # copy of the multi-value's first value
195        );
196
197        /** @noinspection SqlResolve */
198        $res = $this->sqlite->query("SELECT colref, row, value FROM multi_testtable WHERE pid = ? ORDER BY rev DESC LIMIT 3", array('testpage'));
199        $actual_saved_multi = $this->sqlite->res2arr($res);
200        $expected_saved_multi = array(
201            array(
202                'colref' => '2',
203                'row' => '1',
204                'value' => "value2.1_saved"
205            ),
206            array(
207                'colref' => '2',
208                'row' => '2',
209                'value' => "value2.2_saved"
210            ),
211            array(
212                'colref' => '2',
213                'row' => '3',
214                'value' => "value2.3_saved"
215            )
216        );
217
218        $this->assertTrue($result, 'should be true on success');
219        $this->assertEquals($expected_saved_single, $actual_saved_single, 'single value fields');
220        $this->assertEquals($expected_saved_multi, $actual_saved_multi, 'multi value fields');
221    }
222
223    public function test_getDataFromDB_clearData()
224    {
225
226        // act
227        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
228        $schemaData->clearData();
229        $actual_data = $schemaData->getDataFromDB();
230
231        $expected_data = array(
232            array(
233                'out1' => '',
234                'out2' => null,
235                'PID' => 'testpage',
236            )
237        );
238
239        $this->assertEquals($expected_data, $actual_data, '');
240    }
241
242    public function test_getData_clearData()
243    {
244
245        // act
246        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
247        $schemaData->clearData();
248        $actual_data = $schemaData->getData();
249
250        // assert
251        $this->assertEquals(array(), $actual_data['testMulitColumn']->getValue());
252        $this->assertEquals(null, $actual_data['testcolumn']->getValue());
253    }
254
255    public function test_getData_skipEmpty()
256    {
257        // arrange
258        $testdata = array(
259            'testcolumn' => '',
260            'testMulitColumn' => array(
261                "value2.1_saved",
262                "value2.2_saved",
263            )
264        );
265        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
266        $schemaData->saveData($testdata);
267
268        // act
269        $schemaData->optionSkipEmpty(true);
270        $actual_data = $schemaData->getData();
271
272        $expected_data = array('value2.1_saved', 'value2.2_saved');
273
274        // assert
275        $this->assertEquals(1, count($actual_data), 'There should be only one value returned and the empty value skipped');
276        $this->assertEquals($expected_data, $actual_data['testMulitColumn']->getValue());
277    }
278
279    public function test_getDataArray_skipEmpty()
280    {
281        // arrange
282        $testdata = array(
283            'testcolumn' => '',
284            'testMulitColumn' => array(
285                "value2.1_saved",
286                "value2.2_saved",
287            )
288        );
289        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
290        $schemaData->saveData($testdata);
291
292        // act
293        $schemaData->optionSkipEmpty(true);
294        $actual_data = $schemaData->getDataArray();
295
296        $expected_data = array(
297            'testMulitColumn' => array('value2.1_saved', 'value2.2_saved')
298        );
299
300        // assert
301        $this->assertEquals(1, count($actual_data), 'There should be only one value returned and the empty value skipped');
302        $this->assertEquals($expected_data, $actual_data);
303    }
304
305    public function test_pseudodiff()
306    {
307        $this->loadSchemaJSON('pageschema');
308        $this->saveData(
309            'syntax',
310            'pageschema',
311            array(
312                'singlepage' => 'wiki:dokuwiki',
313                'multipage' => array('wiki:dokuwiki', 'wiki:syntax', 'wiki:welcome'),
314                'singletitle' => 'wiki:dokuwiki',
315                'multititle' => array('wiki:dokuwiki', 'wiki:syntax', 'wiki:welcome'),
316            ),
317            time()
318        );
319
320        // make sure titles for some pages are known (not for wiki:welcome)
321        $pageMeta = new \dokuwiki\plugin\struct\meta\PageMeta('wiki:dokuwiki');
322        $pageMeta->setTitle('DokuWiki Overview');
323        $pageMeta = new \dokuwiki\plugin\struct\meta\PageMeta('wiki:syntax');
324        $pageMeta->setTitle('DokuWiki Foobar Syntax');
325        $pageMeta->savePageData();
326
327        $schemaData = meta\AccessTable::getPageAccess('pageschema', 'syntax');
328        $actual_pseudodiff = $schemaData->getDataPseudoSyntax();
329        $expected_pseudodiff = "pageschema.singlepage : wiki:dokuwiki
330pageschema.multipage : wiki:dokuwiki, wiki:syntax, wiki:welcome
331pageschema.singletitle : DokuWiki Overview
332pageschema.multititle : DokuWiki Overview, DokuWiki Foobar Syntax, wiki:welcome\n";
333
334        $this->assertEquals($expected_pseudodiff, $actual_pseudodiff);
335    }
336}
337