1<?php
2
3/**
4 * Helper tests for the tagging plugin
5 *
6 * @group plugin_tagging
7 * @group plugins
8 */
9class helper_plugin_tagging_test extends DokuWikiTest
10{
11    protected $pluginsEnabled = ['tagging', 'sqlite'];
12
13    /**
14     * Provide the test data
15     *
16     * @return array
17     */
18    public function dataTags()
19    {
20        return [
21            [
22                ['ortag' => ['image']],
23                'SELECT pid AS item, COUNT(*) AS cnt
24                FROM taggings
25                WHERE 1=1
26                AND CLEANTAG(tag) = CLEANTAG(?)
27                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
28                GROUP BY pid
29                ORDER BY cnt DESC, pid'
30            ],
31            [
32                ['ortag' => ['acks', 'image']],
33                'SELECT pid AS item, COUNT(*) AS cnt
34                FROM taggings
35                WHERE 1=1
36                AND CLEANTAG(tag) = CLEANTAG(?) OR CLEANTAG(tag) = CLEANTAG(?)
37                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
38                GROUP BY pid
39                ORDER BY cnt DESC, pid'
40            ],
41            [
42                ['andtag' => ['acks', 'image']],
43                'SELECT pid AS item, COUNT(*) AS cnt
44                FROM taggings
45                WHERE 1=1
46                AND CLEANTAG(tag) = CLEANTAG(?) OR CLEANTAG(tag) = CLEANTAG(?)
47                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
48                GROUP BY pid
49                HAVING cnt = 2
50                ORDER BY cnt DESC, pid'
51            ],
52            [
53                [
54                    'ortag' => ['image'],
55                    'ns' => ['wiki:*']
56                ],
57                'SELECT pid AS item, COUNT(*) AS cnt
58                FROM taggings
59                WHERE 1=1
60                AND pid GLOB ?
61                AND CLEANTAG(tag) = CLEANTAG(?)
62                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
63                GROUP BY pid
64                ORDER BY cnt DESC, pid'
65            ],
66            [
67                [
68                    'ortag' => ['image'],
69                    'notns' => ['wiki:*']
70                ],
71                'SELECT pid AS item, COUNT(*) AS cnt
72                FROM taggings
73                WHERE 1=1
74                AND pid NOT GLOB ?
75                AND CLEANTAG(tag) = CLEANTAG(?)
76                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
77                GROUP BY pid
78                ORDER BY cnt DESC, pid'
79
80            ],
81            [
82                [
83                    'ortag' => ['image'],
84                    'notns' => ['wiki:*', 'awiki:*']
85                ],
86                'SELECT pid AS item, COUNT(*) AS cnt
87                FROM taggings
88                WHERE 1=1
89                AND pid NOT GLOB ? AND pid NOT GLOB ?
90                AND CLEANTAG(tag) = CLEANTAG(?)
91                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
92                GROUP BY pid
93                ORDER BY cnt DESC, pid'
94            ],
95            [
96                ['ortag' => ['acks*']],
97                'SELECT pid AS item, COUNT(*) AS cnt
98                FROM taggings
99                WHERE 1=1
100                AND CLEANTAG(tag) GLOB CLEANTAG(?)
101                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
102                GROUP BY pid
103                ORDER BY cnt DESC, pid'
104            ],
105            [
106                ['ortag' => ['acks', 'image*']],
107                'SELECT pid AS item, COUNT(*) AS cnt
108                FROM taggings
109                WHERE 1=1
110                AND CLEANTAG(tag) = CLEANTAG(?) OR CLEANTAG(tag) GLOB CLEANTAG(?)
111                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
112                GROUP BY pid
113                ORDER BY cnt DESC, pid'
114            ],
115            [
116                ['ortag' => ['acks*', 'image']],
117                'SELECT pid AS item, COUNT(*) AS cnt
118                FROM taggings
119                WHERE 1=1
120                AND CLEANTAG(tag) GLOB CLEANTAG(?) OR CLEANTAG(tag) = CLEANTAG(?)
121                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
122                GROUP BY pid
123                ORDER BY cnt DESC, pid'
124            ],
125            [
126                ['ortag' => ['acks*', 'image*']],
127                'SELECT pid AS item, COUNT(*) AS cnt
128                FROM taggings
129                WHERE 1=1
130                AND CLEANTAG(tag) GLOB CLEANTAG(?) OR CLEANTAG(tag) GLOB CLEANTAG(?)
131                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
132                GROUP BY pid
133                ORDER BY cnt DESC, pid'
134            ],
135            [
136                ['andtag' => ['acks*', 'image*']],
137                'SELECT pid AS item, COUNT(*) AS cnt
138                FROM taggings
139                WHERE 1=1
140                AND CLEANTAG(tag) GLOB CLEANTAG(?) OR CLEANTAG(tag) GLOB CLEANTAG(?)
141                AND GETACCESSLEVEL(pid) >= '. AUTH_READ .'
142                GROUP BY pid
143                HAVING cnt = 2
144                ORDER BY cnt DESC, pid'
145            ],
146        ];
147    }
148
149    /**
150     * Search results
151     *
152     * @dataProvider dataTags
153     * @param array $filter
154     * @param string $expected
155     */
156    public function testSearchSql($filter, $expected)
157    {
158        /** @var helper_plugin_tagging_querybuilder $queryBuilder */
159        $queryBuilder = plugin_load('helper', 'tagging_querybuilder');
160        $queryBuilder->setField('pid');
161
162        if (isset($filter['andtag'])) {
163            $queryBuilder->setTags($filter['andtag']);
164            $queryBuilder->setLogicalAnd(true);
165        } else {
166            $queryBuilder->setTags($filter['ortag']);
167        }
168
169        if (isset($filter['ns'])) $queryBuilder->includeNS($filter['ns']);
170        if (isset($filter['notns'])) $queryBuilder->excludeNS($filter['notns']);
171
172        $actual = $queryBuilder->getPages()[0];
173        $this->assertEquals($this->toSingleLine($expected), $this->toSingleLine($actual));
174    }
175
176    /**
177     * @param string $string
178     * @return string
179     */
180    protected function toSingleLine($string)
181    {
182        $string = str_replace(["\r","\n"], '', $string);
183        $string = preg_replace('/ +/', ' ', $string);
184        return trim($string);
185    }
186}
187