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