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 35*71769bc3SAndreas Gohr // different values for each entry 36*71769bc3SAndreas Gohr $second = [ 37*71769bc3SAndreas Gohr ['green', 'red'], 38*71769bc3SAndreas Gohr ['green', 'blue'], 39*71769bc3SAndreas Gohr ['blue', 'yellow'] 40*71769bc3SAndreas Gohr ]; 41*71769bc3SAndreas 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", 52*71769bc3SAndreas Gohr 'second' => $second[$i], 538fed17f3SAndreas Gohr 'third' => "foobar$i", 548fed17f3SAndreas Gohr 'fourth' => "barfoo$i", 558fed17f3SAndreas Gohr ]; 568fed17f3SAndreas Gohr $access = MockAccessTableAlias::getSerialAccess('schema1', "test$i"); 578fed17f3SAndreas Gohr $access->saveData($data); 588fed17f3SAndreas Gohr } 598fed17f3SAndreas Gohr } 608fed17f3SAndreas Gohr 618fed17f3SAndreas Gohr /** 628fed17f3SAndreas Gohr * Test whether serial syntax produces a table of serial data limited to current page 638fed17f3SAndreas Gohr */ 648fed17f3SAndreas Gohr public function test_pid() 658fed17f3SAndreas Gohr { 668fed17f3SAndreas Gohr // \syntax_plugin_struct_serial accesses the global $ID 678fed17f3SAndreas Gohr $id = 'test1'; 688fed17f3SAndreas Gohr $schema = 'schema1'; 698fed17f3SAndreas Gohr $result = $this->fetchResult($schema, $id); 708fed17f3SAndreas Gohr 718fed17f3SAndreas Gohr $this->assertCount(1, $result); 728fed17f3SAndreas Gohr $this->assertEquals('test1', $result[0][0]->getValue()); 738fed17f3SAndreas Gohr // skip %rowid% column and test saved values 748fed17f3SAndreas Gohr $this->assertEquals('foo1', $result[0][2]->getValue()); 758fed17f3SAndreas Gohr $this->assertEquals(['bar1', 'baz1'], $result[0][3]->getValue()); 768fed17f3SAndreas Gohr $this->assertEquals('foobar1', $result[0][4]->getValue()); 778fed17f3SAndreas Gohr $this->assertEquals('barfoo1', $result[0][5]->getValue()); 788fed17f3SAndreas Gohr } 798fed17f3SAndreas Gohr 808fed17f3SAndreas Gohr /** 818fed17f3SAndreas Gohr * Test simple text filter 828fed17f3SAndreas Gohr */ 838fed17f3SAndreas Gohr public function test_filter_text() 848fed17f3SAndreas Gohr { 858fed17f3SAndreas Gohr $schema = 'schema1'; 868fed17f3SAndreas Gohr $result = $this->fetchResult($schema, 'test0'); 878fed17f3SAndreas Gohr $this->assertCount(1, $result); 888fed17f3SAndreas Gohr 898fed17f3SAndreas Gohr $result = $this->fetchResult($schema, 'test0', ['first', '=', 'foo0', 'AND']); 908fed17f3SAndreas Gohr $this->assertCount(1, $result); 918fed17f3SAndreas Gohr 928fed17f3SAndreas Gohr $result = $this->fetchResult($schema, 'test0', ['first', '!=', 'foo0', 'AND']); 938fed17f3SAndreas Gohr $this->assertCount(0, $result); 948fed17f3SAndreas Gohr } 958fed17f3SAndreas Gohr 96*71769bc3SAndreas Gohr /** @noinspection PhpUnreachableStatementInspection */ 97*71769bc3SAndreas Gohr public function test_filter_multi() 98*71769bc3SAndreas Gohr { 99*71769bc3SAndreas Gohr $schema = 'schema1'; 100*71769bc3SAndreas Gohr $result = $this->fetchPagesResult($schema, ''); 101*71769bc3SAndreas Gohr $this->assertCount(3, $result); 102*71769bc3SAndreas Gohr 103*71769bc3SAndreas Gohr $result = $this->fetchPagesResult($schema, '', ['second', '=', 'green', 'AND']); 104*71769bc3SAndreas Gohr $this->assertCount(2, $result); 105*71769bc3SAndreas Gohr 106*71769bc3SAndreas Gohr $this->markTestIncomplete('negative filters currently do not work on multi fields. See #512'); 107*71769bc3SAndreas Gohr 108*71769bc3SAndreas Gohr $result = $this->fetchPagesResult($schema, '', ['second', '!~', 'green', 'AND']); 109*71769bc3SAndreas Gohr $this->assertCount(1, $result); 110*71769bc3SAndreas Gohr } 111*71769bc3SAndreas Gohr 1128fed17f3SAndreas Gohr /** 1138fed17f3SAndreas Gohr * Test filtering on a page field, with 'usetitles' set to true and false 1148fed17f3SAndreas Gohr */ 1158fed17f3SAndreas Gohr public function test_filter_page() 1168fed17f3SAndreas Gohr { 1178fed17f3SAndreas Gohr $this->prepareLookup(); 1188fed17f3SAndreas Gohr $schema = 'pageschema'; 1198fed17f3SAndreas Gohr $result = $this->fetchResult($schema); 1208fed17f3SAndreas Gohr $this->assertCount(3, $result); 1218fed17f3SAndreas Gohr 1228fed17f3SAndreas Gohr // 'usetitles' = true 1238fed17f3SAndreas Gohr $result = $this->fetchResult($schema, '', ['singletitle', '*~', 'another', 'AND']); 1248fed17f3SAndreas Gohr $this->assertCount(1, $result); 1258fed17f3SAndreas Gohr 1268fed17f3SAndreas Gohr // 'usetitles' = false 1278fed17f3SAndreas Gohr $result = $this->fetchResult($schema, '', ['singlepage', '*~', 'this', 'AND']); 1288fed17f3SAndreas Gohr $this->assertCount(0, $result); 1298fed17f3SAndreas Gohr } 1308fed17f3SAndreas Gohr 1318fed17f3SAndreas Gohr /** 1328fed17f3SAndreas Gohr * Test filtering on a DateTime field 1338fed17f3SAndreas Gohr */ 1348fed17f3SAndreas Gohr public function test_filter_datetime() 1358fed17f3SAndreas Gohr { 1368fed17f3SAndreas Gohr $this->prepareDatetime(); 1378fed17f3SAndreas Gohr $schema = 'datetime'; 1388fed17f3SAndreas Gohr $result = $this->fetchResult($schema); 1398fed17f3SAndreas Gohr $this->assertCount(3, $result); 1408fed17f3SAndreas Gohr 1418fed17f3SAndreas Gohr $result = $this->fetchResult($schema, '', ['field', '<', '2023-01-02', 'AND']); 1428fed17f3SAndreas Gohr $this->assertCount(1, $result); 1438fed17f3SAndreas Gohr 1448fed17f3SAndreas Gohr $result = $this->fetchResult($schema, '', ['field', '<', '2023-01-01 11:00', 'AND']); 1458fed17f3SAndreas Gohr $this->assertCount(0, $result); 1468fed17f3SAndreas Gohr } 1478fed17f3SAndreas Gohr 1488fed17f3SAndreas Gohr /** 1498fed17f3SAndreas Gohr * Test whether aggregation tables respect revoking of schema assignments 1508fed17f3SAndreas Gohr */ 1518fed17f3SAndreas Gohr public function test_assignments() 1528fed17f3SAndreas Gohr { 1538fed17f3SAndreas Gohr $result = $this->fetchPagesResult('schema1'); 1548fed17f3SAndreas Gohr $this->assertCount(3, $result); 1558fed17f3SAndreas Gohr 1568fed17f3SAndreas Gohr // revoke assignment 1578fed17f3SAndreas Gohr $assignments = mock\Assignments::getInstance(); 1588fed17f3SAndreas Gohr $assignments->deassignPageSchema('test0', 'schema1'); 1598fed17f3SAndreas Gohr 1608fed17f3SAndreas Gohr $result = $this->fetchPagesResult('schema1'); 1618fed17f3SAndreas Gohr $this->assertCount(2, $result); 1628fed17f3SAndreas Gohr } 1638fed17f3SAndreas Gohr 1648fed17f3SAndreas Gohr 1658fed17f3SAndreas Gohr /** 1668fed17f3SAndreas Gohr * Initialize a lookup table from syntax and return the result from its internal search. 1678fed17f3SAndreas Gohr * 1688fed17f3SAndreas Gohr * @param string $schema 1698fed17f3SAndreas Gohr * @param string $id 1708fed17f3SAndreas Gohr * @param array $filters 1718fed17f3SAndreas Gohr * @return \dokuwiki\plugin\struct\meta\Value[][] 1728fed17f3SAndreas Gohr */ 1738fed17f3SAndreas Gohr protected function fetchPagesResult($schema, $id = '', $filters = []) 1748fed17f3SAndreas Gohr { 1758fed17f3SAndreas Gohr $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *']; 1768fed17f3SAndreas Gohr $configParser = new ConfigParser($syntaxConfig); 1778fed17f3SAndreas Gohr $config = $configParser->getConfig(); 1788fed17f3SAndreas Gohr 1798fed17f3SAndreas Gohr if ($filters) $config['filter'][] = $filters; 1808fed17f3SAndreas Gohr $search = new MockSearchConfigAlias($config); 1818fed17f3SAndreas Gohr 1828fed17f3SAndreas Gohr $table = new MockAggregationTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search); 1838fed17f3SAndreas Gohr return $table->getResult(); 1848fed17f3SAndreas Gohr } 1858fed17f3SAndreas Gohr 1868fed17f3SAndreas Gohr /** 1878fed17f3SAndreas Gohr * Initialize a lookup table from syntax and return the result from its internal search. 1888fed17f3SAndreas Gohr * 1898fed17f3SAndreas Gohr * @param string $schema 1908fed17f3SAndreas Gohr * @param string $id 1918fed17f3SAndreas Gohr * @param array $filters 1928fed17f3SAndreas Gohr * @return \dokuwiki\plugin\struct\meta\Value[][] 1938fed17f3SAndreas Gohr */ 1948fed17f3SAndreas Gohr protected function fetchResult($schema, $id = '', $filters = []) 1958fed17f3SAndreas Gohr { 1968fed17f3SAndreas Gohr $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *']; 1978fed17f3SAndreas Gohr $configParser = new ConfigParser($syntaxConfig); 1988fed17f3SAndreas Gohr $config = $configParser->getConfig(); 1998fed17f3SAndreas Gohr 2008fed17f3SAndreas Gohr // FIXME simulate addYypeFilter() from \syntax_plugin_struct_serial or \syntax_plugin_struct_lookup 2018fed17f3SAndreas Gohr if ($id) { 2028fed17f3SAndreas Gohr $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND']; 2038fed17f3SAndreas Gohr $config['filter'][] = ['%pageid%', '=', $id, 'AND']; 2048fed17f3SAndreas Gohr } else { 2058fed17f3SAndreas Gohr $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND']; 2068fed17f3SAndreas Gohr $config['filter'][] = ['%pageid%', '=*', '^(?![\s\S])', 'AND']; 2078fed17f3SAndreas Gohr } 2088fed17f3SAndreas Gohr 2098fed17f3SAndreas Gohr if ($filters) $config['filter'][] = $filters; 2108fed17f3SAndreas Gohr $search = new MockSearchConfigAlias($config); 2118fed17f3SAndreas Gohr 2128fed17f3SAndreas Gohr $table = new MockAggregationEditorTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search); 2138fed17f3SAndreas Gohr return $table->getResult(); 2148fed17f3SAndreas Gohr } 2158fed17f3SAndreas Gohr 2168fed17f3SAndreas Gohr protected function prepareLookup() 2178fed17f3SAndreas Gohr { 2188fed17f3SAndreas Gohr saveWikiText('title1', 'test', 'test'); 2198fed17f3SAndreas Gohr $pageMeta = new PageMeta('title1'); 2208fed17f3SAndreas Gohr $pageMeta->setTitle('This is a title'); 2218fed17f3SAndreas Gohr 2228fed17f3SAndreas Gohr saveWikiText('title2', 'test', 'test'); 2238fed17f3SAndreas Gohr $pageMeta = new PageMeta('title2'); 2248fed17f3SAndreas Gohr $pageMeta->setTitle('This is a 2nd title'); 2258fed17f3SAndreas Gohr 2268fed17f3SAndreas Gohr saveWikiText('title3', 'test', 'test'); 2278fed17f3SAndreas Gohr $pageMeta = new PageMeta('title3'); 2288fed17f3SAndreas Gohr $pageMeta->setTitle('Another Title'); 2298fed17f3SAndreas Gohr 2308fed17f3SAndreas Gohr $this->loadSchemaJSON('pageschema'); 2318fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2328fed17f3SAndreas Gohr $access->saveData( 2338fed17f3SAndreas Gohr [ 2348fed17f3SAndreas Gohr 'singlepage' => 'title1', 2358fed17f3SAndreas Gohr 'multipage' => ['title1'], 2368fed17f3SAndreas Gohr 'singletitle' => 'title1', 2378fed17f3SAndreas Gohr 'multititle' => ['title1'], 2388fed17f3SAndreas Gohr ] 2398fed17f3SAndreas Gohr ); 2408fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2418fed17f3SAndreas Gohr $access->saveData( 2428fed17f3SAndreas Gohr [ 2438fed17f3SAndreas Gohr 'singlepage' => 'title2', 2448fed17f3SAndreas Gohr 'multipage' => ['title2'], 2458fed17f3SAndreas Gohr 'singletitle' => 'title2', 2468fed17f3SAndreas Gohr 'multititle' => ['title2'], 2478fed17f3SAndreas Gohr ] 2488fed17f3SAndreas Gohr ); 2498fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('pageschema'); 2508fed17f3SAndreas Gohr $access->saveData( 2518fed17f3SAndreas Gohr [ 2528fed17f3SAndreas Gohr 'singlepage' => 'title3', 2538fed17f3SAndreas Gohr 'multipage' => ['title3'], 2548fed17f3SAndreas Gohr 'singletitle' => 'title3', 2558fed17f3SAndreas Gohr 'multititle' => ['title3'], 2568fed17f3SAndreas Gohr ] 2578fed17f3SAndreas Gohr ); 2588fed17f3SAndreas Gohr } 2598fed17f3SAndreas Gohr 2608fed17f3SAndreas Gohr protected function prepareDatetime() 2618fed17f3SAndreas Gohr { 2628fed17f3SAndreas Gohr $this->loadSchemaJSON('datetime'); 2638fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2648fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-01 12:00']); 2658fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2668fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-02 00:00']); 2678fed17f3SAndreas Gohr $access = MockAccessTableAlias::getGlobalAccess('datetime'); 2688fed17f3SAndreas Gohr $access->saveData(['field' => '2023-01-02 12:00']); 2698fed17f3SAndreas Gohr } 2708fed17f3SAndreas Gohr} 271