18fed17f3SAndreas Gohr<?php 28fed17f3SAndreas Gohr 38fed17f3SAndreas Gohrnamespace dokuwiki\plugin\struct\test; 48fed17f3SAndreas Gohr 58fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta\AccessTablePage; 68fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta\ConfigParser; 78fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta\PageMeta; 88fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AccessTable as MockAccessTableAlias; 98fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AggregationEditorTable as MockAggregationEditorTableAlias; 108fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AggregationTable as MockAggregationTableAlias; 118fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\SearchConfig as MockSearchConfigAlias; 128fed17f3SAndreas Gohr 138fed17f3SAndreas Gohr/** 148fed17f3SAndreas Gohr * Testing serial data 158fed17f3SAndreas Gohr * 168fed17f3SAndreas Gohr * @group plugin_struct 178fed17f3SAndreas Gohr * @group plugins 188fed17f3SAndreas Gohr */ 198fed17f3SAndreas Gohrclass AggregationResultsTest extends StructTest 208fed17f3SAndreas Gohr{ 218fed17f3SAndreas Gohr protected $sqlite; 228fed17f3SAndreas Gohr 238fed17f3SAndreas Gohr public function setUp(): void 248fed17f3SAndreas Gohr { 258fed17f3SAndreas Gohr parent::setUp(); 268fed17f3SAndreas Gohr 278fed17f3SAndreas Gohr $sqlite = plugin_load('helper', 'struct_db'); 288fed17f3SAndreas Gohr $this->sqlite = $sqlite->getDB(); 298fed17f3SAndreas Gohr 308fed17f3SAndreas Gohr $this->loadSchemaJSON('schema1'); 318fed17f3SAndreas Gohr 328fed17f3SAndreas Gohr $assignments = mock\Assignments::getInstance(); 338fed17f3SAndreas Gohr $assignments->clear(true); 348fed17f3SAndreas Gohr 3571769bc3SAndreas Gohr // different values for each entry 3671769bc3SAndreas Gohr $second = [ 3771769bc3SAndreas Gohr ['green', 'red'], 3871769bc3SAndreas Gohr ['green', 'blue'], 3971769bc3SAndreas Gohr ['blue', 'yellow'] 4071769bc3SAndreas Gohr ]; 4171769bc3SAndreas Gohr 428fed17f3SAndreas Gohr for ($i = 0; $i < 3; $i++) { 438fed17f3SAndreas Gohr // assign a schema 448fed17f3SAndreas Gohr $assignments->assignPageSchema("test$i", 'schema1'); 458fed17f3SAndreas Gohr 468fed17f3SAndreas Gohr // save wiki pages 478fed17f3SAndreas Gohr saveWikiText("test$i", "test$i", "test$i"); 488fed17f3SAndreas Gohr 498fed17f3SAndreas Gohr // save serial data 508fed17f3SAndreas Gohr $data = [ 518fed17f3SAndreas Gohr 'first' => "foo$i", 5271769bc3SAndreas Gohr 'second' => $second[$i], 538fed17f3SAndreas Gohr 'third' => "foobar$i", 548fed17f3SAndreas Gohr 'fourth' => "barfoo$i", 558fed17f3SAndreas Gohr ]; 56*4bffd436SAnna Dabrowska $accessSerial = MockAccessTableAlias::getSerialAccess('schema1', "test$i"); 57*4bffd436SAnna Dabrowska $accessSerial->saveData($data); 58*4bffd436SAnna Dabrowska $accessPage = MockAccessTableAlias::getPageAccess('schema1', "test$i"); 59*4bffd436SAnna Dabrowska $accessPage->saveData($data); 608fed17f3SAndreas Gohr } 618fed17f3SAndreas Gohr } 628fed17f3SAndreas Gohr 638fed17f3SAndreas Gohr /** 648fed17f3SAndreas Gohr * Test whether serial syntax produces a table of serial data limited to current page 658fed17f3SAndreas Gohr */ 668fed17f3SAndreas Gohr public function test_pid() 678fed17f3SAndreas Gohr { 688fed17f3SAndreas Gohr // \syntax_plugin_struct_serial accesses the global $ID 698fed17f3SAndreas Gohr $id = 'test1'; 708fed17f3SAndreas Gohr $schema = 'schema1'; 71*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, $id); 728fed17f3SAndreas Gohr 738fed17f3SAndreas Gohr $this->assertCount(1, $result); 748fed17f3SAndreas Gohr $this->assertEquals('test1', $result[0][0]->getValue()); 758fed17f3SAndreas Gohr // skip %rowid% column and test saved values 768fed17f3SAndreas Gohr $this->assertEquals('foo1', $result[0][2]->getValue()); 77fb2252eaSAndreas Gohr $this->assertEquals(['green', 'blue'], $result[0][3]->getValue()); 788fed17f3SAndreas Gohr $this->assertEquals('foobar1', $result[0][4]->getValue()); 798fed17f3SAndreas Gohr $this->assertEquals('barfoo1', $result[0][5]->getValue()); 808fed17f3SAndreas Gohr } 818fed17f3SAndreas Gohr 828fed17f3SAndreas Gohr /** 838fed17f3SAndreas Gohr * Test simple text filter 848fed17f3SAndreas Gohr */ 858fed17f3SAndreas Gohr public function test_filter_text() 868fed17f3SAndreas Gohr { 878fed17f3SAndreas Gohr $schema = 'schema1'; 88*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, 'test0'); 898fed17f3SAndreas Gohr $this->assertCount(1, $result); 908fed17f3SAndreas Gohr 91*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, 'test0', ['first', '=', 'foo0', 'AND']); 928fed17f3SAndreas Gohr $this->assertCount(1, $result); 938fed17f3SAndreas Gohr 94*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, 'test0', ['first', '!=', 'foo0', 'AND']); 958fed17f3SAndreas Gohr $this->assertCount(0, $result); 968fed17f3SAndreas Gohr } 978fed17f3SAndreas Gohr 9871769bc3SAndreas Gohr /** @noinspection PhpUnreachableStatementInspection */ 9971769bc3SAndreas Gohr public function test_filter_multi() 10071769bc3SAndreas Gohr { 10171769bc3SAndreas Gohr $schema = 'schema1'; 102*4bffd436SAnna Dabrowska $result = $this->fetchAllResults($schema, ''); 103*4bffd436SAnna Dabrowska $this->assertCount(6, $result); 10471769bc3SAndreas Gohr 105*4bffd436SAnna Dabrowska $result = $this->fetchAllResults($schema, '', ['second', '=', 'green', 'AND']); 106*4bffd436SAnna Dabrowska $this->assertCount(4, $result); 10771769bc3SAndreas Gohr 10871769bc3SAndreas Gohr $this->markTestIncomplete('negative filters currently do not work on multi fields. See #512'); 10971769bc3SAndreas Gohr 110*4bffd436SAnna Dabrowska $result = $this->fetchAllResults($schema, '', ['second', '!~', 'green', 'AND']); 111*4bffd436SAnna Dabrowska $this->assertCount(2, $result); 11271769bc3SAndreas Gohr } 11371769bc3SAndreas Gohr 1148fed17f3SAndreas Gohr /** 1158fed17f3SAndreas Gohr * Test filtering on a page field, with 'usetitles' set to true and false 1168fed17f3SAndreas Gohr */ 1178fed17f3SAndreas Gohr public function test_filter_page() 1188fed17f3SAndreas Gohr { 1198fed17f3SAndreas Gohr $this->prepareLookup(); 1208fed17f3SAndreas Gohr $schema = 'pageschema'; 121*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema); 1228fed17f3SAndreas Gohr $this->assertCount(3, $result); 1238fed17f3SAndreas Gohr 1248fed17f3SAndreas Gohr // 'usetitles' = true 125*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, '', ['singletitle', '*~', 'another', 'AND']); 1268fed17f3SAndreas Gohr $this->assertCount(1, $result); 1278fed17f3SAndreas Gohr 1288fed17f3SAndreas Gohr // 'usetitles' = false 129*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, '', ['singlepage', '*~', 'this', 'AND']); 1308fed17f3SAndreas Gohr $this->assertCount(0, $result); 1318fed17f3SAndreas Gohr } 1328fed17f3SAndreas Gohr 1338fed17f3SAndreas Gohr /** 1348fed17f3SAndreas Gohr * Test filtering on a DateTime field 1358fed17f3SAndreas Gohr */ 1368fed17f3SAndreas Gohr public function test_filter_datetime() 1378fed17f3SAndreas Gohr { 1388fed17f3SAndreas Gohr $this->prepareDatetime(); 1398fed17f3SAndreas Gohr $schema = 'datetime'; 140*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema); 1418fed17f3SAndreas Gohr $this->assertCount(3, $result); 1428fed17f3SAndreas Gohr 143*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, '', ['field', '<', '2023-01-02', 'AND']); 1448fed17f3SAndreas Gohr $this->assertCount(1, $result); 1458fed17f3SAndreas Gohr 146*4bffd436SAnna Dabrowska $result = $this->fetchNonPageResults($schema, '', ['field', '<', '2023-01-01 11:00', 'AND']); 1478fed17f3SAndreas Gohr $this->assertCount(0, $result); 1488fed17f3SAndreas Gohr } 1498fed17f3SAndreas Gohr 1508fed17f3SAndreas Gohr /** 1518fed17f3SAndreas Gohr * Test whether aggregation tables respect revoking of schema assignments 1528fed17f3SAndreas Gohr */ 1538fed17f3SAndreas Gohr public function test_assignments() 1548fed17f3SAndreas Gohr { 155*4bffd436SAnna Dabrowska $result = $this->fetchAllResults('schema1'); 156*4bffd436SAnna Dabrowska $this->assertCount(6, $result); 1578fed17f3SAndreas Gohr 1588fed17f3SAndreas Gohr // revoke assignment 1598fed17f3SAndreas Gohr $assignments = mock\Assignments::getInstance(); 1608fed17f3SAndreas Gohr $assignments->deassignPageSchema('test0', 'schema1'); 1618fed17f3SAndreas Gohr 162*4bffd436SAnna Dabrowska $result = $this->fetchAllResults('schema1'); 163*4bffd436SAnna Dabrowska $this->assertCount(5, $result); 1648fed17f3SAndreas Gohr } 1658fed17f3SAndreas Gohr 1668fed17f3SAndreas Gohr 1678fed17f3SAndreas Gohr /** 168*4bffd436SAnna Dabrowska * Initialize a table from syntax and return the result from its internal search. 1698fed17f3SAndreas Gohr * 1708fed17f3SAndreas Gohr * @param string $schema 1718fed17f3SAndreas Gohr * @param string $id 1728fed17f3SAndreas Gohr * @param array $filters 1738fed17f3SAndreas Gohr * @return \dokuwiki\plugin\struct\meta\Value[][] 1748fed17f3SAndreas Gohr */ 175*4bffd436SAnna Dabrowska protected function fetchAllResults($schema, $id = '', $filters = []) 1768fed17f3SAndreas Gohr { 1778fed17f3SAndreas Gohr $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *']; 1788fed17f3SAndreas Gohr $configParser = new ConfigParser($syntaxConfig); 1798fed17f3SAndreas Gohr $config = $configParser->getConfig(); 1808fed17f3SAndreas Gohr 1818fed17f3SAndreas Gohr if ($filters) $config['filter'][] = $filters; 1828fed17f3SAndreas Gohr $search = new MockSearchConfigAlias($config); 1838fed17f3SAndreas Gohr 1848fed17f3SAndreas Gohr $table = new MockAggregationTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search); 1858fed17f3SAndreas Gohr return $table->getResult(); 1868fed17f3SAndreas Gohr } 1878fed17f3SAndreas Gohr 1888fed17f3SAndreas Gohr /** 1898fed17f3SAndreas Gohr * Initialize a lookup table from syntax and return the result from its internal search. 1908fed17f3SAndreas Gohr * 1918fed17f3SAndreas Gohr * @param string $schema 1928fed17f3SAndreas Gohr * @param string $id 1938fed17f3SAndreas Gohr * @param array $filters 1948fed17f3SAndreas Gohr * @return \dokuwiki\plugin\struct\meta\Value[][] 1958fed17f3SAndreas Gohr */ 196*4bffd436SAnna Dabrowska protected function fetchNonPageResults($schema, $id = '', $filters = []) 1978fed17f3SAndreas Gohr { 1988fed17f3SAndreas Gohr $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *']; 1998fed17f3SAndreas Gohr $configParser = new ConfigParser($syntaxConfig); 2008fed17f3SAndreas Gohr $config = $configParser->getConfig(); 2018fed17f3SAndreas Gohr 202*4bffd436SAnna Dabrowska // simulate addYypeFilter() from \syntax_plugin_struct_serial and \syntax_plugin_struct_lookup 2038fed17f3SAndreas Gohr if ($id) { 2048fed17f3SAndreas Gohr $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND']; 2058fed17f3SAndreas Gohr $config['filter'][] = ['%pageid%', '=', $id, 'AND']; 2068fed17f3SAndreas Gohr } else { 2078fed17f3SAndreas Gohr $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND']; 2088fed17f3SAndreas Gohr $config['filter'][] = ['%pageid%', '=*', '^(?![\s\S])', 'AND']; 2098fed17f3SAndreas Gohr } 2108fed17f3SAndreas Gohr 2118fed17f3SAndreas Gohr if ($filters) $config['filter'][] = $filters; 2128fed17f3SAndreas Gohr $search = new MockSearchConfigAlias($config); 2138fed17f3SAndreas Gohr 2148fed17f3SAndreas Gohr $table = new MockAggregationEditorTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search); 2158fed17f3SAndreas Gohr return $table->getResult(); 2168fed17f3SAndreas Gohr } 2178fed17f3SAndreas Gohr 2188fed17f3SAndreas Gohr protected function prepareLookup() 2198fed17f3SAndreas Gohr { 2208fed17f3SAndreas Gohr saveWikiText('title1', 'test', 'test'); 2218fed17f3SAndreas Gohr $pageMeta = new PageMeta('title1'); 2228fed17f3SAndreas Gohr $pageMeta->setTitle('This is a title'); 2238fed17f3SAndreas Gohr 2248fed17f3SAndreas Gohr saveWikiText('title2', 'test', 'test'); 2258fed17f3SAndreas Gohr $pageMeta = new PageMeta('title2'); 2268fed17f3SAndreas Gohr $pageMeta->setTitle('This is a 2nd title'); 2278fed17f3SAndreas Gohr 2288fed17f3SAndreas Gohr saveWikiText('title3', 'test', 'test'); 2298fed17f3SAndreas Gohr $pageMeta = new PageMeta('title3'); 2308fed17f3SAndreas Gohr $pageMeta->setTitle('Another Title'); 2318fed17f3SAndreas Gohr 2328fed17f3SAndreas Gohr $this->loadSchemaJSON('pageschema'); 2338fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2348fed17f3SAndreas Gohr $access->saveData( 2358fed17f3SAndreas Gohr [ 2368fed17f3SAndreas Gohr 'singlepage' => 'title1', 2378fed17f3SAndreas Gohr 'multipage' => ['title1'], 2388fed17f3SAndreas Gohr 'singletitle' => 'title1', 2398fed17f3SAndreas Gohr 'multititle' => ['title1'], 2408fed17f3SAndreas Gohr ] 2418fed17f3SAndreas Gohr ); 2428fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2438fed17f3SAndreas Gohr $access->saveData( 2448fed17f3SAndreas Gohr [ 2458fed17f3SAndreas Gohr 'singlepage' => 'title2', 2468fed17f3SAndreas Gohr 'multipage' => ['title2'], 2478fed17f3SAndreas Gohr 'singletitle' => 'title2', 2488fed17f3SAndreas Gohr 'multititle' => ['title2'], 2498fed17f3SAndreas Gohr ] 2508fed17f3SAndreas Gohr ); 2518fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2528fed17f3SAndreas Gohr $access->saveData( 2538fed17f3SAndreas Gohr [ 2548fed17f3SAndreas Gohr 'singlepage' => 'title3', 2558fed17f3SAndreas Gohr 'multipage' => ['title3'], 2568fed17f3SAndreas Gohr 'singletitle' => 'title3', 2578fed17f3SAndreas Gohr 'multititle' => ['title3'], 2588fed17f3SAndreas Gohr ] 2598fed17f3SAndreas Gohr ); 2608fed17f3SAndreas Gohr } 2618fed17f3SAndreas Gohr 2628fed17f3SAndreas Gohr protected function prepareDatetime() 2638fed17f3SAndreas Gohr { 2648fed17f3SAndreas Gohr $this->loadSchemaJSON('datetime'); 2658fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2668fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-01 12:00']); 2678fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2688fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-02 00:00']); 2698fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2708fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-02 12:00']); 2718fed17f3SAndreas Gohr } 2728fed17f3SAndreas Gohr} 273