1<?php
2
3namespace dokuwiki\plugin\struct\test;
4
5use dokuwiki\plugin\struct\meta;
6
7/**
8 * Tests handling dynamic search parameters
9 *
10 * @group plugin_struct
11 * @group plugins
12 *
13 */
14class SearchConfigParameter_struct_test extends StructTest
15{
16
17    public function setUp(): void
18    {
19        parent::setUp();
20
21        $this->loadSchemaJSON('schema1');
22        $this->loadSchemaJSON('schema2');
23
24        $as = mock\Assignments::getInstance();
25
26        $as->assignPageSchema('page01', 'schema1');
27        $this->saveData(
28            'page01',
29            'schema1',
30            array(
31                'first' => 'first data',
32                'second' => array('second data', 'more data', 'even more'),
33                'third' => 'third data',
34                'fourth' => 'fourth data'
35            ),
36            time()
37        );
38
39        $as->assignPageSchema('page01', 'schema2');
40        $this->saveData(
41            'page01',
42            'schema2',
43            array(
44                'afirst' => 'first data',
45                'asecond' => array('second data', 'more data', 'even more'),
46                'athird' => 'third data',
47                'afourth' => 'fourth data'
48            ),
49            time()
50        );
51
52        for ($i = 10; $i <= 20; $i++) {
53            $as->assignPageSchema("page$i", 'schema2');
54            $this->saveData(
55                "page$i",
56                'schema2',
57                array(
58                    'afirst' => "page$i first data",
59                    'asecond' => array("page$i second data"),
60                    'athird' => "page$i third data",
61                    'afourth' => "page$i fourth data"
62                ),
63                time()
64            );
65        }
66    }
67
68    public function test_constructor()
69    {
70        global $INPUT;
71
72        $data = array(
73            'schemas' => array(
74                array('schema1', 'alias1'),
75                array('schema2', 'alias2'),
76            ),
77            'cols' => array(
78                '%pageid%',
79                'first', 'second', 'third', 'fourth',
80                'afirst', 'asecond', 'athird', 'afourth',
81            )
82        );
83
84        // init with no parameters
85        $expect = $data;
86        $params = array();
87        $searchConfig = new meta\SearchConfig($data);
88        $dynamic = $searchConfig->getDynamicParameters();
89        $this->assertEquals($expect, $searchConfig->getConf());
90        $this->assertEquals($params, $dynamic->getURLParameters());
91
92        // init with sort
93        $INPUT->set(meta\SearchConfigParameters::$PARAM_SORT, '^alias2.athird');
94        $expect['sort'] = array(array('schema2.athird', false));
95        $params[meta\SearchConfigParameters::$PARAM_SORT] = '^schema2.athird';
96        $searchConfig = new meta\SearchConfig($data);
97        $dynamic = $searchConfig->getDynamicParameters();
98        $this->assertEquals($expect, $searchConfig->getConf());
99        $this->assertEquals($params, $dynamic->getURLParameters());
100
101        // init with offset
102        $INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 25);
103        $expect['offset'] = 25;
104        $params[meta\SearchConfigParameters::$PARAM_OFFSET] = 25;
105        $searchConfig = new meta\SearchConfig($data);
106        $dynamic = $searchConfig->getDynamicParameters();
107        $this->assertEquals($expect, $searchConfig->getConf());
108        $this->assertEquals($params, $dynamic->getURLParameters());
109
110        // init with filters
111        $_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['alias1.first*~'] = 'test';
112        $_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['afirst='] = 'test2';
113        $expect['filter'] = array(
114            array('schema1.first', '*~', 'test', 'AND'),
115            array('schema2.afirst', '=', 'test2', 'AND')
116        );
117        $params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema1.first*~]'] = 'test';
118        $params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema2.afirst=]'] = 'test2';
119        $searchConfig = new meta\SearchConfig($data);
120        $dynamic = $searchConfig->getDynamicParameters();
121        $this->assertEquals($expect, $searchConfig->getConf());
122        $this->assertEquals($params, $dynamic->getURLParameters());
123    }
124
125    public function test_filter()
126    {
127        $data = array(
128            'schemas' => array(
129                array('schema1', 'alias1'),
130                array('schema2', 'alias2'),
131            ),
132            'cols' => array(
133                '%pageid%',
134                'first', 'second', 'third', 'fourth',
135                'afirst', 'asecond', 'athird', 'afourth',
136            )
137        );
138
139        $searchConfig = new meta\SearchConfig($data);
140        $dynamic = $searchConfig->getDynamicParameters();
141        $expect = array();
142        $this->assertEquals($expect, $dynamic->getFilters());
143
144        $dynamic->addFilter('first', '*~', 'test');
145        $expect = array('schema1.first' => array('*~', 'test'));
146        $this->assertEquals($expect, $dynamic->getFilters());
147
148        $dynamic->addFilter('asecond', '*~', 'test2');
149        $expect = array('schema1.first' => array('*~', 'test'), 'schema2.asecond' => array('*~', 'test2'));
150        $this->assertEquals($expect, $dynamic->getFilters());
151
152        // overwrite a filter
153        $dynamic->addFilter('asecond', '*~', 'foobar');
154        $expect = array('schema1.first' => array('*~', 'test'), 'schema2.asecond' => array('*~', 'foobar'));
155        $this->assertEquals($expect, $dynamic->getFilters());
156
157        // overwrite a filter with blank removes
158        $dynamic->addFilter('asecond', '*~', '');
159        $expect = array('schema1.first' => array('*~', 'test'));
160        $this->assertEquals($expect, $dynamic->getFilters());
161
162        // adding unknown filter does nothing
163        $dynamic->addFilter('nope', '*~', 'foobar');
164        $expect = array('schema1.first' => array('*~', 'test'));
165        $this->assertEquals($expect, $dynamic->getFilters());
166
167        // removing unknown column does nothing
168        $dynamic->removeFilter('nope');
169        $expect = array('schema1.first' => array('*~', 'test'));
170        $this->assertEquals($expect, $dynamic->getFilters());
171
172        $dynamic->removeFilter('first');
173        $expect = array();
174        $this->assertEquals($expect, $dynamic->getFilters());
175    }
176
177    public function test_sort()
178    {
179        $data = array(
180            'schemas' => array(
181                array('schema1', 'alias1'),
182                array('schema2', 'alias2'),
183            ),
184            'cols' => array(
185                '%pageid%',
186                'first', 'second', 'third', 'fourth',
187                'afirst', 'asecond', 'athird', 'afourth',
188            )
189        );
190
191        $searchConfig = new meta\SearchConfig($data);
192        $dynamic = $searchConfig->getDynamicParameters();
193
194        $dynamic->setSort('%pageid%', true);
195        $conf = $dynamic->updateConfig($data);
196        $param = $dynamic->getURLParameters();
197        $this->assertEquals(array(array('%pageid%', true)), $conf['sort']);
198        $this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
199        $this->assertEquals('%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]);
200
201        $dynamic->setSort('%pageid%', false);
202        $conf = $dynamic->updateConfig($data);
203        $param = $dynamic->getURLParameters();
204        $this->assertEquals(array(array('%pageid%', false)), $conf['sort']);
205        $this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
206        $this->assertEquals('^%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]);
207
208        $dynamic->removeSort();
209        $conf = $dynamic->updateConfig($data);
210        $param = $dynamic->getURLParameters();
211        $this->assertArrayNotHasKey('sort', $conf);
212        $this->assertArrayNotHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param);
213    }
214
215    public function test_pagination()
216    {
217        global $INPUT;
218
219        $data = array(
220            'schemas' => array(
221                array('schema2', 'alias2'),
222            ),
223            'cols' => array(
224                'afirst'
225            ),
226            'rownumbers' => '1',
227            'limit' => '5',
228        );
229
230        $R = new \Doku_Renderer_xhtml();
231        // init with offset
232        $INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 5);
233        //$params[meta\SearchConfigParameters::$PARAM_OFFSET] = 25;
234        $searchConfig = new meta\SearchConfig($data);
235        $aggregationTable = new meta\AggregationTable('test_pagination', 'xhtml', $R, $searchConfig);
236        $aggregationTable->render();
237
238        $rev = time();
239        $expect_html = '<div class="structaggregation"><div class="table"><table class="inline">
240	<thead>
241	<tr class="row0">
242		<th class="col0">#</th><th  data-field="schema2.afirst"><a href="/./doku.php?id=test_pagination&amp;ofs=5&amp;srt=schema2.afirst" class="" title="Sort by this column">afirst</a></th>
243	</tr>
244	</thead>
245	<tbody>
246	<tr class="row1" data-pid="page14" data-rev="' . $rev . '" data-rid="0"><td class="col0">6</td><td class="col1">page14 first data</td>
247	</tr>
248	<tr class="row2" data-pid="page15" data-rev="' . $rev . '" data-rid="0"><td class="col0">7</td><td class="col1">page15 first data</td>
249	</tr>
250	<tr class="row3" data-pid="page16" data-rev="' . $rev . '" data-rid="0"><td class="col0">8</td><td class="col1">page16 first data</td>
251	</tr>
252	<tr class="row4" data-pid="page17" data-rev="' . $rev . '" data-rid="0"><td class="col0">9</td><td class="col1">page17 first data</td>
253	</tr>
254	<tr class="row5" data-pid="page18" data-rev="' . $rev . '" data-rid="0"><td class="col0">10</td><td class="col1">page18 first data</td>
255	</tr>
256	</tbody>
257	<tfoot>
258	<tr class="row6">
259		<th class="col0" colspan="2"><a href="/./doku.php?id=test_pagination" class="prev">Previous page</a><a href="/./doku.php?id=test_pagination&amp;ofs=10" class="next">Next page</a></th>
260	</tr>
261	</tfoot>
262</table></div>
263</div>';
264
265        $pq = \phpQuery::newDocument($expect_html);
266        $tr1 = $pq->find(".row1");
267        $this->assertEquals('6page14 first data', trim($tr1->text()));
268        $this->assertEquals('page14', $tr1->attr('data-pid'));
269        $this->assertEquals('0', $tr1->attr('data-rid'));
270        $this->assertEquals($rev, $tr1->attr('data-rev'));
271
272        $tr6aPrev = $pq->find(".row6 a.prev");
273        $this->assertEquals('/./doku.php?id=test_pagination', $tr6aPrev->attr('href'));
274
275    }
276}
277