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