3 use MediaWiki\Block\BlockRestriction
;
4 use MediaWiki\Block\Restriction\PageRestriction
;
5 use MediaWiki\Block\Restriction\NamespaceRestriction
;
6 use Wikimedia\TestingAccessWrapper
;
11 * @coversDefaultClass SpecialBlock
13 class SpecialBlockTest
extends SpecialPageTestBase
{
17 protected function newSpecialPage() {
18 return new SpecialBlock();
21 public function tearDown() {
27 * @covers ::getFormFields()
29 public function testGetFormFields() {
30 $this->setMwGlobals( [
31 'wgEnablePartialBlocks' => false,
32 'wgBlockAllowsUTEdit' => true,
34 $page = $this->newSpecialPage();
35 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
36 $fields = $wrappedPage->getFormFields();
37 $this->assertInternalType( 'array', $fields );
38 $this->assertArrayHasKey( 'Target', $fields );
39 $this->assertArrayHasKey( 'Expiry', $fields );
40 $this->assertArrayHasKey( 'Reason', $fields );
41 $this->assertArrayHasKey( 'CreateAccount', $fields );
42 $this->assertArrayHasKey( 'DisableUTEdit', $fields );
43 $this->assertArrayHasKey( 'AutoBlock', $fields );
44 $this->assertArrayHasKey( 'HardBlock', $fields );
45 $this->assertArrayHasKey( 'PreviousTarget', $fields );
46 $this->assertArrayHasKey( 'Confirm', $fields );
48 $this->assertArrayNotHasKey( 'EditingRestriction', $fields );
49 $this->assertArrayNotHasKey( 'PageRestrictions', $fields );
50 $this->assertArrayNotHasKey( 'NamespaceRestrictions', $fields );
54 * @covers ::getFormFields()
56 public function testGetFormFieldsPartialBlocks() {
57 $this->setMwGlobals( [
58 'wgEnablePartialBlocks' => true,
60 $page = $this->newSpecialPage();
61 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
62 $fields = $wrappedPage->getFormFields();
64 $this->assertArrayHasKey( 'EditingRestriction', $fields );
65 $this->assertArrayHasKey( 'PageRestrictions', $fields );
66 $this->assertArrayHasKey( 'NamespaceRestrictions', $fields );
70 * @covers ::maybeAlterFormDefaults()
72 public function testMaybeAlterFormDefaults() {
73 $this->setMwGlobals( [
74 'wgEnablePartialBlocks' => false,
75 'wgBlockAllowsUTEdit' => true,
78 $block = $this->insertBlock();
80 // Refresh the block from the database.
81 $block = Block
::newFromTarget( $block->getTarget() );
83 $page = $this->newSpecialPage();
85 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
86 $wrappedPage->target
= $block->getTarget();
87 $fields = $wrappedPage->getFormFields();
89 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
90 $this->assertSame( $block->isHardblock(), $fields['HardBlock']['default'] );
91 $this->assertSame( $block->isCreateAccountBlocked(), $fields['CreateAccount']['default'] );
92 $this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
93 $this->assertSame( !$block->isUsertalkEditAllowed(), $fields['DisableUTEdit']['default'] );
94 $this->assertSame( $block->mReason
, $fields['Reason']['default'] );
95 $this->assertSame( 'infinite', $fields['Expiry']['default'] );
99 * @covers ::maybeAlterFormDefaults()
101 public function testMaybeAlterFormDefaultsPartial() {
102 $this->setMwGlobals( [
103 'wgEnablePartialBlocks' => true,
106 $badActor = $this->getTestUser()->getUser();
107 $sysop = $this->getTestSysop()->getUser();
108 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
109 $pageMars = $this->getExistingTestPage( 'Mars' );
111 $block = new \
Block( [
112 'address' => $badActor->getName(),
113 'user' => $badActor->getId(),
114 'by' => $sysop->getId(),
115 'expiry' => 'infinity',
117 'enableAutoblock' => true,
120 $block->setRestrictions( [
121 new PageRestriction( 0, $pageSaturn->getId() ),
122 new PageRestriction( 0, $pageMars->getId() ),
123 new NamespaceRestriction( 0, NS_TALK
),
125 new PageRestriction( 0, 999999 ),
130 // Refresh the block from the database.
131 $block = Block
::newFromTarget( $block->getTarget() );
133 $page = $this->newSpecialPage();
135 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
136 $wrappedPage->target
= $block->getTarget();
137 $fields = $wrappedPage->getFormFields();
140 $pageMars->getTitle()->getPrefixedText(),
141 $pageSaturn->getTitle()->getPrefixedText(),
144 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
145 $this->assertSame( 'partial', $fields['EditingRestriction']['default'] );
146 $this->assertSame( implode( "\n", $titles ), $fields['PageRestrictions']['default'] );
150 * @covers ::processForm()
152 public function testProcessForm() {
153 $this->setMwGlobals( [
154 'wgEnablePartialBlocks' => false,
156 $badActor = $this->getTestUser()->getUser();
157 $context = RequestContext
::getMain();
159 $page = $this->newSpecialPage();
161 $expiry = 'infinity';
163 'Target' => (string)$badActor,
164 'Expiry' => 'infinity',
169 'CreateAccount' => '0',
170 'DisableUTEdit' => '0',
171 'DisableEmail' => '0',
177 $result = $page->processForm( $data, $context );
179 $this->assertTrue( $result );
181 $block = Block
::newFromTarget( $badActor );
182 $this->assertSame( $reason, $block->mReason
);
183 $this->assertSame( $expiry, $block->getExpiry() );
187 * @covers ::processForm()
189 public function testProcessFormExisting() {
190 $this->setMwGlobals( [
191 'wgEnablePartialBlocks' => false,
193 $badActor = $this->getTestUser()->getUser();
194 $sysop = $this->getTestSysop()->getUser();
195 $context = RequestContext
::getMain();
197 // Create a block that will be updated.
198 $block = new \
Block( [
199 'address' => $badActor->getName(),
200 'user' => $badActor->getId(),
201 'by' => $sysop->getId(),
202 'expiry' => 'infinity',
204 'enableAutoblock' => false,
208 $page = $this->newSpecialPage();
210 $expiry = 'infinity';
212 'Target' => (string)$badActor,
213 'Expiry' => 'infinity',
218 'CreateAccount' => '0',
219 'DisableUTEdit' => '0',
220 'DisableEmail' => '0',
226 $result = $page->processForm( $data, $context );
228 $this->assertTrue( $result );
230 $block = Block
::newFromTarget( $badActor );
231 $this->assertSame( $reason, $block->mReason
);
232 $this->assertSame( $expiry, $block->getExpiry() );
233 $this->assertSame( '1', $block->isAutoblocking() );
237 * @covers ::processForm()
239 public function testProcessFormRestrictions() {
240 $this->setMwGlobals( [
241 'wgEnablePartialBlocks' => true,
243 $badActor = $this->getTestUser()->getUser();
244 $context = RequestContext
::getMain();
246 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
247 $pageMars = $this->getExistingTestPage( 'Mars' );
250 $pageSaturn->getTitle()->getText(),
251 $pageMars->getTitle()->getText(),
254 $page = $this->newSpecialPage();
256 $expiry = 'infinity';
258 'Target' => (string)$badActor,
259 'Expiry' => 'infinity',
264 'CreateAccount' => '0',
265 'DisableUTEdit' => '0',
266 'DisableEmail' => '0',
271 'EditingRestriction' => 'partial',
272 'PageRestrictions' => implode( "\n", $titles ),
273 'NamespaceRestrictions' => '',
275 $result = $page->processForm( $data, $context );
277 $this->assertTrue( $result );
279 $block = Block
::newFromTarget( $badActor );
280 $this->assertSame( $reason, $block->mReason
);
281 $this->assertSame( $expiry, $block->getExpiry() );
282 $this->assertCount( 2, $block->getRestrictions() );
283 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
284 new PageRestriction( $block->getId(), $pageMars->getId() ),
285 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
290 * @covers ::processForm()
292 public function testProcessFormRestrictionsChange() {
293 $this->setMwGlobals( [
294 'wgEnablePartialBlocks' => true,
296 $badActor = $this->getTestUser()->getUser();
297 $context = RequestContext
::getMain();
299 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
300 $pageMars = $this->getExistingTestPage( 'Mars' );
303 $pageSaturn->getTitle()->getText(),
304 $pageMars->getTitle()->getText(),
307 // Create a partial block.
308 $page = $this->newSpecialPage();
310 $expiry = 'infinity';
312 'Target' => (string)$badActor,
313 'Expiry' => 'infinity',
318 'CreateAccount' => '0',
319 'DisableUTEdit' => '0',
320 'DisableEmail' => '0',
325 'EditingRestriction' => 'partial',
326 'PageRestrictions' => implode( "\n", $titles ),
327 'NamespaceRestrictions' => '',
329 $result = $page->processForm( $data, $context );
331 $this->assertTrue( $result );
333 $block = Block
::newFromTarget( $badActor );
334 $this->assertSame( $reason, $block->mReason
);
335 $this->assertSame( $expiry, $block->getExpiry() );
336 $this->assertFalse( $block->isSitewide() );
337 $this->assertCount( 2, $block->getRestrictions() );
338 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
339 new PageRestriction( $block->getId(), $pageMars->getId() ),
340 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
343 // Remove a page from the partial block.
344 $data['PageRestrictions'] = $pageMars->getTitle()->getText();
345 $result = $page->processForm( $data, $context );
347 $this->assertTrue( $result );
349 $block = Block
::newFromTarget( $badActor );
350 $this->assertSame( $reason, $block->mReason
);
351 $this->assertSame( $expiry, $block->getExpiry() );
352 $this->assertFalse( $block->isSitewide() );
353 $this->assertCount( 1, $block->getRestrictions() );
354 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
355 new PageRestriction( $block->getId(), $pageMars->getId() ),
358 // Remove the last page from the block.
359 $data['PageRestrictions'] = '';
360 $result = $page->processForm( $data, $context );
362 $this->assertTrue( $result );
364 $block = Block
::newFromTarget( $badActor );
365 $this->assertSame( $reason, $block->mReason
);
366 $this->assertSame( $expiry, $block->getExpiry() );
367 $this->assertFalse( $block->isSitewide() );
368 $this->assertCount( 0, $block->getRestrictions() );
370 // Change to sitewide.
371 $data['EditingRestriction'] = 'sitewide';
372 $result = $page->processForm( $data, $context );
374 $this->assertTrue( $result );
376 $block = Block
::newFromTarget( $badActor );
377 $this->assertSame( $reason, $block->mReason
);
378 $this->assertSame( $expiry, $block->getExpiry() );
379 $this->assertTrue( $block->isSitewide() );
380 $this->assertCount( 0, $block->getRestrictions() );
382 // Ensure that there are no restrictions where the blockId is 0.
383 $count = $this->db
->selectRowCount(
384 'ipblocks_restrictions',
386 [ 'ir_ipb_id' => 0 ],
389 $this->assertSame( 0, $count );
393 * @dataProvider provideCheckUnblockSelf
394 * @covers ::checkUnblockSelf
396 public function testCheckUnblockSelf(
404 $this->setMwGlobals( [
405 'wgBlockDisablesLogin' => false,
407 $this->setGroupPermissions( 'sysop', 'unblockself', true );
408 $this->setGroupPermissions( 'user', 'block', true );
409 // Getting errors about creating users in db in provider.
410 // Need to use mutable to ensure different named testusers.
412 'u1' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
413 'u2' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
414 'u3' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
415 'u4' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
416 'nonsysop' => $this->getTestUser()->getUser()
418 foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
419 $
$var = $users[$
$var];
422 $block = new \
Block( [
423 'address' => $blockedUser->getName(),
424 'user' => $blockedUser->getId(),
425 'by' => $blockPerformer->getId(),
426 'expiry' => 'infinity',
428 'enableAutoblock' => true,
434 SpecialBlock
::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
440 public function provideCheckUnblockSelf() {
441 // 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
443 [ 'u1', 'u2', 'u3', 'u4', true, 'Unrelated users' ],
444 [ 'u1', 'u2', 'u1', 'u4', 'ipbblocked', 'Block unrelated while blocked' ],
445 [ 'u1', 'u2', 'u1', 'u1', true, 'Has unblockself' ],
446 [ 'nonsysop', 'u2', 'nonsysop', 'nonsysop', 'ipbnounblockself', 'no unblockself' ],
447 [ 'nonsysop', 'nonsysop', 'nonsysop', 'nonsysop', true, 'no unblockself but can de-selfblock' ],
448 [ 'u1', 'u2', 'u1', 'u2', true, 'Can block user who blocked' ],
452 protected function insertBlock() {
453 $badActor = $this->getTestUser()->getUser();
454 $sysop = $this->getTestSysop()->getUser();
456 $block = new \
Block( [
457 'address' => $badActor->getName(),
458 'user' => $badActor->getId(),
459 'by' => $sysop->getId(),
460 'expiry' => 'infinity',
462 'enableAutoblock' => true,
470 protected function resetTables() {
471 $this->db
->delete( 'ipblocks', '*', __METHOD__
);
472 $this->db
->delete( 'ipblocks_restrictions', '*', __METHOD__
);