xref: /plugin/struct/_test/AccessTableDataReplacementTest.php (revision 8fed17f342cc190557a6ce94d1787f9e2f63cb6c)
1*8fed17f3SAndreas Gohr<?php
2*8fed17f3SAndreas Gohr
3*8fed17f3SAndreas Gohrnamespace dokuwiki\plugin\struct\test;
4*8fed17f3SAndreas Gohr
5*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta;
6*8fed17f3SAndreas Gohr
7*8fed17f3SAndreas Gohr/**
8*8fed17f3SAndreas Gohr * Tests for the building of SQL-Queries for the struct plugin
9*8fed17f3SAndreas Gohr *
10*8fed17f3SAndreas Gohr * @group plugin_struct
11*8fed17f3SAndreas Gohr * @group plugins
12*8fed17f3SAndreas Gohr *
13*8fed17f3SAndreas Gohr */
14*8fed17f3SAndreas Gohrclass AccessTableDataReplacementTest extends StructTest
15*8fed17f3SAndreas Gohr{
16*8fed17f3SAndreas Gohr
17*8fed17f3SAndreas Gohr    /** @var array alway enable the needed plugins */
18*8fed17f3SAndreas Gohr    protected $pluginsEnabled = ['struct', 'sqlite'];
19*8fed17f3SAndreas Gohr
20*8fed17f3SAndreas Gohr    public function setUp(): void
21*8fed17f3SAndreas Gohr    {
22*8fed17f3SAndreas Gohr        parent::setUp();
23*8fed17f3SAndreas Gohr        $schemafoo = [];
24*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['label'] = 'pages';
25*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['ismulti'] = 1;
26*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['class'] = 'Page';
27*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['isenabled'] = '1';
28*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['config'] = null;
29*8fed17f3SAndreas Gohr        $schemafoo['new']['new1']['sort'] = null;
30*8fed17f3SAndreas Gohr
31*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['label'] = 'data';
32*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['ismulti'] = 0;
33*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['class'] = 'Text';
34*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['isenabled'] = '1';
35*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['config'] = null;
36*8fed17f3SAndreas Gohr        $schemabar['new']['new2']['sort'] = null;
37*8fed17f3SAndreas Gohr
38*8fed17f3SAndreas Gohr        $builder_foo = new meta\SchemaBuilder('foo', $schemafoo);
39*8fed17f3SAndreas Gohr        $builder_foo->build();
40*8fed17f3SAndreas Gohr
41*8fed17f3SAndreas Gohr        $builder_bar = new meta\SchemaBuilder('bar', $schemabar);
42*8fed17f3SAndreas Gohr        $builder_bar->build();
43*8fed17f3SAndreas Gohr
44*8fed17f3SAndreas Gohr        $as = mock\Assignments::getInstance();
45*8fed17f3SAndreas Gohr        $as->assignPageSchema('start', 'foo');
46*8fed17f3SAndreas Gohr        $as->assignPageSchema('no:data', 'foo');
47*8fed17f3SAndreas Gohr        $as->assignPageSchema('page1', 'bar');
48*8fed17f3SAndreas Gohr        $as->assignPageSchema('page2', 'bar');
49*8fed17f3SAndreas Gohr        $as->assignPageSchema('page2', 'bar');
50*8fed17f3SAndreas Gohr
51*8fed17f3SAndreas Gohr        // page data is saved with a rev timestamp
52*8fed17f3SAndreas Gohr        $now = time();
53*8fed17f3SAndreas Gohr        $this->saveData(
54*8fed17f3SAndreas Gohr            'start',
55*8fed17f3SAndreas Gohr            'foo',
56*8fed17f3SAndreas Gohr            [
57*8fed17f3SAndreas Gohr                'pages' => ['page1', 'page2']
58*8fed17f3SAndreas Gohr            ],
59*8fed17f3SAndreas Gohr            $now
60*8fed17f3SAndreas Gohr        );
61*8fed17f3SAndreas Gohr
62*8fed17f3SAndreas Gohr        $this->saveData(
63*8fed17f3SAndreas Gohr            'page1',
64*8fed17f3SAndreas Gohr            'bar',
65*8fed17f3SAndreas Gohr            [
66*8fed17f3SAndreas Gohr                'data' => 'data of page1'
67*8fed17f3SAndreas Gohr            ],
68*8fed17f3SAndreas Gohr            $now
69*8fed17f3SAndreas Gohr        );
70*8fed17f3SAndreas Gohr
71*8fed17f3SAndreas Gohr        $this->saveData(
72*8fed17f3SAndreas Gohr            'page2',
73*8fed17f3SAndreas Gohr            'bar',
74*8fed17f3SAndreas Gohr            [
75*8fed17f3SAndreas Gohr                'data' => 'data of page2'
76*8fed17f3SAndreas Gohr            ],
77*8fed17f3SAndreas Gohr            $now
78*8fed17f3SAndreas Gohr        );
79*8fed17f3SAndreas Gohr    }
80*8fed17f3SAndreas Gohr
81*8fed17f3SAndreas Gohr    public function test_simple()
82*8fed17f3SAndreas Gohr    {
83*8fed17f3SAndreas Gohr        global $INFO;
84*8fed17f3SAndreas Gohr        $INFO['id'] = 'start';
85*8fed17f3SAndreas Gohr        $lines = [
86*8fed17f3SAndreas Gohr            "schema    : bar",
87*8fed17f3SAndreas Gohr            "cols      : %pageid%, data",
88*8fed17f3SAndreas Gohr            "filter    : %pageid% = \$STRUCT.foo.pages$"
89*8fed17f3SAndreas Gohr        ];
90*8fed17f3SAndreas Gohr
91*8fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
92*8fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
93*8fed17f3SAndreas Gohr
94*8fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
95*8fed17f3SAndreas Gohr        list(, $opts) = $search->getSQL();
96*8fed17f3SAndreas Gohr        $result = $search->execute();
97*8fed17f3SAndreas Gohr
98*8fed17f3SAndreas Gohr        $this->assertEquals(['page1', 'page2'], $opts, '$STRUCT.table.col$ should not require table to be selected');
99*8fed17f3SAndreas Gohr        $this->assertEquals('data of page1', $result[0][1]->getValue());
100*8fed17f3SAndreas Gohr        $this->assertEquals('data of page2', $result[1][1]->getValue());
101*8fed17f3SAndreas Gohr    }
102*8fed17f3SAndreas Gohr
103*8fed17f3SAndreas Gohr    public function test_emptyfield()
104*8fed17f3SAndreas Gohr    {
105*8fed17f3SAndreas Gohr        global $ID;
106*8fed17f3SAndreas Gohr        $ID = 'no:data';
107*8fed17f3SAndreas Gohr        $lines = [
108*8fed17f3SAndreas Gohr            "schema    : bar",
109*8fed17f3SAndreas Gohr            "cols      : %pageid%, data",
110*8fed17f3SAndreas Gohr            "filter    : %pageid% = \$STRUCT.foo.pages$"
111*8fed17f3SAndreas Gohr        ];
112*8fed17f3SAndreas Gohr
113*8fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
114*8fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
115*8fed17f3SAndreas Gohr
116*8fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
117*8fed17f3SAndreas Gohr        $result = $search->execute();
118*8fed17f3SAndreas Gohr
119*8fed17f3SAndreas Gohr        $this->assertEquals(0, count($result), 'if no pages a given, then none should be shown');
120*8fed17f3SAndreas Gohr    }
121*8fed17f3SAndreas Gohr
122*8fed17f3SAndreas Gohr    public function dataProvider_DataFiltersAsSubQuery()
123*8fed17f3SAndreas Gohr    {
124*8fed17f3SAndreas Gohr        return [
125*8fed17f3SAndreas Gohr            [
126*8fed17f3SAndreas Gohr                [
127*8fed17f3SAndreas Gohr                    "filter    : data = foo"
128*8fed17f3SAndreas Gohr                ],
129*8fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))",
130*8fed17f3SAndreas Gohr                "The WHERE-clauses from page-syntax should be wrapped in parentheses"
131*8fed17f3SAndreas Gohr            ],
132*8fed17f3SAndreas Gohr            [
133*8fed17f3SAndreas Gohr                [
134*8fed17f3SAndreas Gohr                    "OR    : data = foo"
135*8fed17f3SAndreas Gohr                ],
136*8fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?))",
137*8fed17f3SAndreas Gohr                "A single OR clause should be treated as AND clauses"
138*8fed17f3SAndreas Gohr            ],
139*8fed17f3SAndreas Gohr            [
140*8fed17f3SAndreas Gohr                [
141*8fed17f3SAndreas Gohr                    "filter    : data = foo",
142*8fed17f3SAndreas Gohr                    "OR        : data = bar"
143*8fed17f3SAndreas Gohr                ],
144*8fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) OR (data_bar.col1 != '' AND data_bar.col1 = ?))",
145*8fed17f3SAndreas Gohr                "The WHERE-clauses from page-syntax should be wrapped in parentheses"
146*8fed17f3SAndreas Gohr            ],
147*8fed17f3SAndreas Gohr            [
148*8fed17f3SAndreas Gohr                [
149*8fed17f3SAndreas Gohr                    "OR        : data = bar",
150*8fed17f3SAndreas Gohr                    "filter    : data = foo"
151*8fed17f3SAndreas Gohr                ],
152*8fed17f3SAndreas Gohr                "AND ((data_bar.col1 != '' AND data_bar.col1 = ?) AND (data_bar.col1 != '' AND data_bar.col1 = ?))",
153*8fed17f3SAndreas Gohr                "A single OR clause should be treated as AND clauses"
154*8fed17f3SAndreas Gohr            ]
155*8fed17f3SAndreas Gohr        ];
156*8fed17f3SAndreas Gohr    }
157*8fed17f3SAndreas Gohr
158*8fed17f3SAndreas Gohr    /**
159*8fed17f3SAndreas Gohr     * @dataProvider dataProvider_DataFiltersAsSubQuery
160*8fed17f3SAndreas Gohr     */
161*8fed17f3SAndreas Gohr    public function test_DataFiltersAsSubQuery($inputFilterLines, $expectedFilterWhere, $msg)
162*8fed17f3SAndreas Gohr    {
163*8fed17f3SAndreas Gohr        $lines = [
164*8fed17f3SAndreas Gohr            "schema    : bar",
165*8fed17f3SAndreas Gohr            "cols      : %pageid%, data",
166*8fed17f3SAndreas Gohr        ];
167*8fed17f3SAndreas Gohr
168*8fed17f3SAndreas Gohr        $lines = array_merge($lines, $inputFilterLines);
169*8fed17f3SAndreas Gohr
170*8fed17f3SAndreas Gohr        $configParser = new meta\ConfigParser($lines);
171*8fed17f3SAndreas Gohr        $actual_config = $configParser->getConfig();
172*8fed17f3SAndreas Gohr
173*8fed17f3SAndreas Gohr        $search = new meta\SearchConfig($actual_config);
174*8fed17f3SAndreas Gohr        list($sql,) = $search->getSQL();
175*8fed17f3SAndreas Gohr        $where = array_filter(explode("\n", $sql), function ($elem) {
176*8fed17f3SAndreas Gohr            return strpos($elem, 'WHERE') !== false;
177*8fed17f3SAndreas Gohr        });
178*8fed17f3SAndreas Gohr        $where = trim(reset($where));
179*8fed17f3SAndreas Gohr
180*8fed17f3SAndreas Gohr        $baseWhere = "WHERE  (
181*8fed17f3SAndreas Gohr                (
182*8fed17f3SAndreas Gohr                    data_bar.pid = '' OR (
183*8fed17f3SAndreas Gohr                        GETACCESSLEVEL(data_bar.pid) > 0
184*8fed17f3SAndreas Gohr                        AND PAGEEXISTS(data_bar.pid) = 1
185*8fed17f3SAndreas Gohr                        AND (ASSIGNED = 1 OR ASSIGNED IS NULL)
186*8fed17f3SAndreas Gohr                    )
187*8fed17f3SAndreas Gohr                )
188*8fed17f3SAndreas Gohr            AND (
189*8fed17f3SAndreas Gohr                (IS_PUBLISHER(data_bar.pid) AND data_bar.latest = 1)
190*8fed17f3SAndreas Gohr                OR (IS_PUBLISHER(data_bar.pid) !=1 AND data_bar.published = 1)
191*8fed17f3SAndreas Gohr            )";
192*8fed17f3SAndreas Gohr
193*8fed17f3SAndreas Gohr        $expected_where = $baseWhere . $expectedFilterWhere . " )";
194*8fed17f3SAndreas Gohr        $this->assertEquals($this->cleanWS($expected_where), $this->cleanWS($where), $msg);
195*8fed17f3SAndreas Gohr    }
196*8fed17f3SAndreas Gohr
197*8fed17f3SAndreas Gohr}
198