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->prevents( 'createaccount' ), $fields['CreateAccount']['default'] );
92 $this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
93 $this->assertSame( $block->prevents( 'editownusertalk' ), $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
),
128 // Refresh the block from the database.
129 $block = Block
::newFromTarget( $block->getTarget() );
131 $page = $this->newSpecialPage();
133 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
134 $wrappedPage->target
= $block->getTarget();
135 $fields = $wrappedPage->getFormFields();
138 $pageMars->getTitle()->getPrefixedText(),
139 $pageSaturn->getTitle()->getPrefixedText(),
142 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
143 $this->assertSame( 'partial', $fields['EditingRestriction']['default'] );
144 $this->assertSame( implode( "\n", $titles ), $fields['PageRestrictions']['default'] );
148 * @covers ::processForm()
150 public function testProcessForm() {
151 $this->setMwGlobals( [
152 'wgEnablePartialBlocks' => false,
154 $badActor = $this->getTestUser()->getUser();
155 $context = RequestContext
::getMain();
157 $page = $this->newSpecialPage();
159 $expiry = 'infinity';
161 'Target' => (string)$badActor,
162 'Expiry' => 'infinity',
167 'CreateAccount' => '0',
168 'DisableUTEdit' => '0',
169 'DisableEmail' => '0',
175 $result = $page->processForm( $data, $context );
177 $this->assertTrue( $result );
179 $block = Block
::newFromTarget( $badActor );
180 $this->assertSame( $reason, $block->mReason
);
181 $this->assertSame( $expiry, $block->getExpiry() );
185 * @covers ::processForm()
187 public function testProcessFormExisting() {
188 $this->setMwGlobals( [
189 'wgEnablePartialBlocks' => false,
191 $badActor = $this->getTestUser()->getUser();
192 $sysop = $this->getTestSysop()->getUser();
193 $context = RequestContext
::getMain();
195 // Create a block that will be updated.
196 $block = new \
Block( [
197 'address' => $badActor->getName(),
198 'user' => $badActor->getId(),
199 'by' => $sysop->getId(),
200 'expiry' => 'infinity',
202 'enableAutoblock' => false,
206 $page = $this->newSpecialPage();
208 $expiry = 'infinity';
210 'Target' => (string)$badActor,
211 'Expiry' => 'infinity',
216 'CreateAccount' => '0',
217 'DisableUTEdit' => '0',
218 'DisableEmail' => '0',
224 $result = $page->processForm( $data, $context );
226 $this->assertTrue( $result );
228 $block = Block
::newFromTarget( $badActor );
229 $this->assertSame( $reason, $block->mReason
);
230 $this->assertSame( $expiry, $block->getExpiry() );
231 $this->assertSame( '1', $block->isAutoblocking() );
235 * @covers ::processForm()
237 public function testProcessFormRestrictions() {
238 $this->setMwGlobals( [
239 'wgEnablePartialBlocks' => true,
241 $badActor = $this->getTestUser()->getUser();
242 $context = RequestContext
::getMain();
244 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
245 $pageMars = $this->getExistingTestPage( 'Mars' );
248 $pageSaturn->getTitle()->getText(),
249 $pageMars->getTitle()->getText(),
252 $page = $this->newSpecialPage();
254 $expiry = 'infinity';
256 'Target' => (string)$badActor,
257 'Expiry' => 'infinity',
262 'CreateAccount' => '0',
263 'DisableUTEdit' => '0',
264 'DisableEmail' => '0',
269 'EditingRestriction' => 'partial',
270 'PageRestrictions' => implode( "\n", $titles ),
271 'NamespaceRestrictions' => '',
273 $result = $page->processForm( $data, $context );
275 $this->assertTrue( $result );
277 $block = Block
::newFromTarget( $badActor );
278 $this->assertSame( $reason, $block->mReason
);
279 $this->assertSame( $expiry, $block->getExpiry() );
280 $this->assertCount( 2, $block->getRestrictions() );
281 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
282 new PageRestriction( $block->getId(), $pageMars->getId() ),
283 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
288 * @covers ::processForm()
290 public function testProcessFormRestrictionsChange() {
291 $this->setMwGlobals( [
292 'wgEnablePartialBlocks' => true,
294 $badActor = $this->getTestUser()->getUser();
295 $context = RequestContext
::getMain();
297 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
298 $pageMars = $this->getExistingTestPage( 'Mars' );
301 $pageSaturn->getTitle()->getText(),
302 $pageMars->getTitle()->getText(),
305 // Create a partial block.
306 $page = $this->newSpecialPage();
308 $expiry = 'infinity';
310 'Target' => (string)$badActor,
311 'Expiry' => 'infinity',
316 'CreateAccount' => '0',
317 'DisableUTEdit' => '0',
318 'DisableEmail' => '0',
323 'EditingRestriction' => 'partial',
324 'PageRestrictions' => implode( "\n", $titles ),
325 'NamespaceRestrictions' => '',
327 $result = $page->processForm( $data, $context );
329 $this->assertTrue( $result );
331 $block = Block
::newFromTarget( $badActor );
332 $this->assertSame( $reason, $block->mReason
);
333 $this->assertSame( $expiry, $block->getExpiry() );
334 $this->assertFalse( $block->isSitewide() );
335 $this->assertCount( 2, $block->getRestrictions() );
336 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
337 new PageRestriction( $block->getId(), $pageMars->getId() ),
338 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
341 // Remove a page from the partial block.
342 $data['PageRestrictions'] = $pageMars->getTitle()->getText();
343 $result = $page->processForm( $data, $context );
345 $this->assertTrue( $result );
347 $block = Block
::newFromTarget( $badActor );
348 $this->assertSame( $reason, $block->mReason
);
349 $this->assertSame( $expiry, $block->getExpiry() );
350 $this->assertFalse( $block->isSitewide() );
351 $this->assertCount( 1, $block->getRestrictions() );
352 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
353 new PageRestriction( $block->getId(), $pageMars->getId() ),
356 // Remove the last page from the block.
357 $data['PageRestrictions'] = '';
358 $result = $page->processForm( $data, $context );
360 $this->assertTrue( $result );
362 $block = Block
::newFromTarget( $badActor );
363 $this->assertSame( $reason, $block->mReason
);
364 $this->assertSame( $expiry, $block->getExpiry() );
365 $this->assertFalse( $block->isSitewide() );
366 $this->assertCount( 0, $block->getRestrictions() );
368 // Change to sitewide.
369 $data['EditingRestriction'] = 'sitewide';
370 $result = $page->processForm( $data, $context );
372 $this->assertTrue( $result );
374 $block = Block
::newFromTarget( $badActor );
375 $this->assertSame( $reason, $block->mReason
);
376 $this->assertSame( $expiry, $block->getExpiry() );
377 $this->assertTrue( $block->isSitewide() );
378 $this->assertCount( 0, $block->getRestrictions() );
380 // Ensure that there are no restrictions where the blockId is 0.
381 $count = $this->db
->selectRowCount(
382 'ipblocks_restrictions',
384 [ 'ir_ipb_id' => 0 ],
387 $this->assertSame( 0, $count );
391 * @dataProvider provideCheckUnblockSelf
392 * @covers ::checkUnblockSelf
394 public function testCheckUnblockSelf(
402 $this->setGroupPermissions( 'sysop', 'unblockself', true );
403 $this->setGroupPermissions( 'user', 'block', true );
404 // Getting errors about creating users in db in provider.
405 // Need to use mutable to ensure different named testusers.
407 'u1' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
408 'u2' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
409 'u3' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
410 'u4' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
411 'nonsysop' => $this->getTestUser()->getUser()
413 foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
414 $
$var = $users[$
$var];
417 $block = new \
Block( [
418 'address' => $blockedUser->getName(),
419 'user' => $blockedUser->getId(),
420 'by' => $blockPerformer->getId(),
421 'expiry' => 'infinity',
423 'enableAutoblock' => true,
429 SpecialBlock
::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
435 public function provideCheckUnblockSelf() {
436 // 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
438 [ 'u1', 'u2', 'u3', 'u4', true, 'Unrelated users' ],
439 [ 'u1', 'u2', 'u1', 'u4', 'ipbblocked', 'Block unrelated while blocked' ],
440 [ 'u1', 'u2', 'u1', 'u1', true, 'Has unblockself' ],
441 [ 'nonsysop', 'u2', 'nonsysop', 'nonsysop', 'ipbnounblockself', 'no unblockself' ],
442 [ 'nonsysop', 'nonsysop', 'nonsysop', 'nonsysop', true, 'no unblockself but can de-selfblock' ],
443 [ 'u1', 'u2', 'u1', 'u2', true, 'Can block user who blocked' ],
447 protected function insertBlock() {
448 $badActor = $this->getTestUser()->getUser();
449 $sysop = $this->getTestSysop()->getUser();
451 $block = new \
Block( [
452 'address' => $badActor->getName(),
453 'user' => $badActor->getId(),
454 'by' => $sysop->getId(),
455 'expiry' => 'infinity',
457 'enableAutoblock' => true,
465 protected function resetTables() {
466 $this->db
->delete( 'ipblocks', '*', __METHOD__
);
467 $this->db
->delete( 'ipblocks_restrictions', '*', __METHOD__
);