RCFilters: define consistent interface in ChangesListFilterGroup
[lhc/web/wiklou.git] / tests / phpunit / includes / changes / ChangesListStringOptionsFilterGroupTest.php
1 <?php
2
3 use Wikimedia\TestingAccessWrapper;
4
5 /**
6 * @covers ChangesListStringOptionsFilterGroup
7 */
8 class ChangesListStringOptionsFilterGroupTest extends MediaWikiTestCase {
9 /**
10 * @expectedException MWException
11 */
12 public function testIsFullCoverage() {
13 $falseGroup = TestingAccessWrapper::newFromObject(
14 new ChangesListStringOptionsFilterGroup( [
15 'name' => 'group',
16 'filters' => [],
17 'isFullCoverage' => false,
18 'queryCallable' => function () {
19 }
20 ] )
21 );
22
23 $this->assertSame(
24 false,
25 $falseGroup->isFullCoverage
26 );
27
28 // Should throw due to missing isFullCoverage
29 $undefinedFullCoverageGroup = new ChangesListStringOptionsFilterGroup( [
30 'name' => 'othergroup',
31 'filters' => [],
32 ] );
33 }
34
35 /**
36 * @param array $filterDefinitions Array of filter definitions
37 * @param array $expectedValues Array of values callback should receive
38 * @param string $input Value in URL
39 *
40 * @dataProvider provideModifyQuery
41 */
42 public function testModifyQuery( $filterDefinitions, $expectedValues, $input ) {
43 $queryCallable = function (
44 $className,
45 $ctx,
46 $dbr,
47 &$tables,
48 &$fields,
49 &$conds,
50 &$query_options,
51 &$join_conds,
52 $actualSelectedValues
53 ) use ( $expectedValues ) {
54 $this->assertSame(
55 $expectedValues,
56 $actualSelectedValues
57 );
58 };
59
60 $groupDefinition = [
61 'name' => 'group',
62 'default' => '',
63 'isFullCoverage' => true,
64 'filters' => $filterDefinitions,
65 'queryCallable' => $queryCallable,
66 ];
67
68 $this->modifyQueryHelper( $groupDefinition, $input );
69 }
70
71 public function provideModifyQuery() {
72 $mixedFilters = [
73 [
74 'name' => 'foo',
75 ],
76 [
77 'name' => 'baz',
78 ],
79 [
80 'name' => 'goo'
81 ],
82 ];
83
84 return [
85 [
86 $mixedFilters,
87 [ 'baz', 'foo', ],
88 'foo;bar;BaZ;invalid',
89 ],
90
91 [
92 $mixedFilters,
93 [ 'baz', 'foo', 'goo' ],
94 'all',
95 ],
96 ];
97 }
98
99 /**
100 * @param array $filterDefinitions Array of filter definitions
101 * @param string $input Value in URL
102 * @param string $message Message thrown by exception
103 *
104 * @dataProvider provideNoOpModifyQuery
105 */
106 public function testNoOpModifyQuery( $filterDefinitions, $input, $message ) {
107 $noFiltersAllowedCallable = function (
108 $className,
109 $ctx,
110 $dbr,
111 &$tables,
112 &$fields,
113 &$conds,
114 &$query_options,
115 &$join_conds,
116 $actualSelectedValues
117 ) use ( $message ) {
118 throw new MWException( $message );
119 };
120
121 $groupDefinition = [
122 'name' => 'group',
123 'default' => '',
124 'isFullCoverage' => true,
125 'filters' => $filterDefinitions,
126 'queryCallable' => $noFiltersAllowedCallable,
127 ];
128
129 $this->modifyQueryHelper( $groupDefinition, $input );
130
131 $this->assertTrue(
132 true,
133 'Test successfully completed without calling queryCallable'
134 );
135 }
136
137 public function provideNoOpModifyQuery() {
138 $noFilters = [];
139
140 $normalFilters = [
141 [
142 'name' => 'foo',
143 ],
144 [
145 'name' => 'bar',
146 ]
147 ];
148
149 return [
150 [
151 $noFilters,
152 'disallowed1;disallowed3',
153 'The queryCallable should not be called if there are no filters',
154 ],
155
156 [
157 $normalFilters,
158 '',
159 'The queryCallable should not be called if no filters are selected',
160 ],
161
162 [
163 $normalFilters,
164 'invalid1',
165 'The queryCallable should not be called if no valid filters are selected',
166 ],
167 ];
168 }
169
170 protected function getSpecialPage() {
171 return $this->getMockBuilder( 'ChangesListSpecialPage' )
172 ->setConstructorArgs( [
173 'ChangesListSpecialPage',
174 '',
175 ] )
176 ->getMockForAbstractClass();
177 }
178
179 /**
180 * @param array $groupDefinition Group definition
181 * @param string $input Value in URL
182 *
183 * @dataProvider provideModifyQuery
184 */
185 protected function modifyQueryHelper( $groupDefinition, $input ) {
186 $ctx = $this->createMock( 'IContextSource' );
187 $dbr = $this->createMock( 'IDatabase' );
188 $tables = $fields = $conds = $query_options = $join_conds = [];
189
190 $group = new ChangesListStringOptionsFilterGroup( $groupDefinition );
191
192 $specialPage = $this->getSpecialPage();
193 $opts = new FormOptions();
194 $opts->add( $groupDefinition[ 'name' ], $input );
195
196 $group->modifyQuery(
197 $dbr,
198 $specialPage,
199 $tables,
200 $fields,
201 $conds,
202 $query_options,
203 $join_conds,
204 $opts,
205 true
206 );
207 }
208
209 public function testGetJsData() {
210 $definition = [
211 'name' => 'some-group',
212 'title' => 'some-group-title',
213 'default' => 'foo',
214 'priority' => 1,
215 'isFullCoverage' => false,
216 'queryCallable' => function () {
217 },
218 'filters' => [
219 [
220 'name' => 'foo',
221 'label' => 'foo-label',
222 'description' => 'foo-description',
223 'priority' => 2,
224 ],
225 [
226 'name' => 'bar',
227 'label' => 'bar-label',
228 'description' => 'bar-description',
229 'priority' => 4,
230 ]
231 ],
232 ];
233
234 $group = new ChangesListStringOptionsFilterGroup( $definition );
235
236 $this->assertArrayEquals(
237 [
238 'name' => 'some-group',
239 'title' => 'some-group-title',
240 'type' => ChangesListStringOptionsFilterGroup::TYPE,
241 'default' => 'foo',
242 'priority' => 1,
243 'fullCoverage' => false,
244 'filters' => [
245 [
246 'name' => 'bar',
247 'label' => 'bar-label',
248 'description' => 'bar-description',
249 'priority' => 4,
250 'cssClass' => null,
251 'conflicts' => [],
252 'subset' => [],
253 'defaultHighlightColor' => null,
254 ],
255 [
256 'name' => 'foo',
257 'label' => 'foo-label',
258 'description' => 'foo-description',
259 'priority' => 2,
260 'cssClass' => null,
261 'conflicts' => [],
262 'subset' => [],
263 'defaultHighlightColor' => null,
264 ],
265 ],
266 'conflicts' => [],
267 'separator' => ';',
268 'messageKeys' => [
269 'some-group-title',
270 'bar-label',
271 'bar-description',
272 'foo-label',
273 'foo-description',
274 ],
275 ],
276 $group->getJsData(),
277 /** ordered= */ false,
278 /** named= */ true
279 );
280 }
281 }