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_BASE . DOKU_SCRIPT . '?id=test_pagination', $tr6aPrev->attr('href')); 264 265 } 266} 267