Merge "Accept BCP 47 codes in LanguageConverter rules"
[lhc/web/wiklou.git] / tests / phpunit / includes / block / BlockRestrictionTest.php
1 <?php
2
3 namespace MediaWiki\Tests\Block;
4
5 use MediaWiki\Block\BlockRestriction;
6 use MediaWiki\Block\Restriction\PageRestriction;
7 use MediaWiki\Block\Restriction\Restriction;
8
9 /**
10 * @group Database
11 * @group Blocking
12 * @coversDefaultClass \MediaWiki\Block\BlockRestriction
13 */
14 class BlockRestrictionTest extends \MediaWikiLangTestCase {
15
16 public function tearDown() {
17 parent::tearDown();
18 $this->resetTables();
19 }
20
21 /**
22 * @covers ::loadByBlockId
23 * @covers ::resultToRestrictions
24 * @covers ::rowToRestriction
25 */
26 public function testLoadMultipleRestrictions() {
27 $block = $this->insertBlock();
28
29 $pageFoo = $this->getExistingTestPage( 'Foo' );
30 $pageBar = $this->getExistingTestPage( 'Bar' );
31
32 BlockRestriction::insert( [
33 new PageRestriction( $block->getId(), $pageFoo->getId() ),
34 new PageRestriction( $block->getId(), $pageBar->getId() ),
35 ] );
36
37 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
38
39 $this->assertCount( 2, $restrictions );
40 }
41
42 /**
43 * @covers ::loadByBlockId
44 * @covers ::resultToRestrictions
45 * @covers ::rowToRestriction
46 */
47 public function testWithNoRestrictions() {
48 $block = $this->insertBlock();
49 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
50 $this->assertEmpty( $restrictions );
51 }
52
53 /**
54 * @covers ::loadByBlockId
55 * @covers ::resultToRestrictions
56 * @covers ::rowToRestriction
57 */
58 public function testWithEmptyParam() {
59 $restrictions = BlockRestriction::loadByBlockId( [] );
60
61 $this->assertEmpty( $restrictions );
62 }
63
64 /**
65 * @covers ::loadByBlockId
66 * @covers ::resultToRestrictions
67 * @covers ::rowToRestriction
68 */
69 public function testIgnoreNotSupportedTypes() {
70 $block = $this->insertBlock();
71
72 $pageFoo = $this->getExistingTestPage( 'Foo' );
73 $pageBar = $this->getExistingTestPage( 'Bar' );
74
75 // valid type
76 $this->insertRestriction( $block->getId(), PageRestriction::TYPE_ID, $pageFoo->getId() );
77
78 // invalid type
79 $this->insertRestriction( $block->getId(), 9, $pageBar->getId() );
80
81 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
82 $this->assertCount( 1, $restrictions );
83 }
84
85 /**
86 * @covers ::loadByBlockId
87 * @covers ::resultToRestrictions
88 * @covers ::rowToRestriction
89 */
90 public function testMappingRestrictionObject() {
91 $block = $this->insertBlock();
92 $title = 'Lady Macbeth';
93 $page = $this->getExistingTestPage( $title );
94
95 BlockRestriction::insert( [
96 new PageRestriction( $block->getId(), $page->getId() ),
97 ] );
98
99 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
100
101 list( $pageRestriction ) = $restrictions;
102 $this->assertInstanceOf( PageRestriction::class, $pageRestriction );
103 $this->assertEquals( $block->getId(), $pageRestriction->getBlockId() );
104 $this->assertEquals( $page->getId(), $pageRestriction->getValue() );
105 $this->assertEquals( $pageRestriction->getType(), PageRestriction::TYPE );
106 $this->assertEquals( $pageRestriction->getTitle()->getText(), $title );
107 }
108
109 /**
110 * @covers ::insert
111 */
112 public function testInsert() {
113 $block = $this->insertBlock();
114
115 $pageFoo = $this->getExistingTestPage( 'Foo' );
116 $pageBar = $this->getExistingTestPage( 'Bar' );
117
118 $restrictions = [
119 new \stdClass(),
120 new PageRestriction( $block->getId(), $pageFoo->getId() ),
121 new PageRestriction( $block->getId(), $pageBar->getId() ),
122 ];
123
124 $result = BlockRestriction::insert( $restrictions );
125 $this->assertTrue( $result );
126
127 $restrictions = [
128 new \stdClass(),
129 ];
130
131 $result = BlockRestriction::insert( $restrictions );
132 $this->assertFalse( $result );
133
134 $result = BlockRestriction::insert( [] );
135 $this->assertFalse( $result );
136 }
137
138 /**
139 * @covers ::insert
140 */
141 public function testInsertTypes() {
142 $block = $this->insertBlock();
143
144 $pageFoo = $this->getExistingTestPage( 'Foo' );
145 $pageBar = $this->getExistingTestPage( 'Bar' );
146
147 $namespace = $this->createMock( Restriction::class );
148 $namespace->method( 'toRow' )
149 ->willReturn( [
150 'ir_ipb_id' => $block->getId(),
151 'ir_type' => 2,
152 'ir_value' => 0,
153 ] );
154
155 $invalid = $this->createMock( Restriction::class );
156 $invalid->method( 'toRow' )
157 ->willReturn( [
158 'ir_ipb_id' => $block->getId(),
159 'ir_type' => 9,
160 'ir_value' => 42,
161 ] );
162
163 $restrictions = [
164 new \stdClass(),
165 new PageRestriction( $block->getId(), $pageFoo->getId() ),
166 new PageRestriction( $block->getId(), $pageBar->getId() ),
167 $namespace,
168 $invalid,
169 ];
170
171 $result = BlockRestriction::insert( $restrictions );
172 $this->assertTrue( $result );
173
174 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
175 $this->assertCount( 2, $restrictions );
176 }
177
178 /**
179 * @covers ::update
180 * @covers ::restrictionsByBlockId
181 * @covers ::restrictionsToRemove
182 */
183 public function testUpdateInsert() {
184 $block = $this->insertBlock();
185 $pageFoo = $this->getExistingTestPage( 'Foo' );
186 $pageBar = $this->getExistingTestPage( 'Bar' );
187 BlockRestriction::insert( [
188 new PageRestriction( $block->getId(), $pageFoo->getId() ),
189 ] );
190
191 BlockRestriction::update( [
192 new \stdClass(),
193 new PageRestriction( $block->getId(), $pageBar->getId() ),
194 ] );
195
196 $db = wfGetDb( DB_REPLICA );
197 $result = $db->select(
198 [ 'ipblocks_restrictions' ],
199 [ '*' ],
200 [ 'ir_ipb_id' => $block->getId() ]
201 );
202
203 $this->assertEquals( 1, $result->numRows() );
204 $row = $result->fetchObject();
205 $this->assertEquals( $block->getId(), $row->ir_ipb_id );
206 $this->assertEquals( $pageBar->getId(), $row->ir_value );
207 }
208
209 /**
210 * @covers ::update
211 * @covers ::restrictionsByBlockId
212 * @covers ::restrictionsToRemove
213 */
214 public function testUpdateChange() {
215 $block = $this->insertBlock();
216 $page = $this->getExistingTestPage( 'Foo' );
217
218 BlockRestriction::update( [
219 new PageRestriction( $block->getId(), $page->getId() ),
220 ] );
221
222 $db = wfGetDb( DB_REPLICA );
223 $result = $db->select(
224 [ 'ipblocks_restrictions' ],
225 [ '*' ],
226 [ 'ir_ipb_id' => $block->getId() ]
227 );
228
229 $this->assertEquals( 1, $result->numRows() );
230 $row = $result->fetchObject();
231 $this->assertEquals( $block->getId(), $row->ir_ipb_id );
232 $this->assertEquals( $page->getId(), $row->ir_value );
233 }
234
235 /**
236 * @covers ::update
237 * @covers ::restrictionsByBlockId
238 * @covers ::restrictionsToRemove
239 */
240 public function testUpdateNoRestrictions() {
241 $block = $this->insertBlock();
242
243 BlockRestriction::update( [] );
244
245 $db = wfGetDb( DB_REPLICA );
246 $result = $db->select(
247 [ 'ipblocks_restrictions' ],
248 [ '*' ],
249 [ 'ir_ipb_id' => $block->getId() ]
250 );
251
252 $this->assertEquals( 0, $result->numRows() );
253 }
254
255 /**
256 * @covers ::update
257 * @covers ::restrictionsByBlockId
258 * @covers ::restrictionsToRemove
259 */
260 public function testUpdateSame() {
261 $block = $this->insertBlock();
262 $page = $this->getExistingTestPage( 'Foo' );
263 BlockRestriction::insert( [
264 new PageRestriction( $block->getId(), $page->getId() ),
265 ] );
266
267 BlockRestriction::update( [
268 new PageRestriction( $block->getId(), $page->getId() ),
269 ] );
270
271 $db = wfGetDb( DB_REPLICA );
272 $result = $db->select(
273 [ 'ipblocks_restrictions' ],
274 [ '*' ],
275 [ 'ir_ipb_id' => $block->getId() ]
276 );
277
278 $this->assertEquals( 1, $result->numRows() );
279 $row = $result->fetchObject();
280 $this->assertEquals( $block->getId(), $row->ir_ipb_id );
281 $this->assertEquals( $page->getId(), $row->ir_value );
282 }
283
284 /**
285 * @covers ::updateByParentBlockId
286 */
287 public function testDeleteAllUpdateByParentBlockId() {
288 // Create a block and an autoblock (a child block)
289 $block = $this->insertBlock();
290 $pageFoo = $this->getExistingTestPage( 'Foo' );
291 $pageBar = $this->getExistingTestPage( 'Bar' );
292 BlockRestriction::insert( [
293 new PageRestriction( $block->getId(), $pageFoo->getId() ),
294 ] );
295 $autoblockId = $block->doAutoblock( '127.0.0.1' );
296
297 // Ensure that the restrictions on the block have not changed.
298 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
299 $this->assertCount( 1, $restrictions );
300 $this->assertEquals( $pageFoo->getId(), $restrictions[0]->getValue() );
301
302 // Ensure that the restrictions on the autoblock are the same as the block.
303 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
304 $this->assertCount( 1, $restrictions );
305 $this->assertEquals( $pageFoo->getId(), $restrictions[0]->getValue() );
306
307 // Update the restrictions on the autoblock (but leave the block unchanged)
308 BlockRestriction::updateByParentBlockId( $block->getId(), [
309 new PageRestriction( $block->getId(), $pageBar->getId() ),
310 ] );
311
312 // Ensure that the restrictions on the block have not changed.
313 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
314 $this->assertCount( 1, $restrictions );
315 $this->assertEquals( $pageFoo->getId(), $restrictions[0]->getValue() );
316
317 // Ensure that the restrictions on the autoblock have been updated.
318 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
319 $this->assertCount( 1, $restrictions );
320 $this->assertEquals( $pageBar->getId(), $restrictions[0]->getValue() );
321 }
322
323 /**
324 * @covers ::updateByParentBlockId
325 */
326 public function testUpdateByParentBlockId() {
327 // Create a block and an autoblock (a child block)
328 $block = $this->insertBlock();
329 $page = $this->getExistingTestPage( 'Foo' );
330 BlockRestriction::insert( [
331 new PageRestriction( $block->getId(), $page->getId() ),
332 ] );
333 $autoblockId = $block->doAutoblock( '127.0.0.1' );
334
335 // Ensure that the restrictions on the block have not changed.
336 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
337 $this->assertCount( 1, $restrictions );
338
339 // Ensure that the restrictions on the autoblock have not changed.
340 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
341 $this->assertCount( 1, $restrictions );
342
343 // Remove the restrictions on the autoblock (but leave the block unchanged)
344 BlockRestriction::updateByParentBlockId( $block->getId(), [] );
345
346 // Ensure that the restrictions on the block have not changed.
347 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
348 $this->assertCount( 1, $restrictions );
349
350 // Ensure that the restrictions on the autoblock have been updated.
351 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
352 $this->assertCount( 0, $restrictions );
353 }
354
355 /**
356 * @covers ::updateByParentBlockId
357 */
358 public function testNoAutoblocksUpdateByParentBlockId() {
359 // Create a block with no autoblock.
360 $block = $this->insertBlock();
361 $page = $this->getExistingTestPage( 'Foo' );
362 BlockRestriction::insert( [
363 new PageRestriction( $block->getId(), $page->getId() ),
364 ] );
365
366 // Ensure that the restrictions on the block have not changed.
367 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
368 $this->assertCount( 1, $restrictions );
369
370 // Update the restrictions on any autoblocks (there are none).
371 BlockRestriction::updateByParentBlockId( $block->getId(), $restrictions );
372
373 // Ensure that the restrictions on the block have not changed.
374 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
375 $this->assertCount( 1, $restrictions );
376 }
377
378 /**
379 * @covers ::delete
380 */
381 public function testDelete() {
382 $block = $this->insertBlock();
383 $page = $this->getExistingTestPage( 'Foo' );
384 BlockRestriction::insert( [
385 new PageRestriction( $block->getId(), $page->getId() ),
386 ] );
387
388 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
389 $this->assertCount( 1, $restrictions );
390
391 $result = BlockRestriction::delete( array_merge( $restrictions, [ new \stdClass() ] ) );
392 $this->assertTrue( $result );
393
394 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
395 $this->assertCount( 0, $restrictions );
396 }
397
398 /**
399 * @covers ::deleteByBlockId
400 */
401 public function testDeleteByBlockId() {
402 $block = $this->insertBlock();
403 $page = $this->getExistingTestPage( 'Foo' );
404 BlockRestriction::insert( [
405 new PageRestriction( $block->getId(), $page->getId() ),
406 ] );
407
408 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
409 $this->assertCount( 1, $restrictions );
410
411 $result = BlockRestriction::deleteByBlockId( $block->getId() );
412 $this->assertNotFalse( $result );
413
414 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
415 $this->assertCount( 0, $restrictions );
416 }
417
418 /**
419 * @covers ::deleteByParentBlockId
420 */
421 public function testDeleteByParentBlockId() {
422 // Create a block with no autoblock.
423 $block = $this->insertBlock();
424 $page = $this->getExistingTestPage( 'Foo' );
425 BlockRestriction::insert( [
426 new PageRestriction( $block->getId(), $page->getId() ),
427 ] );
428 $autoblockId = $block->doAutoblock( '127.0.0.1' );
429
430 // Ensure that the restrictions on the block have not changed.
431 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
432 $this->assertCount( 1, $restrictions );
433
434 // Ensure that the restrictions on the autoblock are the same as the block.
435 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
436 $this->assertCount( 1, $restrictions );
437
438 // Remove all of the restrictions on the autoblock (but leave the block unchanged).
439 $result = BlockRestriction::deleteByParentBlockId( $block->getId() );
440 // NOTE: commented out until https://gerrit.wikimedia.org/r/c/mediawiki/core/+/469324 is merged
441 //$this->assertTrue( $result );
442
443 // Ensure that the restrictions on the block have not changed.
444 $restrictions = BlockRestriction::loadByBlockId( $block->getId() );
445 $this->assertCount( 1, $restrictions );
446
447 // Ensure that the restrictions on the autoblock have been removed.
448 $restrictions = BlockRestriction::loadByBlockId( $autoblockId );
449 $this->assertCount( 0, $restrictions );
450 }
451
452 /**
453 * @covers ::equals
454 * @dataProvider equalsDataProvider
455 *
456 * @param array $a
457 * @param array $b
458 * @param bool $expected
459 */
460 public function testEquals( array $a, array $b, $expected ) {
461 $this->assertSame( $expected, BlockRestriction::equals( $a, $b ) );
462 }
463
464 public function equalsDataProvider() {
465 return [
466 [
467 [
468 new \stdClass(),
469 new PageRestriction( 1, 1 ),
470 ],
471 [
472 new \stdClass(),
473 new PageRestriction( 1, 2 )
474 ],
475 false,
476 ],
477 [
478 [
479 new PageRestriction( 1, 1 ),
480 ],
481 [
482 new PageRestriction( 1, 1 ),
483 new PageRestriction( 1, 2 )
484 ],
485 false,
486 ],
487 [
488 [],
489 [],
490 true,
491 ],
492 [
493 [
494 new PageRestriction( 1, 1 ),
495 new PageRestriction( 1, 2 ),
496 new PageRestriction( 2, 3 ),
497 ],
498 [
499 new PageRestriction( 2, 3 ),
500 new PageRestriction( 1, 2 ),
501 new PageRestriction( 1, 1 ),
502 ],
503 true
504 ],
505 ];
506 }
507
508 /**
509 * @covers ::setBlockId
510 */
511 public function testSetBlockId() {
512 $restrictions = [
513 new \stdClass(),
514 new PageRestriction( 1, 1 ),
515 new PageRestriction( 1, 2 ),
516 ];
517
518 $result = BlockRestriction::setBlockId( 2, $restrictions );
519
520 $this->assertSame( 1, $restrictions[1]->getBlockId() );
521 $this->assertSame( 1, $restrictions[2]->getBlockId() );
522 $this->assertSame( 2, $result[0]->getBlockId() );
523 $this->assertSame( 2, $result[1]->getBlockId() );
524 }
525
526 protected function insertBlock() {
527 $badActor = $this->getTestUser()->getUser();
528 $sysop = $this->getTestSysop()->getUser();
529
530 $block = new \Block( [
531 'address' => $badActor->getName(),
532 'user' => $badActor->getId(),
533 'by' => $sysop->getId(),
534 'expiry' => 'infinity',
535 'sitewide' => 0,
536 'enableAutoblock' => true,
537 ] );
538
539 $block->insert();
540
541 return $block;
542 }
543
544 protected function insertRestriction( $blockId, $type, $value ) {
545 $this->db->insert( 'ipblocks_restrictions', [
546 'ir_ipb_id' => $blockId,
547 'ir_type' => $type,
548 'ir_value' => $value,
549 ] );
550 }
551
552 protected function resetTables() {
553 $this->db->delete( 'ipblocks', '*', __METHOD__ );
554 $this->db->delete( 'ipblocks_restrictions', '*', __METHOD__ );
555 }
556 }