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