xref: /plugin/struct/_test/AggregationResultsTest.php (revision ba7f5789bbbcab95d7a655f6ec50a97b731b40d5)
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\SearchConfig as MockSearchConfigAlias;
108fed17f3SAndreas Gohr
118fed17f3SAndreas Gohr/**
128fed17f3SAndreas Gohr * Testing serial data
138fed17f3SAndreas Gohr *
148fed17f3SAndreas Gohr * @group plugin_struct
158fed17f3SAndreas Gohr * @group plugins
168fed17f3SAndreas Gohr */
178fed17f3SAndreas Gohrclass AggregationResultsTest extends StructTest
188fed17f3SAndreas Gohr{
198fed17f3SAndreas Gohr    protected $sqlite;
208fed17f3SAndreas Gohr
218fed17f3SAndreas Gohr    public function setUp(): void
228fed17f3SAndreas Gohr    {
238fed17f3SAndreas Gohr        parent::setUp();
248fed17f3SAndreas Gohr
258fed17f3SAndreas Gohr        $sqlite = plugin_load('helper', 'struct_db');
268fed17f3SAndreas Gohr        $this->sqlite = $sqlite->getDB();
278fed17f3SAndreas Gohr
288fed17f3SAndreas Gohr        $this->loadSchemaJSON('schema1');
298fed17f3SAndreas Gohr
308fed17f3SAndreas Gohr        $assignments = mock\Assignments::getInstance();
318fed17f3SAndreas Gohr        $assignments->clear(true);
328fed17f3SAndreas Gohr
3371769bc3SAndreas Gohr        // different values for each entry
3471769bc3SAndreas Gohr        $second = [
3571769bc3SAndreas Gohr            ['green', 'red'],
3671769bc3SAndreas Gohr            ['green', 'blue'],
3771769bc3SAndreas Gohr            ['blue', 'yellow']
3871769bc3SAndreas Gohr        ];
3971769bc3SAndreas Gohr
408fed17f3SAndreas Gohr        for ($i = 0; $i < 3; $i++) {
418fed17f3SAndreas Gohr            // assign a schema
428fed17f3SAndreas Gohr            $assignments->assignPageSchema("test$i", 'schema1');
438fed17f3SAndreas Gohr
448fed17f3SAndreas Gohr            // save wiki pages
458fed17f3SAndreas Gohr            saveWikiText("test$i", "test$i", "test$i");
468fed17f3SAndreas Gohr
478fed17f3SAndreas Gohr            // save serial data
488fed17f3SAndreas Gohr            $data = [
498fed17f3SAndreas Gohr                'first' => "foo$i",
5071769bc3SAndreas Gohr                'second' => $second[$i],
518fed17f3SAndreas Gohr                'third' => "foobar$i",
528fed17f3SAndreas Gohr                'fourth' => "barfoo$i",
538fed17f3SAndreas Gohr            ];
544bffd436SAnna Dabrowska            $accessSerial = MockAccessTableAlias::getSerialAccess('schema1', "test$i");
554bffd436SAnna Dabrowska            $accessSerial->saveData($data);
564bffd436SAnna Dabrowska            $accessPage = MockAccessTableAlias::getPageAccess('schema1', "test$i");
574bffd436SAnna Dabrowska            $accessPage->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';
694bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($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());
75fb2252eaSAndreas Gohr        $this->assertEquals(['green', 'blue'], $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';
864bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema, 'test0');
878fed17f3SAndreas Gohr        $this->assertCount(1, $result);
888fed17f3SAndreas Gohr
894bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema, 'test0', ['first', '=', 'foo0', 'AND']);
908fed17f3SAndreas Gohr        $this->assertCount(1, $result);
918fed17f3SAndreas Gohr
924bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema, 'test0', ['first', '!=', 'foo0', 'AND']);
938fed17f3SAndreas Gohr        $this->assertCount(0, $result);
948fed17f3SAndreas Gohr    }
958fed17f3SAndreas Gohr
9671769bc3SAndreas Gohr    /** @noinspection PhpUnreachableStatementInspection */
9771769bc3SAndreas Gohr    public function test_filter_multi()
9871769bc3SAndreas Gohr    {
9971769bc3SAndreas Gohr        $schema = 'schema1';
1004bffd436SAnna Dabrowska        $result = $this->fetchAllResults($schema, '');
1014bffd436SAnna Dabrowska        $this->assertCount(6, $result);
10271769bc3SAndreas Gohr
1034bffd436SAnna Dabrowska        $result = $this->fetchAllResults($schema, '', ['second', '=', 'green', 'AND']);
1044bffd436SAnna Dabrowska        $this->assertCount(4, $result);
10571769bc3SAndreas Gohr
10671769bc3SAndreas Gohr        $this->markTestIncomplete('negative filters currently do not work on multi fields. See #512');
10771769bc3SAndreas Gohr
1084bffd436SAnna Dabrowska        $result = $this->fetchAllResults($schema, '', ['second', '!~', 'green', 'AND']);
1094bffd436SAnna Dabrowska        $this->assertCount(2, $result);
11071769bc3SAndreas Gohr    }
11171769bc3SAndreas 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';
1194bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema);
1208fed17f3SAndreas Gohr        $this->assertCount(3, $result);
1218fed17f3SAndreas Gohr
1228fed17f3SAndreas Gohr        // 'usetitles' = true
1234bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema, '', ['singletitle', '*~', 'another', 'AND']);
1248fed17f3SAndreas Gohr        $this->assertCount(1, $result);
1258fed17f3SAndreas Gohr
1268fed17f3SAndreas Gohr        // 'usetitles' = false
1274bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($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';
1384bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema);
1398fed17f3SAndreas Gohr        $this->assertCount(3, $result);
1408fed17f3SAndreas Gohr
1414bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($schema, '', ['field', '<', '2023-01-02', 'AND']);
1428fed17f3SAndreas Gohr        $this->assertCount(1, $result);
1438fed17f3SAndreas Gohr
1444bffd436SAnna Dabrowska        $result = $this->fetchNonPageResults($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    {
1534bffd436SAnna Dabrowska        $result = $this->fetchAllResults('schema1');
1544bffd436SAnna Dabrowska        $this->assertCount(6, $result);
1558fed17f3SAndreas Gohr
1568fed17f3SAndreas Gohr        // revoke assignment
1578fed17f3SAndreas Gohr        $assignments = mock\Assignments::getInstance();
1588fed17f3SAndreas Gohr        $assignments->deassignPageSchema('test0', 'schema1');
1598fed17f3SAndreas Gohr
1604bffd436SAnna Dabrowska        $result = $this->fetchAllResults('schema1');
1614bffd436SAnna Dabrowska        $this->assertCount(5, $result);
1628fed17f3SAndreas Gohr    }
1638fed17f3SAndreas Gohr
1648fed17f3SAndreas Gohr
1658fed17f3SAndreas Gohr    /**
1664bffd436SAnna Dabrowska     * Initialize a 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     */
1734bffd436SAnna Dabrowska    protected function fetchAllResults($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
182*ba7f5789SAnna Dabrowska        return $search->getRows();
1838fed17f3SAndreas Gohr    }
1848fed17f3SAndreas Gohr
1858fed17f3SAndreas Gohr    /**
1868fed17f3SAndreas Gohr     * Initialize a lookup table from syntax and return the result from its internal search.
1878fed17f3SAndreas Gohr     *
1888fed17f3SAndreas Gohr     * @param string $schema
1898fed17f3SAndreas Gohr     * @param string $id
1908fed17f3SAndreas Gohr     * @param array $filters
1918fed17f3SAndreas Gohr     * @return \dokuwiki\plugin\struct\meta\Value[][]
1928fed17f3SAndreas Gohr     */
1934bffd436SAnna Dabrowska    protected function fetchNonPageResults($schema, $id = '', $filters = [])
1948fed17f3SAndreas Gohr    {
1958fed17f3SAndreas Gohr        $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *'];
1968fed17f3SAndreas Gohr        $configParser = new ConfigParser($syntaxConfig);
1978fed17f3SAndreas Gohr        $config = $configParser->getConfig();
1988fed17f3SAndreas Gohr
1994bffd436SAnna Dabrowska        // simulate addYypeFilter() from \syntax_plugin_struct_serial and \syntax_plugin_struct_lookup
2008fed17f3SAndreas Gohr        if ($id) {
2018fed17f3SAndreas Gohr            $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND'];
2028fed17f3SAndreas Gohr            $config['filter'][] = ['%pageid%', '=', $id, 'AND'];
2038fed17f3SAndreas Gohr        } else {
2048fed17f3SAndreas Gohr            $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND'];
2058fed17f3SAndreas Gohr            $config['filter'][] = ['%pageid%', '=*', '^(?![\s\S])', 'AND'];
2068fed17f3SAndreas Gohr        }
2078fed17f3SAndreas Gohr
2088fed17f3SAndreas Gohr        if ($filters) $config['filter'][] = $filters;
2098fed17f3SAndreas Gohr        $search = new MockSearchConfigAlias($config);
2108fed17f3SAndreas Gohr
211*ba7f5789SAnna Dabrowska        return $search->getRows();
2128fed17f3SAndreas Gohr    }
2138fed17f3SAndreas Gohr
2148fed17f3SAndreas Gohr    protected function prepareLookup()
2158fed17f3SAndreas Gohr    {
2168fed17f3SAndreas Gohr        saveWikiText('title1', 'test', 'test');
2178fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title1');
2188fed17f3SAndreas Gohr        $pageMeta->setTitle('This is a title');
2198fed17f3SAndreas Gohr
2208fed17f3SAndreas Gohr        saveWikiText('title2', 'test', 'test');
2218fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title2');
2228fed17f3SAndreas Gohr        $pageMeta->setTitle('This is a 2nd title');
2238fed17f3SAndreas Gohr
2248fed17f3SAndreas Gohr        saveWikiText('title3', 'test', 'test');
2258fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title3');
2268fed17f3SAndreas Gohr        $pageMeta->setTitle('Another Title');
2278fed17f3SAndreas Gohr
2288fed17f3SAndreas Gohr        $this->loadSchemaJSON('pageschema');
2298fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
2308fed17f3SAndreas Gohr        $access->saveData(
2318fed17f3SAndreas Gohr            [
2328fed17f3SAndreas Gohr                'singlepage' => 'title1',
2338fed17f3SAndreas Gohr                'multipage' => ['title1'],
2348fed17f3SAndreas Gohr                'singletitle' => 'title1',
2358fed17f3SAndreas Gohr                'multititle' => ['title1'],
2368fed17f3SAndreas Gohr            ]
2378fed17f3SAndreas Gohr        );
2388fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
2398fed17f3SAndreas Gohr        $access->saveData(
2408fed17f3SAndreas Gohr            [
2418fed17f3SAndreas Gohr                'singlepage' => 'title2',
2428fed17f3SAndreas Gohr                'multipage' => ['title2'],
2438fed17f3SAndreas Gohr                'singletitle' => 'title2',
2448fed17f3SAndreas Gohr                'multititle' => ['title2'],
2458fed17f3SAndreas Gohr            ]
2468fed17f3SAndreas Gohr        );
2478fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
2488fed17f3SAndreas Gohr        $access->saveData(
2498fed17f3SAndreas Gohr            [
2508fed17f3SAndreas Gohr                'singlepage' => 'title3',
2518fed17f3SAndreas Gohr                'multipage' => ['title3'],
2528fed17f3SAndreas Gohr                'singletitle' => 'title3',
2538fed17f3SAndreas Gohr                'multititle' => ['title3'],
2548fed17f3SAndreas Gohr            ]
2558fed17f3SAndreas Gohr        );
2568fed17f3SAndreas Gohr    }
2578fed17f3SAndreas Gohr
2588fed17f3SAndreas Gohr    protected function prepareDatetime()
2598fed17f3SAndreas Gohr    {
2608fed17f3SAndreas Gohr        $this->loadSchemaJSON('datetime');
2618fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
2628fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-01 12:00']);
2638fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
2648fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-02 00:00']);
2658fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
2668fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-02 12:00']);
2678fed17f3SAndreas Gohr    }
2688fed17f3SAndreas Gohr}
269