xref: /plugin/struct/_test/AggregationResultsTest.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\AccessTablePage;
6*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta\ConfigParser;
7*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\meta\PageMeta;
8*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AccessTable as MockAccessTableAlias;
9*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AggregationEditorTable as MockAggregationEditorTableAlias;
10*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\AggregationTable as MockAggregationTableAlias;
11*8fed17f3SAndreas Gohruse dokuwiki\plugin\struct\test\mock\SearchConfig as MockSearchConfigAlias;
12*8fed17f3SAndreas Gohr
13*8fed17f3SAndreas Gohr/**
14*8fed17f3SAndreas Gohr * Testing serial data
15*8fed17f3SAndreas Gohr *
16*8fed17f3SAndreas Gohr * @group plugin_struct
17*8fed17f3SAndreas Gohr * @group plugins
18*8fed17f3SAndreas Gohr */
19*8fed17f3SAndreas Gohrclass AggregationResultsTest extends StructTest
20*8fed17f3SAndreas Gohr{
21*8fed17f3SAndreas Gohr    protected $sqlite;
22*8fed17f3SAndreas Gohr
23*8fed17f3SAndreas Gohr    public function setUp(): void
24*8fed17f3SAndreas Gohr    {
25*8fed17f3SAndreas Gohr        parent::setUp();
26*8fed17f3SAndreas Gohr
27*8fed17f3SAndreas Gohr        $sqlite = plugin_load('helper', 'struct_db');
28*8fed17f3SAndreas Gohr        $this->sqlite = $sqlite->getDB();
29*8fed17f3SAndreas Gohr
30*8fed17f3SAndreas Gohr        $this->loadSchemaJSON('schema1');
31*8fed17f3SAndreas Gohr
32*8fed17f3SAndreas Gohr        $assignments = mock\Assignments::getInstance();
33*8fed17f3SAndreas Gohr        $assignments->clear(true);
34*8fed17f3SAndreas Gohr
35*8fed17f3SAndreas Gohr        for ($i = 0; $i < 3; $i++) {
36*8fed17f3SAndreas Gohr            // assign a schema
37*8fed17f3SAndreas Gohr            $assignments->assignPageSchema("test$i", 'schema1');
38*8fed17f3SAndreas Gohr
39*8fed17f3SAndreas Gohr            // save wiki pages
40*8fed17f3SAndreas Gohr            saveWikiText("test$i", "test$i", "test$i");
41*8fed17f3SAndreas Gohr
42*8fed17f3SAndreas Gohr            // save serial data
43*8fed17f3SAndreas Gohr            $data = [
44*8fed17f3SAndreas Gohr                'first' => "foo$i",
45*8fed17f3SAndreas Gohr                'second' => ["bar$i", "baz$i"],
46*8fed17f3SAndreas Gohr                'third' => "foobar$i",
47*8fed17f3SAndreas Gohr                'fourth' => "barfoo$i",
48*8fed17f3SAndreas Gohr            ];
49*8fed17f3SAndreas Gohr            $access = MockAccessTableAlias::getSerialAccess('schema1', "test$i");
50*8fed17f3SAndreas Gohr            $access->saveData($data);
51*8fed17f3SAndreas Gohr        }
52*8fed17f3SAndreas Gohr    }
53*8fed17f3SAndreas Gohr
54*8fed17f3SAndreas Gohr    /**
55*8fed17f3SAndreas Gohr     * Test whether serial syntax produces a table of serial data limited to current page
56*8fed17f3SAndreas Gohr     */
57*8fed17f3SAndreas Gohr    public function test_pid()
58*8fed17f3SAndreas Gohr    {
59*8fed17f3SAndreas Gohr        // \syntax_plugin_struct_serial accesses the global $ID
60*8fed17f3SAndreas Gohr        $id = 'test1';
61*8fed17f3SAndreas Gohr        $schema = 'schema1';
62*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, $id);
63*8fed17f3SAndreas Gohr
64*8fed17f3SAndreas Gohr        $this->assertCount(1, $result);
65*8fed17f3SAndreas Gohr        $this->assertEquals('test1', $result[0][0]->getValue());
66*8fed17f3SAndreas Gohr        // skip %rowid% column and test saved values
67*8fed17f3SAndreas Gohr        $this->assertEquals('foo1', $result[0][2]->getValue());
68*8fed17f3SAndreas Gohr        $this->assertEquals(['bar1', 'baz1'], $result[0][3]->getValue());
69*8fed17f3SAndreas Gohr        $this->assertEquals('foobar1', $result[0][4]->getValue());
70*8fed17f3SAndreas Gohr        $this->assertEquals('barfoo1', $result[0][5]->getValue());
71*8fed17f3SAndreas Gohr    }
72*8fed17f3SAndreas Gohr
73*8fed17f3SAndreas Gohr    /**
74*8fed17f3SAndreas Gohr     * Test simple text filter
75*8fed17f3SAndreas Gohr     */
76*8fed17f3SAndreas Gohr    public function test_filter_text()
77*8fed17f3SAndreas Gohr    {
78*8fed17f3SAndreas Gohr        $schema = 'schema1';
79*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, 'test0');
80*8fed17f3SAndreas Gohr        $this->assertCount(1, $result);
81*8fed17f3SAndreas Gohr
82*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, 'test0', ['first', '=', 'foo0', 'AND']);
83*8fed17f3SAndreas Gohr        $this->assertCount(1, $result);
84*8fed17f3SAndreas Gohr
85*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, 'test0', ['first', '!=', 'foo0', 'AND']);
86*8fed17f3SAndreas Gohr        $this->assertCount(0, $result);
87*8fed17f3SAndreas Gohr    }
88*8fed17f3SAndreas Gohr
89*8fed17f3SAndreas Gohr    /**
90*8fed17f3SAndreas Gohr     * Test filtering on a page field, with 'usetitles' set to true and false
91*8fed17f3SAndreas Gohr     */
92*8fed17f3SAndreas Gohr    public function test_filter_page()
93*8fed17f3SAndreas Gohr    {
94*8fed17f3SAndreas Gohr        $this->prepareLookup();
95*8fed17f3SAndreas Gohr        $schema = 'pageschema';
96*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema);
97*8fed17f3SAndreas Gohr        $this->assertCount(3, $result);
98*8fed17f3SAndreas Gohr
99*8fed17f3SAndreas Gohr        // 'usetitles' = true
100*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, '', ['singletitle', '*~', 'another', 'AND']);
101*8fed17f3SAndreas Gohr        $this->assertCount(1, $result);
102*8fed17f3SAndreas Gohr
103*8fed17f3SAndreas Gohr        // 'usetitles' = false
104*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, '', ['singlepage', '*~', 'this', 'AND']);
105*8fed17f3SAndreas Gohr        $this->assertCount(0, $result);
106*8fed17f3SAndreas Gohr    }
107*8fed17f3SAndreas Gohr
108*8fed17f3SAndreas Gohr    /**
109*8fed17f3SAndreas Gohr     * Test filtering on a DateTime field
110*8fed17f3SAndreas Gohr     */
111*8fed17f3SAndreas Gohr    public function test_filter_datetime()
112*8fed17f3SAndreas Gohr    {
113*8fed17f3SAndreas Gohr        $this->prepareDatetime();
114*8fed17f3SAndreas Gohr        $schema = 'datetime';
115*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema);
116*8fed17f3SAndreas Gohr        $this->assertCount(3, $result);
117*8fed17f3SAndreas Gohr
118*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, '', ['field', '<', '2023-01-02', 'AND']);
119*8fed17f3SAndreas Gohr        $this->assertCount(1, $result);
120*8fed17f3SAndreas Gohr
121*8fed17f3SAndreas Gohr        $result = $this->fetchResult($schema, '', ['field', '<', '2023-01-01 11:00', 'AND']);
122*8fed17f3SAndreas Gohr        $this->assertCount(0, $result);
123*8fed17f3SAndreas Gohr    }
124*8fed17f3SAndreas Gohr
125*8fed17f3SAndreas Gohr    /**
126*8fed17f3SAndreas Gohr     * Test whether aggregation tables respect revoking of schema assignments
127*8fed17f3SAndreas Gohr     */
128*8fed17f3SAndreas Gohr    public function test_assignments()
129*8fed17f3SAndreas Gohr    {
130*8fed17f3SAndreas Gohr        $result = $this->fetchPagesResult('schema1');
131*8fed17f3SAndreas Gohr        $this->assertCount(3, $result);
132*8fed17f3SAndreas Gohr
133*8fed17f3SAndreas Gohr        // revoke assignment
134*8fed17f3SAndreas Gohr        $assignments = mock\Assignments::getInstance();
135*8fed17f3SAndreas Gohr        $assignments->deassignPageSchema('test0', 'schema1');
136*8fed17f3SAndreas Gohr
137*8fed17f3SAndreas Gohr        $result = $this->fetchPagesResult('schema1');
138*8fed17f3SAndreas Gohr        $this->assertCount(2, $result);
139*8fed17f3SAndreas Gohr    }
140*8fed17f3SAndreas Gohr
141*8fed17f3SAndreas Gohr
142*8fed17f3SAndreas Gohr    /**
143*8fed17f3SAndreas Gohr     * Initialize a lookup table from syntax and return the result from its internal search.
144*8fed17f3SAndreas Gohr     *
145*8fed17f3SAndreas Gohr     * @param string $schema
146*8fed17f3SAndreas Gohr     * @param string $id
147*8fed17f3SAndreas Gohr     * @param array $filters
148*8fed17f3SAndreas Gohr     * @return \dokuwiki\plugin\struct\meta\Value[][]
149*8fed17f3SAndreas Gohr     */
150*8fed17f3SAndreas Gohr    protected function fetchPagesResult($schema, $id = '', $filters = [])
151*8fed17f3SAndreas Gohr    {
152*8fed17f3SAndreas Gohr        $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *'];
153*8fed17f3SAndreas Gohr        $configParser = new ConfigParser($syntaxConfig);
154*8fed17f3SAndreas Gohr        $config = $configParser->getConfig();
155*8fed17f3SAndreas Gohr
156*8fed17f3SAndreas Gohr        if ($filters) $config['filter'][] = $filters;
157*8fed17f3SAndreas Gohr        $search = new MockSearchConfigAlias($config);
158*8fed17f3SAndreas Gohr
159*8fed17f3SAndreas Gohr        $table = new MockAggregationTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search);
160*8fed17f3SAndreas Gohr        return $table->getResult();
161*8fed17f3SAndreas Gohr    }
162*8fed17f3SAndreas Gohr
163*8fed17f3SAndreas Gohr    /**
164*8fed17f3SAndreas Gohr     * Initialize a lookup table from syntax and return the result from its internal search.
165*8fed17f3SAndreas Gohr     *
166*8fed17f3SAndreas Gohr     * @param string $schema
167*8fed17f3SAndreas Gohr     * @param string $id
168*8fed17f3SAndreas Gohr     * @param array $filters
169*8fed17f3SAndreas Gohr     * @return \dokuwiki\plugin\struct\meta\Value[][]
170*8fed17f3SAndreas Gohr     */
171*8fed17f3SAndreas Gohr    protected function fetchResult($schema, $id = '', $filters = [])
172*8fed17f3SAndreas Gohr    {
173*8fed17f3SAndreas Gohr        $syntaxConfig = ['schema: ' . $schema, 'cols: %pageid%, %rowid%, *'];
174*8fed17f3SAndreas Gohr        $configParser = new ConfigParser($syntaxConfig);
175*8fed17f3SAndreas Gohr        $config = $configParser->getConfig();
176*8fed17f3SAndreas Gohr
177*8fed17f3SAndreas Gohr        // FIXME simulate addYypeFilter() from \syntax_plugin_struct_serial or \syntax_plugin_struct_lookup
178*8fed17f3SAndreas Gohr        if ($id) {
179*8fed17f3SAndreas Gohr            $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND'];
180*8fed17f3SAndreas Gohr            $config['filter'][] = ['%pageid%', '=', $id, 'AND'];
181*8fed17f3SAndreas Gohr        } else {
182*8fed17f3SAndreas Gohr            $config['filter'][] = ['%rowid%', '!=', (string)AccessTablePage::DEFAULT_PAGE_RID, 'AND'];
183*8fed17f3SAndreas Gohr            $config['filter'][] = ['%pageid%', '=*', '^(?![\s\S])', 'AND'];
184*8fed17f3SAndreas Gohr        }
185*8fed17f3SAndreas Gohr
186*8fed17f3SAndreas Gohr        if ($filters) $config['filter'][] = $filters;
187*8fed17f3SAndreas Gohr        $search = new MockSearchConfigAlias($config);
188*8fed17f3SAndreas Gohr
189*8fed17f3SAndreas Gohr        $table = new MockAggregationEditorTableAlias($id, 'xhtml', new \Doku_Renderer_xhtml(), $search);
190*8fed17f3SAndreas Gohr        return $table->getResult();
191*8fed17f3SAndreas Gohr    }
192*8fed17f3SAndreas Gohr
193*8fed17f3SAndreas Gohr    protected function prepareLookup()
194*8fed17f3SAndreas Gohr    {
195*8fed17f3SAndreas Gohr        saveWikiText('title1', 'test', 'test');
196*8fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title1');
197*8fed17f3SAndreas Gohr        $pageMeta->setTitle('This is a title');
198*8fed17f3SAndreas Gohr
199*8fed17f3SAndreas Gohr        saveWikiText('title2', 'test', 'test');
200*8fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title2');
201*8fed17f3SAndreas Gohr        $pageMeta->setTitle('This is a 2nd title');
202*8fed17f3SAndreas Gohr
203*8fed17f3SAndreas Gohr        saveWikiText('title3', 'test', 'test');
204*8fed17f3SAndreas Gohr        $pageMeta = new PageMeta('title3');
205*8fed17f3SAndreas Gohr        $pageMeta->setTitle('Another Title');
206*8fed17f3SAndreas Gohr
207*8fed17f3SAndreas Gohr        $this->loadSchemaJSON('pageschema');
208*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
209*8fed17f3SAndreas Gohr        $access->saveData(
210*8fed17f3SAndreas Gohr            [
211*8fed17f3SAndreas Gohr                'singlepage' => 'title1',
212*8fed17f3SAndreas Gohr                'multipage' => ['title1'],
213*8fed17f3SAndreas Gohr                'singletitle' => 'title1',
214*8fed17f3SAndreas Gohr                'multititle' => ['title1'],
215*8fed17f3SAndreas Gohr            ]
216*8fed17f3SAndreas Gohr        );
217*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
218*8fed17f3SAndreas Gohr        $access->saveData(
219*8fed17f3SAndreas Gohr            [
220*8fed17f3SAndreas Gohr                'singlepage' => 'title2',
221*8fed17f3SAndreas Gohr                'multipage' => ['title2'],
222*8fed17f3SAndreas Gohr                'singletitle' => 'title2',
223*8fed17f3SAndreas Gohr                'multititle' => ['title2'],
224*8fed17f3SAndreas Gohr            ]
225*8fed17f3SAndreas Gohr        );
226*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('pageschema');
227*8fed17f3SAndreas Gohr        $access->saveData(
228*8fed17f3SAndreas Gohr            [
229*8fed17f3SAndreas Gohr                'singlepage' => 'title3',
230*8fed17f3SAndreas Gohr                'multipage' => ['title3'],
231*8fed17f3SAndreas Gohr                'singletitle' => 'title3',
232*8fed17f3SAndreas Gohr                'multititle' => ['title3'],
233*8fed17f3SAndreas Gohr            ]
234*8fed17f3SAndreas Gohr        );
235*8fed17f3SAndreas Gohr    }
236*8fed17f3SAndreas Gohr
237*8fed17f3SAndreas Gohr    protected function prepareDatetime()
238*8fed17f3SAndreas Gohr    {
239*8fed17f3SAndreas Gohr        $this->loadSchemaJSON('datetime');
240*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
241*8fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-01 12:00']);
242*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
243*8fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-02 00:00']);
244*8fed17f3SAndreas Gohr        $access = MockAccessTableAlias::getGlobalAccess('datetime');
245*8fed17f3SAndreas Gohr        $access->saveData(['field' => '2023-01-02 12:00']);
246*8fed17f3SAndreas Gohr    }
247*8fed17f3SAndreas Gohr}
248