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