1<?php
2
3class data_dummy_renderer extends Doku_Renderer_xhtml
4{
5
6    function internallink($id, $title = '', $ignored = null, $ignored2 = false, $linktype = 'content')
7    {
8        return "link: $id $title";
9    }
10
11}
12
13/**
14 * @group plugin_data
15 * @group plugins
16 */
17class helper_plugin_data_test extends DokuWikiTest
18{
19
20    protected $pluginsEnabled = array('data', 'sqlite');
21
22    public static function setUpBeforeClass(): void
23    {
24        parent::setUpBeforeClass();
25        // copy our own config files to the test directory
26        TestUtils::rcopy(dirname(DOKU_CONF), dirname(__FILE__) . '/conf');
27    }
28
29    function testCleanData()
30    {
31
32        $helper = new helper_plugin_data();
33
34        $this->assertEquals('', $helper->cleanData('   ', ''));
35        $this->assertEquals('', $helper->cleanData('', ''));
36        $this->assertEquals('', $helper->cleanData(null, ''));
37        $this->assertEquals('', $helper->cleanData(false, ''));
38
39        $this->assertEquals('', $helper->cleanData('', 'dt'));
40        $this->assertEquals('', $helper->cleanData('this is not a date', 'dt'));
41        $this->assertEquals('1234-01-01', $helper->cleanData('1234-1-1', 'dt'));
42        $this->assertEquals('1234-01-01', $helper->cleanData('1234-01-01', 'dt'));
43        $this->assertEquals('%now%', $helper->cleanData('%now%', 'dt'));
44        $this->assertEquals('', $helper->cleanData('1234-01-011', 'dt'));
45
46        $this->assertEquals('http://bla', $helper->cleanData('bla', 'url'));
47        $this->assertEquals('http://bla', $helper->cleanData('http://bla', 'url'));
48        $this->assertEquals('https://bla', $helper->cleanData('https://bla', 'url'));
49        $this->assertEquals('tell://bla', $helper->cleanData('tell://bla', 'url'));
50
51        $this->assertEquals('bla@bla.de', $helper->cleanData('bla@bla.de', 'mail'));
52        $this->assertEquals('bla@bla.de bla', $helper->cleanData('bla@bla.de bla', 'mail'));
53        $this->assertEquals('bla@bla.de bla word', $helper->cleanData('bla@bla.de bla word', 'mail'));
54        $this->assertEquals('bla@bla.de bla bla word', $helper->cleanData('bla bla@bla.de bla word', 'mail'));
55        $this->assertEquals('bla@bla.de bla bla word', $helper->cleanData(' bla bla@bla.de bla word ', 'mail'));
56
57        $this->assertEquals('123', $helper->cleanData('123', 'page'));
58        $this->assertEquals('123_123', $helper->cleanData('123 123', 'page'));
59        $this->assertEquals('123', $helper->cleanData('123', 'nspage'));
60
61        $this->assertEquals('test', $helper->cleanData('test', ''));
62
63        $this->assertEquals('test', $helper->cleanData('test', array('type' => '')));
64        $this->assertEquals('', $helper->cleanData('test', array('type' => '', 'enum' => 'some other')));
65    }
66
67    function testColumn()
68    {
69        global $conf;
70        $helper = new helper_plugin_data();
71
72        $this->assertEquals($this->createColumnEntry('type', false, 'type', 'type', 'type', ''), $helper->column('type'));
73        $this->assertEquals($this->createColumnEntry('types', true, 'type', 'type', 'type', ''), $helper->column('types'));
74        $this->assertEquals($this->createColumnEntry('', false, '', '', '', ''), $helper->column(''));
75        $this->assertEquals($this->createColumnEntry('type_url', false, 'type', 'type', 'type', 'url'), $helper->column('type_url'));
76        $this->assertEquals($this->createColumnEntry('type_urls', true, 'type', 'type', 'type', 'url'), $helper->column('type_urls'));
77
78        $this->assertEquals($this->createColumnEntry('type_hidden', false, 'type', 'type', 'type', 'hidden'), $helper->column('type_hidden'));
79        $this->assertEquals($this->createColumnEntry('type_hiddens', true, 'type', 'type', 'type', 'hidden'), $helper->column('type_hiddens'));
80
81        $this->assertEquals($this->createColumnEntry('%title%', false, '%title%', '%title%', 'Page', 'title'), $helper->column('%title%'));
82        $this->assertEquals($this->createColumnEntry('%pageid%', false, '%pageid%', '%pageid%', 'Title', 'page'), $helper->column('%pageid%'));
83        $this->assertEquals($this->createColumnEntry('%class%', false, '%class%', '%class%', 'Page Class', ''), $helper->column('%class%'));
84        $this->assertEquals($this->createColumnEntry('%lastmod%', false, '%lastmod%', '%lastmod%', 'Last Modified', 'timestamp'), $helper->column('%lastmod%'));
85
86        $this->assertEquals($this->createColumnEntry('Type', false, 'type', 'Type', 'Type', ''), $helper->column('Type'));
87
88
89        // test translated key name
90        $this->assertEquals($this->createColumnEntry('trans_urls', true, 'trans', 'trans', 'Translated Title', 'url'), $helper->column('trans_urls'));
91        // retry in different language
92        $conf['lang'] = 'de';
93        $helper = new helper_plugin_data();
94        $this->assertEquals($this->createColumnEntry('trans_urls', true, 'trans', 'trans', 'Übersetzter Titel', 'url'), $helper->column('trans_urls'));
95    }
96
97    function testAddPrePostFixes()
98    {
99        global $conf;
100        $helper = new helper_plugin_data();
101
102        $this->assertEquals('value', $helper->addPrePostFixes('', 'value'));
103        $this->assertEquals('prevaluepost', $helper->addPrePostFixes('', 'value', 'pre', 'post'));
104        $this->assertEquals('valuepost', $helper->addPrePostFixes('', 'value', '', 'post'));
105        $this->assertEquals('prevalue', $helper->addPrePostFixes('', 'value', 'pre'));
106        $this->assertEquals('prevaluepost', $helper->addPrePostFixes(array('prefix' => 'pre', 'postfix' => 'post'), 'value'));
107
108        $conf['lang'] = 'en';
109        $this->assertEquals('envalue', $helper->addPrePostFixes(array('prefix' => '%lang%'), 'value'));
110
111        $this->assertEquals('value', $helper->addPrePostFixes(array('prefix' => '%trans%'), 'value'));
112
113        $plugininstalled = in_array('translation', plugin_list('helper', $all = true));
114        if (!$plugininstalled) $this->markTestSkipped('Pre-condition not satisfied: translation plugin must be installed');
115
116        if ($plugininstalled && plugin_enable('translation')) {
117            global $ID;
118            $conf['plugin']['translation']['translations'] = 'de';
119            $ID = 'de:somepage';
120            $this->assertEquals('de:value', $helper->addPrePostFixes(array('prefix' => '%trans%:'), 'value'));
121        }
122
123    }
124
125    function testResolveData()
126    {
127        $helper = new helper_plugin_data();
128
129        $this->assertEquals('tom', $helper->resolveData('tom', 'name'));
130        $this->assertEquals('jerry', $helper->resolveData('jerry', 'name'));
131
132        $this->assertEquals('wiki:syntax Formatting Syntax', $helper->resolveData('wiki:syntax', 'name_title'));
133        $this->assertEquals('none:existing ', $helper->resolveData('none:existing', 'name_title'));
134    }
135
136    function testFormatData()
137    {
138        global $conf;
139        global $ID;
140        $ID = '';
141
142        $helper = new helper_plugin_data();
143        $renderer = new data_dummy_renderer();
144
145        $this->assertEquals('value1, value2, val',
146            $helper->formatData(array('type' => ''), "value1\n value2\n val", $renderer));
147
148        $this->assertEquals('link: :page ',
149            $helper->formatData(array('type' => 'page'), "page", $renderer));
150
151        $this->assertEquals('link: :page title',
152            $helper->formatData(array('type' => 'title'), "page|title", $renderer));
153
154        $this->assertEquals('link: page title',
155            $helper->formatData(array('type' => 'pageid'), "page|title", $renderer));
156
157        $this->assertEquals('link: :key:page ',
158            $helper->formatData(array('type' => 'nspage', 'key' => 'key'), "page", $renderer));
159
160        $conf['mailguard'] = '';
161        $this->assertEquals('<a href="mailto:pa:ge" class="mail" title="pa:ge">pa:ge</a>',
162            $helper->formatData(array('type' => 'mail'), "pa:ge", $renderer));
163
164        $this->assertEquals('<a href="mailto:pa:ge" class="mail" title="pa:ge">some user</a>',
165            $helper->formatData(array('type' => 'mail'), "pa:ge some user", $renderer));
166
167        $conf['mailguard'] = 'visible';
168        $this->assertEquals('<a href="mailto:pa%3Age" class="mail" title="pa%3Age">pa:ge</a>',
169            $helper->formatData(array('type' => 'mail'), "pa:ge", $renderer));
170
171        $this->assertEquals('<a href="mailto:pa%3Age" class="mail" title="pa%3Age">some user</a>',
172            $helper->formatData(array('type' => 'mail'), "pa:ge some user", $renderer));
173
174        $this->assertEquals('<a href=\'url\' class=\'urlextern\' rel="nofollow">url</a>',
175            $helper->formatData(array('type' => 'url'), "url", $renderer));
176
177        $this->assertEquals('<a href="' . wl('start', array('dataflt[0]' => '_=value')) . '" title="Show pages matching \'value\'" class="wikilink1">value</a>',
178            $helper->formatData(array('type' => 'tag', 'key' => ''), "value", $renderer));
179
180        $this->assertEquals(strftime('%Y/%m/%d %H:%M', 1234567),
181            $helper->formatData(array('type' => 'timestamp'), "1234567", $renderer));
182
183        $this->assertEquals('<strong>bla</strong>',
184            $helper->formatData(array('type' => 'wiki'), '|**bla**', $renderer));
185
186
187        $this->assertEquals('<a rel="lightbox" href="' . ml('wiki:dokuwiki-128.png', array('cache' => null)) . '" class="media" title="wiki:dokuwiki-128.png"><img src="' . ml('wiki:dokuwiki-128.png', array('w' => 300, 'cache' => null)) . '" class="media" loading="lazy" title=": dokuwiki-128.png" alt=": dokuwiki-128.png" width="300" /></a>',
188            $helper->formatData(array('type' => 'img300', 'key' => ''), 'wiki:dokuwiki-128.png', $renderer));
189    }
190
191    function testReplacePlaceholdersInSQL()
192    {
193        global $USERINFO;
194        global $INPUT;
195        $helper = new helper_plugin_data();
196
197        $data = array('sql' => '%user%');
198        $INPUT->server->set('REMOTE_USER', 'test');
199        $helper->replacePlaceholdersInSQL($data);
200        $this->assertEquals('test', $data['sql']);
201
202        $data = array('sql' => '%groups%');
203        $USERINFO['grps'] = array('test', 'admin');
204        $helper->replacePlaceholdersInSQL($data);
205        $this->assertEquals("test','admin", $data['sql']);
206
207        $data = array('sql' => '%now%');
208        $helper->replacePlaceholdersInSQL($data);
209        $this->assertRegExp('/[0-9]{4}-[0-9]{2}-[0-9]{2}/', $data['sql']);
210
211        $data = array('sql' => '%lang%');
212        $helper->replacePlaceholdersInSQL($data);
213        $this->assertEquals('en', $data['sql']);
214    }
215
216    protected function createColumnEntry($name, $multi, $key, $origkey, $title, $type)
217    {
218        return array(
219            'colname' => $name,
220            'multi' => $multi,
221            'key' => $key,
222            'origkey' => $origkey,
223            'title' => $title,
224            'type' => $type
225        );
226    }
227
228    public function testNoSqlPlugin()
229    {
230        plugin_disable('sqlite');
231        $this->expectException(\Exception::class);
232        $helper = new helper_plugin_data();
233        $helper->getDB();
234    }
235
236    public function testParseFilter()
237    {
238        $helper = new helper_plugin_data();
239
240        $this->assertEquals($this->createFilterArray('name', "'tom'", '=', 'name_some', 'some')
241            , $helper->parseFilter('name_some = tom'));
242
243        $this->assertEquals($this->createFilterArray('name', "'tom'", '=', 'name', '')
244            , $helper->parseFilter('name = tom'));
245
246        $this->assertEquals($this->createFilterArray('name', "'tom'", '!=', 'name', '')
247            , $helper->parseFilter('name != tom'));
248
249        $this->assertEquals($this->createFilterArray('name', "'tom'", '!=', 'name', '')
250            , $helper->parseFilter('name <> tom'));
251
252        $this->assertEquals($this->createFilterArray('name', "'tom'", '<', 'name', '')
253            , $helper->parseFilter('name < tom'));
254
255        $this->assertEquals($this->createFilterArray('name', "'tom'", '>', 'name', '')
256            , $helper->parseFilter('name > tom'));
257
258        $this->assertEquals($this->createFilterArray('name', "'tom'", '<=', 'name', '')
259            , $helper->parseFilter('name <= tom'));
260
261        $this->assertEquals($this->createFilterArray('name', "'tom'", '>=', 'name', '')
262            , $helper->parseFilter('name >= tom'));
263
264        $this->assertEquals($this->createFilterArray('name', "'tom'", 'LIKE', 'name', '')
265            , $helper->parseFilter('name ~ tom'));
266
267        $this->assertEquals($this->createFilterArray('name', "'%tom%'", 'LIKE', 'name', '')
268            , $helper->parseFilter('name *~ tom'));
269
270        $this->assertEquals($this->createFilterArray('name', "'tom'", 'NOT LIKE', 'name', '')
271            , $helper->parseFilter('name !~ tom'));
272
273        $this->assertEquals($this->createFilterArray('name', "'%tom'", 'LIKE', 'name', '')
274            , $helper->parseFilter('name ~ *tom'));
275
276        $this->assertEquals($this->createFilterArray('name', "'tom%'", 'LIKE', 'name', '')
277            , $helper->parseFilter('name ~ tom*'));
278
279        $this->assertEquals($this->createFilterArray('name', "'%tom%'", 'LIKE', 'name', '')
280            , $helper->parseFilter('name ~ *tom*'));
281
282        $this->assertEquals($this->createFilterArray('name', "'tom'", 'IN(', 'name', '')
283            , $helper->parseFilter('name ~~ tom'));
284
285        $this->assertEquals($this->createFilterArray('name', "'t''om','john*'", 'IN(', 'name', '')
286            , $helper->parseFilter("name ~~ t'om,john*"));
287
288        $this->assertEquals(false, $helper->parseFilter('name is *tom*'));
289        $this->assertEquals(false, $helper->parseFilter(''));
290    }
291
292    protected function createFilterArray($key, $value, $compare, $colname, $type)
293    {
294        return array(
295            'key' => $key,
296            'value' => $value,
297            'compare' => $compare,
298            'colname' => $colname,
299            'type' => $type
300        );
301    }
302
303    public function testGetFilters()
304    {
305        $helper = new helper_plugin_data();
306
307        $this->assertEquals(array(), $helper->getFilters());
308
309        $_REQUEST['dataflt'] = 'name = tom';
310        $this->assertEquals(array($this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND')),
311            $helper->getFilters());
312
313        $_REQUEST['dataflt'] = array();
314        $_REQUEST['dataflt'][] = 'name = tom';
315        $this->assertEquals(array($this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND')),
316            $helper->getFilters());
317
318        $_REQUEST['dataflt'] = array();
319        $_REQUEST['dataflt'][] = 'name = tom';
320        $_REQUEST['dataflt'][] = 'unit_url = dokuwiki.org';
321        $this->assertEquals(
322            array(
323                $this->createFilterArrayListEntry('name', "'tom'", '=', 'name', '', 'AND'),
324                $this->createFilterArrayListEntry('unit', "'http://dokuwiki.org'", '=', 'unit_url', 'url', 'AND')
325            ),
326            $helper->getFilters());
327    }
328
329    private function createFilterArrayListEntry($key, $value, $compare, $colname, $type, $logic)
330    {
331        $item = $this->createFilterArray($key, $value, $compare, $colname, $type);
332        $item['logic'] = $logic;
333        return $item;
334    }
335
336    public function testA2UA()
337    {
338        $helper = new helper_plugin_data();
339
340        $array = array(
341            'id' => '1',
342            'name' => 'tom'
343        );
344
345        $result = array(
346            'table[id]' => '1',
347            'table[name]' => 'tom'
348        );
349
350        $this->assertEquals($result, $helper->a2ua('table', $array));
351    }
352
353    public function testMakeTranslationReplacement()
354    {
355        $helper = new helper_plugin_data();
356
357        $this->assertEquals('en', $helper->makeTranslationReplacement('%lang%'));
358        $this->assertEquals('', $helper->makeTranslationReplacement('%trans%'));
359
360        $plugininstalled = in_array('translation', plugin_list('helper', $all = true));
361        if (!$plugininstalled) $this->markTestSkipped('Pre-condition not satisfied: translation plugin must be installed');
362
363        if ($plugininstalled && plugin_enable('translation')) {
364            global $conf;
365            global $ID;
366            $conf['plugin']['translation']['translations'] = 'de';
367            $ID = 'de:somepage';
368            $this->assertEquals('en', $helper->makeTranslationReplacement('%lang%'));
369            $this->assertEquals('de', $helper->makeTranslationReplacement('%trans%'));
370        }
371    }
372}
373