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 AccessTableDataDBTest 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            [
36                'testcolumn' => 'value1',
37                'testMulitColumn' => ['value2.1', 'value2.2']
38            ],
39            123
40        );
41
42        // revision 2
43        $this->saveData(
44            'testpage',
45            'testtable',
46            [
47                'testcolumn' => 'value1a',
48                'testMulitColumn' => ['value2.1a', 'value2.2a']
49            ],
50            789
51        );
52
53        // revision 1 of different page
54        $this->saveData(
55            'testpage2',
56            'testtable',
57            [
58                'testcolumn' => 'value1a',
59                'testMulitColumn' => ['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 = [
73            [
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 = [
91            [
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 = [
109            'testMulitColumn' => ['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 = [
127            'testMulitColumn' => ['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 = [
143            'testMulitColumn' => ['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 = [
161            'testMulitColumn' => ['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
172    /**
173     * @noinspection SqlNoDataSourceInspection
174     * @noinspection SqlDialectInspection
175     */
176    public function test_saveData()
177    {
178        // arrange
179        $testdata = [
180            'testcolumn' => 'value1_saved',
181            'testMulitColumn' => [
182                "value2.1_saved",
183                "value2.2_saved",
184                "value2.3_saved",
185            ]
186        ];
187
188        // act
189        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
190        $result = $schemaData->saveData($testdata);
191
192        // assert
193        $actual_saved_single = $this->sqlite->queryRecord(
194            "SELECT pid, col1, col2 FROM data_testtable WHERE pid = ? ORDER BY rev DESC LIMIT 1",
195            ['testpage']
196        );
197        $expected_saved_single = [
198            'pid' => 'testpage',
199            'col1' => 'value1_saved',
200            'col2' => 'value2.1_saved' # copy of the multi-value's first value
201        ];
202
203        $actual_saved_multi = $this->sqlite->queryAll(
204            "SELECT colref, row, value FROM multi_testtable WHERE pid = ? ORDER BY rev DESC LIMIT 3",
205            ['testpage']
206        );
207        $expected_saved_multi = [
208            [
209                'colref' => '2',
210                'row' => '1',
211                'value' => "value2.1_saved"
212            ],
213            [
214                'colref' => '2',
215                'row' => '2',
216                'value' => "value2.2_saved"
217            ],
218            [
219                'colref' => '2',
220                'row' => '3',
221                'value' => "value2.3_saved"
222            ]
223        ];
224
225        $this->assertTrue($result, 'should be true on success');
226        $this->assertEquals($expected_saved_single, $actual_saved_single, 'single value fields');
227        $this->assertEquals($expected_saved_multi, $actual_saved_multi, 'multi value fields');
228    }
229
230    public function test_getDataFromDB_clearData()
231    {
232
233        // act
234        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
235        $schemaData->clearData();
236        $actual_data = $schemaData->getDataFromDB();
237
238        $expected_data = [
239            [
240                'out1' => '',
241                'out2' => null,
242                'PID' => 'testpage',
243            ]
244        ];
245
246        $this->assertEquals($expected_data, $actual_data, '');
247    }
248
249    public function test_getData_clearData()
250    {
251
252        // act
253        $schemaData = mock\AccessTable::getPageAccess('testtable', 'testpage');
254        $schemaData->clearData();
255        $actual_data = $schemaData->getData();
256
257        // assert
258        $this->assertEquals([], $actual_data['testMulitColumn']->getValue());
259        $this->assertEquals(null, $actual_data['testcolumn']->getValue());
260    }
261
262    public function test_getData_skipEmpty()
263    {
264        // arrange
265        $testdata = [
266            'testcolumn' => '',
267            'testMulitColumn' => [
268                "value2.1_saved",
269                "value2.2_saved",
270            ]
271        ];
272        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
273        $schemaData->saveData($testdata);
274
275        // act
276        $schemaData->optionSkipEmpty(true);
277        $actual_data = $schemaData->getData();
278
279        $expected_data = ['value2.1_saved', 'value2.2_saved'];
280
281        // assert
282        $this->assertEquals(1, count($actual_data), 'There should be only one value returned and the empty value skipped');
283        $this->assertEquals($expected_data, $actual_data['testMulitColumn']->getValue());
284    }
285
286    public function test_getDataArray_skipEmpty()
287    {
288        // arrange
289        $testdata = [
290            'testcolumn' => '',
291            'testMulitColumn' => [
292                "value2.1_saved",
293                "value2.2_saved",
294            ]
295        ];
296        $schemaData = meta\AccessTable::getPageAccess('testtable', 'testpage');
297        $schemaData->saveData($testdata);
298
299        // act
300        $schemaData->optionSkipEmpty(true);
301        $actual_data = $schemaData->getDataArray();
302
303        $expected_data = [
304            'testMulitColumn' => ['value2.1_saved', 'value2.2_saved']
305        ];
306
307        // assert
308        $this->assertEquals(1, count($actual_data), 'There should be only one value returned and the empty value skipped');
309        $this->assertEquals($expected_data, $actual_data);
310    }
311
312    public function test_pseudodiff()
313    {
314        $this->loadSchemaJSON('pageschema');
315        $this->saveData(
316            'syntax',
317            'pageschema',
318            [
319                'singlepage' => 'wiki:dokuwiki',
320                'multipage' => ['wiki:dokuwiki', 'wiki:syntax', 'wiki:welcome'],
321                'singletitle' => 'wiki:dokuwiki',
322                'multititle' => ['wiki:dokuwiki', 'wiki:syntax', 'wiki:welcome'],
323            ],
324            time()
325        );
326
327        // make sure titles for some pages are known (not for wiki:welcome)
328        $pageMeta = new \dokuwiki\plugin\struct\meta\PageMeta('wiki:dokuwiki');
329        $pageMeta->setTitle('DokuWiki Overview');
330        $pageMeta = new \dokuwiki\plugin\struct\meta\PageMeta('wiki:syntax');
331        $pageMeta->setTitle('DokuWiki Foobar Syntax');
332        $pageMeta->savePageData();
333
334        $schemaData = meta\AccessTable::getPageAccess('pageschema', 'syntax');
335        $actual_pseudodiff = $schemaData->getDataPseudoSyntax();
336        $expected_pseudodiff = "pageschema.singlepage : wiki:dokuwiki
337pageschema.multipage : wiki:dokuwiki, wiki:syntax, wiki:welcome
338pageschema.singletitle : DokuWiki Overview
339pageschema.multititle : DokuWiki Overview, DokuWiki Foobar Syntax, wiki:welcome\n";
340
341        $this->assertEquals($expected_pseudodiff, $actual_pseudodiff);
342    }
343}
344