xref: /plugin/struct/_test/AggregationResultsTest.php (revision 71769bc3a6f39de8fbcaf00b4c3e6aeee4c74d99)
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