18fed17f3SAndreas Gohr<?php 28fed17f3SAndreas Gohr 38fed17f3SAndreas Gohrnamespace dokuwiki\plugin\struct\test; 48fed17f3SAndreas Gohr 58fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta; 6850ad33eSAndreas Gohruse DOMWrap\Document; 78fed17f3SAndreas Gohr 88fed17f3SAndreas Gohr/** 98fed17f3SAndreas Gohr * Tests handling dynamic search parameters 108fed17f3SAndreas Gohr * 118fed17f3SAndreas Gohr * @group plugin_struct 128fed17f3SAndreas Gohr * @group plugins 138fed17f3SAndreas Gohr * 148fed17f3SAndreas Gohr */ 158fed17f3SAndreas Gohrclass SearchConfigParameterTest extends StructTest 168fed17f3SAndreas Gohr{ 173ff5da8aSAndreas Gohr /** @var int fixed revision timestamp */ 183ff5da8aSAndreas Gohr protected $fixedrev; 198fed17f3SAndreas Gohr 208fed17f3SAndreas Gohr public function setUp(): void 218fed17f3SAndreas Gohr { 228fed17f3SAndreas Gohr parent::setUp(); 238fed17f3SAndreas Gohr 248fed17f3SAndreas Gohr $this->loadSchemaJSON('schema1'); 258fed17f3SAndreas Gohr $this->loadSchemaJSON('schema2'); 268fed17f3SAndreas Gohr 278fed17f3SAndreas Gohr $as = mock\Assignments::getInstance(); 288fed17f3SAndreas Gohr 293ff5da8aSAndreas Gohr // save all data with the same fake revision 303ff5da8aSAndreas Gohr $this->fixedrev = time(); 313ff5da8aSAndreas Gohr 328fed17f3SAndreas Gohr $as->assignPageSchema('page01', 'schema1'); 338fed17f3SAndreas Gohr $this->saveData( 348fed17f3SAndreas Gohr 'page01', 358fed17f3SAndreas Gohr 'schema1', 368fed17f3SAndreas Gohr [ 378fed17f3SAndreas Gohr 'first' => 'first data', 388fed17f3SAndreas Gohr 'second' => ['second data', 'more data', 'even more'], 398fed17f3SAndreas Gohr 'third' => 'third data', 408fed17f3SAndreas Gohr 'fourth' => 'fourth data' 418fed17f3SAndreas Gohr ], 423ff5da8aSAndreas Gohr $this->fixedrev 438fed17f3SAndreas Gohr ); 448fed17f3SAndreas Gohr 458fed17f3SAndreas Gohr $as->assignPageSchema('page01', 'schema2'); 468fed17f3SAndreas Gohr $this->saveData( 478fed17f3SAndreas Gohr 'page01', 488fed17f3SAndreas Gohr 'schema2', 498fed17f3SAndreas Gohr [ 508fed17f3SAndreas Gohr 'afirst' => 'first data', 518fed17f3SAndreas Gohr 'asecond' => ['second data', 'more data', 'even more'], 528fed17f3SAndreas Gohr 'athird' => 'third data', 538fed17f3SAndreas Gohr 'afourth' => 'fourth data' 548fed17f3SAndreas Gohr ], 553ff5da8aSAndreas Gohr $this->fixedrev 568fed17f3SAndreas Gohr ); 578fed17f3SAndreas Gohr 588fed17f3SAndreas Gohr for ($i = 10; $i <= 20; $i++) { 598fed17f3SAndreas Gohr $as->assignPageSchema("page$i", 'schema2'); 608fed17f3SAndreas Gohr $this->saveData( 618fed17f3SAndreas Gohr "page$i", 628fed17f3SAndreas Gohr 'schema2', 638fed17f3SAndreas Gohr [ 648fed17f3SAndreas Gohr 'afirst' => "page$i first data", 658fed17f3SAndreas Gohr 'asecond' => ["page$i second data"], 668fed17f3SAndreas Gohr 'athird' => "page$i third data", 678fed17f3SAndreas Gohr 'afourth' => "page$i fourth data" 688fed17f3SAndreas Gohr ], 693ff5da8aSAndreas Gohr $this->fixedrev 708fed17f3SAndreas Gohr ); 718fed17f3SAndreas Gohr } 728fed17f3SAndreas Gohr } 738fed17f3SAndreas Gohr 748fed17f3SAndreas Gohr public function test_constructor() 758fed17f3SAndreas Gohr { 768fed17f3SAndreas Gohr global $INPUT; 778fed17f3SAndreas Gohr 788fed17f3SAndreas Gohr $data = [ 798fed17f3SAndreas Gohr 'schemas' => [ 808fed17f3SAndreas Gohr ['schema1', 'alias1'], 818fed17f3SAndreas Gohr ['schema2', 'alias2'], 828fed17f3SAndreas Gohr ], 838fed17f3SAndreas Gohr 'cols' => [ 848fed17f3SAndreas Gohr '%pageid%', 858fed17f3SAndreas Gohr 'first', 'second', 'third', 'fourth', 868fed17f3SAndreas Gohr 'afirst', 'asecond', 'athird', 'afourth', 878fed17f3SAndreas Gohr ] 888fed17f3SAndreas Gohr ]; 898fed17f3SAndreas Gohr 908fed17f3SAndreas Gohr // init with no parameters 918fed17f3SAndreas Gohr $params = []; 928fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 938fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 94fdf37115SAndreas Gohr $this->assertEquals($data, $searchConfig->getConf(), 'config as is'); 95fdf37115SAndreas Gohr $this->assertEquals($params, $dynamic->getURLParameters(), 'no dynamic parameters'); 968fed17f3SAndreas Gohr 978fed17f3SAndreas Gohr // init with sort 988fed17f3SAndreas Gohr $INPUT->set(meta\SearchConfigParameters::$PARAM_SORT, '^alias2.athird'); 998fed17f3SAndreas Gohr $params[meta\SearchConfigParameters::$PARAM_SORT] = '^schema2.athird'; 1008fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 1018fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 1028fed17f3SAndreas Gohr $this->assertEquals($params, $dynamic->getURLParameters()); 103fdf37115SAndreas Gohr $sorts = $searchConfig->getSorts(); 104fdf37115SAndreas Gohr $this->assertArrayHasKey('schema2.athird', $sorts); 105fdf37115SAndreas Gohr $this->assertInstanceOf(meta\Column::class, $sorts['schema2.athird'][0]); 106fdf37115SAndreas Gohr $this->assertEquals('schema2.athird', $sorts['schema2.athird'][0]->getFullQualifiedLabel()); 107fdf37115SAndreas Gohr $this->assertFalse($sorts['schema2.athird'][1], 'DESC sorting'); 108fdf37115SAndreas Gohr $this->assertTrue($sorts['schema2.athird'][2], 'case-insensitive sorting'); 1098fed17f3SAndreas Gohr 1108fed17f3SAndreas Gohr // init with offset 1118fed17f3SAndreas Gohr $INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 25); 1128fed17f3SAndreas Gohr $params[meta\SearchConfigParameters::$PARAM_OFFSET] = 25; 1138fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 1148fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 1158fed17f3SAndreas Gohr $this->assertEquals($params, $dynamic->getURLParameters()); 116fdf37115SAndreas Gohr $this->assertEquals(25, $searchConfig->getOffset(), 'offset set'); 1178fed17f3SAndreas Gohr 1188fed17f3SAndreas Gohr // init with filters 1198fed17f3SAndreas Gohr $_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['alias1.first*~'] = 'test'; 1208fed17f3SAndreas Gohr $_REQUEST[meta\SearchConfigParameters::$PARAM_FILTER]['afirst='] = 'test2'; 1218fed17f3SAndreas Gohr $params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema1.first*~]'] = 'test'; 1228fed17f3SAndreas Gohr $params[meta\SearchConfigParameters::$PARAM_FILTER . '[schema2.afirst=]'] = 'test2'; 1238fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 1248fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 1258fed17f3SAndreas Gohr $this->assertEquals($params, $dynamic->getURLParameters()); 126fdf37115SAndreas Gohr $filters = $this->getInaccessibleProperty($searchConfig, 'dynamicFilter'); 127fdf37115SAndreas Gohr 128fdf37115SAndreas Gohr $this->assertInstanceOf(meta\Column::class, $filters[0][0]); 129fdf37115SAndreas Gohr $this->assertEquals('schema1.first', $filters[0][0]->getFullQualifiedLabel(), 'full qualified column name'); 130fdf37115SAndreas Gohr $this->assertEquals('%test%', $filters[0][1], 'value with like placeholders'); 131fdf37115SAndreas Gohr $this->assertEquals('LIKE', $filters[0][2], 'comparator'); 132fdf37115SAndreas Gohr $this->assertEquals('AND', $filters[0][3], 'boolean operator'); 133fdf37115SAndreas Gohr 134fdf37115SAndreas Gohr $this->assertInstanceOf(meta\Column::class, $filters[1][0]); 135fdf37115SAndreas Gohr $this->assertEquals('schema2.afirst', $filters[1][0]->getFullQualifiedLabel(), 'full qualified column name'); 136fdf37115SAndreas Gohr $this->assertEquals('test2', $filters[1][1], 'value with no placeholders'); 137fdf37115SAndreas Gohr $this->assertEquals('=', $filters[1][2], 'comparator'); 138fdf37115SAndreas Gohr $this->assertEquals('AND', $filters[1][3], 'boolean operator'); 1398fed17f3SAndreas Gohr } 1408fed17f3SAndreas Gohr 1418fed17f3SAndreas Gohr public function test_filter() 1428fed17f3SAndreas Gohr { 1438fed17f3SAndreas Gohr $data = [ 1448fed17f3SAndreas Gohr 'schemas' => [ 1458fed17f3SAndreas Gohr ['schema1', 'alias1'], 1468fed17f3SAndreas Gohr ['schema2', 'alias2'], 1478fed17f3SAndreas Gohr ], 1488fed17f3SAndreas Gohr 'cols' => [ 1498fed17f3SAndreas Gohr '%pageid%', 1508fed17f3SAndreas Gohr 'first', 'second', 'third', 'fourth', 1518fed17f3SAndreas Gohr 'afirst', 'asecond', 'athird', 'afourth', 1528fed17f3SAndreas Gohr ] 1538fed17f3SAndreas Gohr ]; 1548fed17f3SAndreas Gohr 1558fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 1568fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 1578fed17f3SAndreas Gohr $expect = []; 1588fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1598fed17f3SAndreas Gohr 1608fed17f3SAndreas Gohr $dynamic->addFilter('first', '*~', 'test'); 1618fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test']]; 1628fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1638fed17f3SAndreas Gohr 1648fed17f3SAndreas Gohr $dynamic->addFilter('asecond', '*~', 'test2'); 1658fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test'], 'schema2.asecond' => ['*~', 'test2']]; 1668fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1678fed17f3SAndreas Gohr 1688fed17f3SAndreas Gohr // overwrite a filter 1698fed17f3SAndreas Gohr $dynamic->addFilter('asecond', '*~', 'foobar'); 1708fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test'], 'schema2.asecond' => ['*~', 'foobar']]; 1718fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1728fed17f3SAndreas Gohr 1738fed17f3SAndreas Gohr // overwrite a filter with blank removes 1748fed17f3SAndreas Gohr $dynamic->addFilter('asecond', '*~', ''); 1758fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test']]; 1768fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1778fed17f3SAndreas Gohr 1788fed17f3SAndreas Gohr // adding unknown filter does nothing 1798fed17f3SAndreas Gohr $dynamic->addFilter('nope', '*~', 'foobar'); 1808fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test']]; 1818fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1828fed17f3SAndreas Gohr 1838fed17f3SAndreas Gohr // removing unknown column does nothing 1848fed17f3SAndreas Gohr $dynamic->removeFilter('nope'); 1858fed17f3SAndreas Gohr $expect = ['schema1.first' => ['*~', 'test']]; 1868fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1878fed17f3SAndreas Gohr 1888fed17f3SAndreas Gohr $dynamic->removeFilter('first'); 1898fed17f3SAndreas Gohr $expect = []; 1908fed17f3SAndreas Gohr $this->assertEquals($expect, $dynamic->getFilters()); 1918fed17f3SAndreas Gohr } 1928fed17f3SAndreas Gohr 1938fed17f3SAndreas Gohr public function test_sort() 1948fed17f3SAndreas Gohr { 1958fed17f3SAndreas Gohr $data = [ 1968fed17f3SAndreas Gohr 'schemas' => [ 1978fed17f3SAndreas Gohr ['schema1', 'alias1'], 1988fed17f3SAndreas Gohr ['schema2', 'alias2'], 1998fed17f3SAndreas Gohr ], 2008fed17f3SAndreas Gohr 'cols' => [ 2018fed17f3SAndreas Gohr '%pageid%', 2028fed17f3SAndreas Gohr 'first', 'second', 'third', 'fourth', 2038fed17f3SAndreas Gohr 'afirst', 'asecond', 'athird', 'afourth', 2048fed17f3SAndreas Gohr ] 2058fed17f3SAndreas Gohr ]; 2068fed17f3SAndreas Gohr 2078fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 2088fed17f3SAndreas Gohr $dynamic = $searchConfig->getDynamicParameters(); 2098fed17f3SAndreas Gohr 210850ad33eSAndreas Gohr $dynamic->setSort('%pageid%'); 2118fed17f3SAndreas Gohr $param = $dynamic->getURLParameters(); 2128fed17f3SAndreas Gohr $this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param); 2138fed17f3SAndreas Gohr $this->assertEquals('%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]); 2148fed17f3SAndreas Gohr 2158fed17f3SAndreas Gohr $dynamic->setSort('%pageid%', false); 2168fed17f3SAndreas Gohr $param = $dynamic->getURLParameters(); 2178fed17f3SAndreas Gohr $this->assertArrayHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param); 2188fed17f3SAndreas Gohr $this->assertEquals('^%pageid%', $param[meta\SearchConfigParameters::$PARAM_SORT]); 2198fed17f3SAndreas Gohr 2208fed17f3SAndreas Gohr $dynamic->removeSort(); 2218fed17f3SAndreas Gohr $param = $dynamic->getURLParameters(); 2228fed17f3SAndreas Gohr $this->assertArrayNotHasKey(meta\SearchConfigParameters::$PARAM_SORT, $param); 2238fed17f3SAndreas Gohr } 2248fed17f3SAndreas Gohr 2258fed17f3SAndreas Gohr public function test_pagination() 2268fed17f3SAndreas Gohr { 2278fed17f3SAndreas Gohr global $INPUT; 2288fed17f3SAndreas Gohr 2298fed17f3SAndreas Gohr $data = [ 2308fed17f3SAndreas Gohr 'schemas' => [ 2318fed17f3SAndreas Gohr ['schema2', 'alias2'], 2328fed17f3SAndreas Gohr ], 2338fed17f3SAndreas Gohr 'cols' => [ 2348fed17f3SAndreas Gohr 'afirst' 2358fed17f3SAndreas Gohr ], 2368fed17f3SAndreas Gohr 'rownumbers' => '1', 2378fed17f3SAndreas Gohr 'limit' => '5', 238af0ce8d2SAndreas Gohr 'nesting' => 0, 239af0ce8d2SAndreas Gohr 'index' => 0, 240af0ce8d2SAndreas Gohr 'classes' => [], 2418fed17f3SAndreas Gohr ]; 2428fed17f3SAndreas Gohr 2438fed17f3SAndreas Gohr $R = new \Doku_Renderer_xhtml(); 2448fed17f3SAndreas Gohr // init with offset 2458fed17f3SAndreas Gohr $INPUT->set(meta\SearchConfigParameters::$PARAM_OFFSET, 5); 2468fed17f3SAndreas Gohr $searchConfig = new meta\SearchConfig($data); 2478fed17f3SAndreas Gohr $aggregationTable = new meta\AggregationTable('test_pagination', 'xhtml', $R, $searchConfig); 248af0ce8d2SAndreas Gohr $aggregationTable->startScope(); 2498fed17f3SAndreas Gohr $aggregationTable->render(); 250af0ce8d2SAndreas Gohr $aggregationTable->finishScope(); 2518fed17f3SAndreas Gohr 252850ad33eSAndreas Gohr $doc = new Document(); 25376e537bfSAndreas Gohr $doc->html($R->doc); 254850ad33eSAndreas Gohr $table = $doc->find('div.structaggregation'); 255850ad33eSAndreas Gohr 256850ad33eSAndreas Gohr $tr1 = $table->find(".row1"); 2578fed17f3SAndreas Gohr $this->assertEquals('6page14 first data', trim($tr1->text())); 2588fed17f3SAndreas Gohr $this->assertEquals('page14', $tr1->attr('data-pid')); 2598fed17f3SAndreas Gohr $this->assertEquals('0', $tr1->attr('data-rid')); 2603ff5da8aSAndreas Gohr $this->assertEquals($this->fixedrev, $tr1->attr('data-rev')); 2618fed17f3SAndreas Gohr 262850ad33eSAndreas Gohr $tr6aPrev = $table->find(".row6 a.prev"); 263*de7aa9acSAnna Dabrowska $this->assertEquals(DOKU_BASE . DOKU_SCRIPT . '?id=test_pagination', $tr6aPrev->attr('href')); 2648fed17f3SAndreas Gohr 2658fed17f3SAndreas Gohr } 2668fed17f3SAndreas Gohr} 267