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