xref: /plugin/struct/_test/AccessTableDataReplacementTest.php (revision 4bffd43680da9f5ab6f22a645c1f04bbe99210f8)
18fed17f3SAndreas Gohr<?php
28fed17f3SAndreas Gohr
38fed17f3SAndreas Gohrnamespace dokuwiki\plugin\struct\test;
48fed17f3SAndreas Gohr
58fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta;
68fed17f3SAndreas Gohr
78fed17f3SAndreas Gohr/**
88fed17f3SAndreas Gohr * Tests for the building of SQL-Queries for the struct plugin
98fed17f3SAndreas Gohr *
108fed17f3SAndreas Gohr * @group plugin_struct
118fed17f3SAndreas Gohr * @group plugins
128fed17f3SAndreas Gohr *
138fed17f3SAndreas Gohr */
148fed17f3SAndreas Gohrclass AccessTableDataReplacementTest extends StructTest
158fed17f3SAndreas Gohr{
168fed17f3SAndreas Gohr
178fed17f3SAndreas Gohr    /** @var array alway enable the needed plugins */
188fed17f3SAndreas Gohr    protected $pluginsEnabled = ['struct', 'sqlite'];
198fed17f3SAndreas Gohr
208fed17f3SAndreas Gohr    public function setUp(): void
218fed17f3SAndreas Gohr    {
228fed17f3SAndreas Gohr        parent::setUp();
238fed17f3SAndreas Gohr        $schemafoo = [];
248fed17f3SAndreas Gohr        $schemafoo['new']['new1']['label'] = 'pages';
258fed17f3SAndreas Gohr        $schemafoo['new']['new1']['ismulti'] = 1;
268fed17f3SAndreas Gohr        $schemafoo['new']['new1']['class'] = 'Page';
278fed17f3SAndreas Gohr        $schemafoo['new']['new1']['isenabled'] = '1';
288fed17f3SAndreas Gohr        $schemafoo['new']['new1']['config'] = null;
29438a804cSAnna Dabrowska        $schemafoo['new']['new1']['sort'] = 10;
308fed17f3SAndreas Gohr
318fed17f3SAndreas Gohr        $schemabar['new']['new2']['label'] = 'data';
328fed17f3SAndreas Gohr        $schemabar['new']['new2']['ismulti'] = 0;
338fed17f3SAndreas Gohr        $schemabar['new']['new2']['class'] = 'Text';
348fed17f3SAndreas Gohr        $schemabar['new']['new2']['isenabled'] = '1';
358fed17f3SAndreas Gohr        $schemabar['new']['new2']['config'] = null;
36438a804cSAnna Dabrowska        $schemabar['new']['new2']['sort'] = 20;
378fed17f3SAndreas Gohr
388fed17f3SAndreas Gohr        $builder_foo = new meta\SchemaBuilder('foo', $schemafoo);
398fed17f3SAndreas Gohr        $builder_foo->build();
408fed17f3SAndreas Gohr
418fed17f3SAndreas Gohr        $builder_bar = new meta\SchemaBuilder('bar', $schemabar);
428fed17f3SAndreas Gohr        $builder_bar->build();
438fed17f3SAndreas Gohr
448fed17f3SAndreas Gohr        $as = mock\Assignments::getInstance();
458fed17f3SAndreas Gohr        $as->assignPageSchema('start', 'foo');
468fed17f3SAndreas Gohr        $as->assignPageSchema('no:data', 'foo');
478fed17f3SAndreas Gohr        $as->assignPageSchema('page1', 'bar');
488fed17f3SAndreas Gohr        $as->assignPageSchema('page2', 'bar');
498fed17f3SAndreas Gohr        $as->assignPageSchema('page2', 'bar');
508fed17f3SAndreas Gohr
518fed17f3SAndreas Gohr        // page data is saved with a rev timestamp
528fed17f3SAndreas Gohr        $now = time();
538fed17f3SAndreas Gohr        $this->saveData(
548fed17f3SAndreas Gohr            'start',
558fed17f3SAndreas Gohr            'foo',
568fed17f3SAndreas Gohr            [
578fed17f3SAndreas Gohr                'pages' => ['page1', 'page2']
588fed17f3SAndreas Gohr            ],
598fed17f3SAndreas Gohr            $now
608fed17f3SAndreas Gohr        );
618fed17f3SAndreas Gohr
628fed17f3SAndreas Gohr        $this->saveData(
638fed17f3SAndreas Gohr            'page1',
648fed17f3SAndreas Gohr            'bar',
658fed17f3SAndreas Gohr            [
668fed17f3SAndreas Gohr                'data' => 'data of page1'
678fed17f3SAndreas Gohr            ],
688fed17f3SAndreas Gohr            $now
698fed17f3SAndreas Gohr        );
708fed17f3SAndreas Gohr
718fed17f3SAndreas Gohr        $this->saveData(
728fed17f3SAndreas Gohr            'page2',
738fed17f3SAndreas Gohr            'bar',
748fed17f3SAndreas Gohr            [
758fed17f3SAndreas Gohr                'data' => 'data of page2'
768fed17f3SAndreas Gohr            ],
778fed17f3SAndreas Gohr            $now
788fed17f3SAndreas Gohr        );
798fed17f3SAndreas Gohr    }
808fed17f3SAndreas Gohr
818fed17f3SAndreas Gohr    public function test_simple()
828fed17f3SAndreas Gohr    {
838fed17f3SAndreas Gohr        global $INFO;
848fed17f3SAndreas Gohr        $INFO['id'] = 'start';
858fed17f3SAndreas Gohr        $lines = [
868fed17f3SAndreas Gohr            "schema    : bar",
878fed17f3SAndreas Gohr            "cols      : %pageid%, data",
888fed17f3SAndreas Gohr            "filter    : %pageid% = \$STRUCT.foo.pages$"
898fed17f3SAndreas Gohr        ];
908fed17f3SAndreas Gohr
918fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
928fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
938fed17f3SAndreas Gohr
948fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
958fed17f3SAndreas Gohr        list(, $opts) = $search->getSQL();
968fed17f3SAndreas Gohr        $result = $search->execute();
978fed17f3SAndreas Gohr
988fed17f3SAndreas Gohr        $this->assertEquals(['page1', 'page2'], $opts, '$STRUCT.table.col$ should not require table to be selected');
998fed17f3SAndreas Gohr        $this->assertEquals('data of page1', $result[0][1]->getValue());
1008fed17f3SAndreas Gohr        $this->assertEquals('data of page2', $result[1][1]->getValue());
1018fed17f3SAndreas Gohr    }
1028fed17f3SAndreas Gohr
1038fed17f3SAndreas Gohr    public function test_emptyfield()
1048fed17f3SAndreas Gohr    {
1058fed17f3SAndreas Gohr        global $ID;
1068fed17f3SAndreas Gohr        $ID = 'no:data';
1078fed17f3SAndreas Gohr        $lines = [
1088fed17f3SAndreas Gohr            "schema    : bar",
1098fed17f3SAndreas Gohr            "cols      : %pageid%, data",
1108fed17f3SAndreas Gohr            "filter    : %pageid% = \$STRUCT.foo.pages$"
1118fed17f3SAndreas Gohr        ];
1128fed17f3SAndreas Gohr
1138fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
1148fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
1158fed17f3SAndreas Gohr
1168fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
1178fed17f3SAndreas Gohr        $result = $search->execute();
1188fed17f3SAndreas Gohr
1198fed17f3SAndreas Gohr        $this->assertEquals(0, count($result), 'if no pages a given, then none should be shown');
1208fed17f3SAndreas Gohr    }
1218fed17f3SAndreas Gohr
1228fed17f3SAndreas Gohr    public function dataProvider_DataFiltersAsSubQuery()
1238fed17f3SAndreas Gohr    {
1248fed17f3SAndreas Gohr        return [
1258fed17f3SAndreas Gohr            [
1268fed17f3SAndreas Gohr                [
1278fed17f3SAndreas Gohr                    "filter    : data = foo"
1288fed17f3SAndreas Gohr                ],
1298fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))",
1308fed17f3SAndreas Gohr                "The WHERE-clauses from page-syntax should be wrapped in parentheses"
1318fed17f3SAndreas Gohr            ],
1328fed17f3SAndreas Gohr            [
1338fed17f3SAndreas Gohr                [
1348fed17f3SAndreas Gohr                    "OR    : data = foo"
1358fed17f3SAndreas Gohr                ],
1368fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))",
1378fed17f3SAndreas Gohr                "A single OR clause should be treated as AND clauses"
1388fed17f3SAndreas Gohr            ],
1398fed17f3SAndreas Gohr            [
1408fed17f3SAndreas Gohr                [
1418fed17f3SAndreas Gohr                    "filter    : data = foo",
1428fed17f3SAndreas Gohr                    "OR        : data = bar"
1438fed17f3SAndreas Gohr                ],
1448fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) OR (data_bar.col1 != '' AND data_bar.col1 = ?))",
1458fed17f3SAndreas Gohr                "The WHERE-clauses from page-syntax should be wrapped in parentheses"
1468fed17f3SAndreas Gohr            ],
1478fed17f3SAndreas Gohr            [
1488fed17f3SAndreas Gohr                [
1498fed17f3SAndreas Gohr                    "OR        : data = bar",
1508fed17f3SAndreas Gohr                    "filter    : data = foo"
1518fed17f3SAndreas Gohr                ],
1528fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) AND (data_bar.col1 != '' AND data_bar.col1 = ?))",
1538fed17f3SAndreas Gohr                "A single OR clause should be treated as AND clauses"
1548fed17f3SAndreas Gohr            ]
1558fed17f3SAndreas Gohr        ];
1568fed17f3SAndreas Gohr    }
1578fed17f3SAndreas Gohr
1588fed17f3SAndreas Gohr    /**
1598fed17f3SAndreas Gohr     * @dataProvider dataProvider_DataFiltersAsSubQuery
1608fed17f3SAndreas Gohr     */
1618fed17f3SAndreas Gohr    public function test_DataFiltersAsSubQuery($inputFilterLines, $expectedFilterWhere, $msg)
1628fed17f3SAndreas Gohr    {
1638fed17f3SAndreas Gohr        $lines = [
1648fed17f3SAndreas Gohr            "schema    : bar",
1658fed17f3SAndreas Gohr            "cols      : %pageid%, data",
1668fed17f3SAndreas Gohr        ];
1678fed17f3SAndreas Gohr
1688fed17f3SAndreas Gohr        $lines = array_merge($lines, $inputFilterLines);
1698fed17f3SAndreas Gohr
1708fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
1718fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
1728fed17f3SAndreas Gohr
1738fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
1748fed17f3SAndreas Gohr        list($sql,) = $search->getSQL();
1758fed17f3SAndreas Gohr        $where = array_filter(explode("\n", $sql), function ($elem) {
1768fed17f3SAndreas Gohr            return strpos($elem, 'WHERE') !== false;
1778fed17f3SAndreas Gohr        });
1788fed17f3SAndreas Gohr        $where = trim(reset($where));
1798fed17f3SAndreas Gohr
1808fed17f3SAndreas Gohr        $baseWhere = "WHERE  (
1818fed17f3SAndreas Gohr                (
1828fed17f3SAndreas Gohr                    data_bar.pid = '' OR (
1838fed17f3SAndreas Gohr                        GETACCESSLEVEL(data_bar.pid) > 0
1848fed17f3SAndreas Gohr                        AND PAGEEXISTS(data_bar.pid) = 1
185*4bffd436SAnna Dabrowska                        AND (
186*4bffd436SAnna Dabrowska                            data_bar.rid != 0
187*4bffd436SAnna Dabrowska                            OR (ASSIGNED = 1 OR ASSIGNED IS NULL)
188*4bffd436SAnna Dabrowska                        )
1898fed17f3SAndreas Gohr                    )
1908fed17f3SAndreas Gohr                )
1918fed17f3SAndreas Gohr            AND (
1928fed17f3SAndreas Gohr                (IS_PUBLISHER(data_bar.pid) AND data_bar.latest = 1)
1938fed17f3SAndreas Gohr                OR (IS_PUBLISHER(data_bar.pid) !=1 AND data_bar.published = 1)
1948fed17f3SAndreas Gohr            )";
1958fed17f3SAndreas Gohr
1968fed17f3SAndreas Gohr        $expected_where = $baseWhere . $expectedFilterWhere . " )";
1978fed17f3SAndreas Gohr        $this->assertEquals($this->cleanWS($expected_where), $this->cleanWS($where), $msg);
1988fed17f3SAndreas Gohr    }
1998fed17f3SAndreas Gohr
2008fed17f3SAndreas Gohr}
201