3 use MediaWiki\Block\BlockRestriction
;
4 use MediaWiki\Block\Restriction\PageRestriction
;
5 use Wikimedia\TestingAccessWrapper
;
10 * @coversDefaultClass SpecialBlock
12 class SpecialBlockTest
extends SpecialPageTestBase
{
16 protected function newSpecialPage() {
17 return new SpecialBlock();
20 public function tearDown() {
26 * @covers ::getFormFields()
28 public function testGetFormFields() {
29 $this->setMwGlobals( [
30 'wgEnablePartialBlocks' => false,
32 $page = $this->newSpecialPage();
33 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
34 $fields = $wrappedPage->getFormFields();
35 $this->assertInternalType( 'array', $fields );
36 $this->assertArrayHasKey( 'Target', $fields );
37 $this->assertArrayHasKey( 'Expiry', $fields );
38 $this->assertArrayHasKey( 'Reason', $fields );
39 $this->assertArrayHasKey( 'CreateAccount', $fields );
40 $this->assertArrayHasKey( 'DisableUTEdit', $fields );
41 $this->assertArrayHasKey( 'AutoBlock', $fields );
42 $this->assertArrayHasKey( 'HardBlock', $fields );
43 $this->assertArrayHasKey( 'PreviousTarget', $fields );
44 $this->assertArrayHasKey( 'Confirm', $fields );
46 $this->assertArrayNotHasKey( 'EditingRestriction', $fields );
47 $this->assertArrayNotHasKey( 'PageRestrictions', $fields );
51 * @covers ::getFormFields()
53 public function testGetFormFieldsPartialBlocks() {
54 $this->setMwGlobals( [
55 'wgEnablePartialBlocks' => true,
57 $page = $this->newSpecialPage();
58 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
59 $fields = $wrappedPage->getFormFields();
61 $this->assertArrayHasKey( 'EditingRestriction', $fields );
62 $this->assertArrayHasKey( 'PageRestrictions', $fields );
66 * @covers ::maybeAlterFormDefaults()
68 public function testMaybeAlterFormDefaults() {
69 $this->setMwGlobals( [
70 'wgEnablePartialBlocks' => false,
73 $block = $this->insertBlock();
75 // Refresh the block from the database.
76 $block = Block
::newFromTarget( $block->getTarget() );
78 $page = $this->newSpecialPage();
80 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
81 $wrappedPage->target
= $block->getTarget();
82 $fields = $wrappedPage->getFormFields();
84 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
85 $this->assertSame( $block->isHardblock(), $fields['HardBlock']['default'] );
86 $this->assertSame( $block->prevents( 'createaccount' ), $fields['CreateAccount']['default'] );
87 $this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
88 $this->assertSame( $block->prevents( 'editownusertalk' ), $fields['DisableUTEdit']['default'] );
89 $this->assertSame( $block->mReason
, $fields['Reason']['default'] );
90 $this->assertSame( 'infinite', $fields['Expiry']['default'] );
94 * @covers ::maybeAlterFormDefaults()
96 public function testMaybeAlterFormDefaultsPartial() {
97 $this->setMwGlobals( [
98 'wgEnablePartialBlocks' => true,
101 $badActor = $this->getTestUser()->getUser();
102 $sysop = $this->getTestSysop()->getUser();
103 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
104 $pageMars = $this->getExistingTestPage( 'Mars' );
106 $block = new \
Block( [
107 'address' => $badActor->getName(),
108 'user' => $badActor->getId(),
109 'by' => $sysop->getId(),
110 'expiry' => 'infinity',
112 'enableAutoblock' => true,
115 $block->setRestrictions( [
116 new PageRestriction( 0, $pageSaturn->getId() ),
117 new PageRestriction( 0, $pageMars->getId() ),
122 // Refresh the block from the database.
123 $block = Block
::newFromTarget( $block->getTarget() );
125 $page = $this->newSpecialPage();
127 $wrappedPage = TestingAccessWrapper
::newFromObject( $page );
128 $wrappedPage->target
= $block->getTarget();
129 $fields = $wrappedPage->getFormFields();
132 $pageMars->getTitle()->getPrefixedText(),
133 $pageSaturn->getTitle()->getPrefixedText(),
136 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
137 $this->assertSame( 'partial', $fields['EditingRestriction']['default'] );
138 $this->assertSame( implode( "\n", $titles ), $fields['PageRestrictions']['default'] );
142 * @covers ::processForm()
144 public function testProcessForm() {
145 $this->setMwGlobals( [
146 'wgEnablePartialBlocks' => false,
148 $badActor = $this->getTestUser()->getUser();
149 $context = RequestContext
::getMain();
151 $page = $this->newSpecialPage();
153 $expiry = 'infinity';
155 'Target' => (string)$badActor,
156 'Expiry' => 'infinity',
161 'CreateAccount' => '0',
162 'DisableUTEdit' => '0',
163 'DisableEmail' => '0',
169 $result = $page->processForm( $data, $context );
171 $this->assertTrue( $result );
173 $block = Block
::newFromTarget( $badActor );
174 $this->assertSame( $reason, $block->mReason
);
175 $this->assertSame( $expiry, $block->getExpiry() );
179 * @covers ::processForm()
181 public function testProcessFormExisting() {
182 $this->setMwGlobals( [
183 'wgEnablePartialBlocks' => false,
185 $badActor = $this->getTestUser()->getUser();
186 $sysop = $this->getTestSysop()->getUser();
187 $context = RequestContext
::getMain();
189 // Create a block that will be updated.
190 $block = new \
Block( [
191 'address' => $badActor->getName(),
192 'user' => $badActor->getId(),
193 'by' => $sysop->getId(),
194 'expiry' => 'infinity',
196 'enableAutoblock' => false,
200 $page = $this->newSpecialPage();
202 $expiry = 'infinity';
204 'Target' => (string)$badActor,
205 'Expiry' => 'infinity',
210 'CreateAccount' => '0',
211 'DisableUTEdit' => '0',
212 'DisableEmail' => '0',
218 $result = $page->processForm( $data, $context );
220 $this->assertTrue( $result );
222 $block = Block
::newFromTarget( $badActor );
223 $this->assertSame( $reason, $block->mReason
);
224 $this->assertSame( $expiry, $block->getExpiry() );
225 $this->assertSame( '1', $block->isAutoblocking() );
229 * @covers ::processForm()
231 public function testProcessFormRestictions() {
232 $this->setMwGlobals( [
233 'wgEnablePartialBlocks' => true,
235 $badActor = $this->getTestUser()->getUser();
236 $context = RequestContext
::getMain();
238 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
239 $pageMars = $this->getExistingTestPage( 'Mars' );
242 $pageSaturn->getTitle()->getText(),
243 $pageMars->getTitle()->getText(),
246 $page = $this->newSpecialPage();
248 $expiry = 'infinity';
250 'Target' => (string)$badActor,
251 'Expiry' => 'infinity',
256 'CreateAccount' => '0',
257 'DisableUTEdit' => '0',
258 'DisableEmail' => '0',
263 'EditingRestriction' => 'partial',
264 'PageRestrictions' => implode( "\n", $titles ),
266 $result = $page->processForm( $data, $context );
268 $this->assertTrue( $result );
270 $block = Block
::newFromTarget( $badActor );
271 $this->assertSame( $reason, $block->mReason
);
272 $this->assertSame( $expiry, $block->getExpiry() );
273 $this->assertCount( 2, $block->getRestrictions() );
274 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
275 new PageRestriction( $block->getId(), $pageMars->getId() ),
276 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
281 * @covers ::processForm()
283 public function testProcessFormRestrictionsChange() {
284 $this->setMwGlobals( [
285 'wgEnablePartialBlocks' => true,
287 $badActor = $this->getTestUser()->getUser();
288 $context = RequestContext
::getMain();
290 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
291 $pageMars = $this->getExistingTestPage( 'Mars' );
294 $pageSaturn->getTitle()->getText(),
295 $pageMars->getTitle()->getText(),
298 // Create a partial block.
299 $page = $this->newSpecialPage();
301 $expiry = 'infinity';
303 'Target' => (string)$badActor,
304 'Expiry' => 'infinity',
309 'CreateAccount' => '0',
310 'DisableUTEdit' => '0',
311 'DisableEmail' => '0',
316 'EditingRestriction' => 'partial',
317 'PageRestrictions' => implode( "\n", $titles ),
319 $result = $page->processForm( $data, $context );
321 $this->assertTrue( $result );
323 $block = Block
::newFromTarget( $badActor );
324 $this->assertSame( $reason, $block->mReason
);
325 $this->assertSame( $expiry, $block->getExpiry() );
326 $this->assertFalse( $block->isSitewide() );
327 $this->assertCount( 2, $block->getRestrictions() );
328 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
329 new PageRestriction( $block->getId(), $pageMars->getId() ),
330 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
333 // Remove a page from the partial block.
334 $data['PageRestrictions'] = $pageMars->getTitle()->getText();
335 $result = $page->processForm( $data, $context );
337 $this->assertTrue( $result );
339 $block = Block
::newFromTarget( $badActor );
340 $this->assertSame( $reason, $block->mReason
);
341 $this->assertSame( $expiry, $block->getExpiry() );
342 $this->assertFalse( $block->isSitewide() );
343 $this->assertCount( 1, $block->getRestrictions() );
344 $this->assertTrue( BlockRestriction
::equals( $block->getRestrictions(), [
345 new PageRestriction( $block->getId(), $pageMars->getId() ),
348 // Remove the last page from the block.
349 $data['PageRestrictions'] = '';
350 $result = $page->processForm( $data, $context );
352 $this->assertTrue( $result );
354 $block = Block
::newFromTarget( $badActor );
355 $this->assertSame( $reason, $block->mReason
);
356 $this->assertSame( $expiry, $block->getExpiry() );
357 $this->assertFalse( $block->isSitewide() );
358 $this->assertCount( 0, $block->getRestrictions() );
360 // Change to sitewide.
361 $data['EditingRestriction'] = 'sitewide';
362 $result = $page->processForm( $data, $context );
364 $this->assertTrue( $result );
366 $block = Block
::newFromTarget( $badActor );
367 $this->assertSame( $reason, $block->mReason
);
368 $this->assertSame( $expiry, $block->getExpiry() );
369 $this->assertTrue( $block->isSitewide() );
370 $this->assertCount( 0, $block->getRestrictions() );
372 // Ensure that there are no restrictions where the blockId is 0.
373 $count = $this->db
->selectRowCount(
374 'ipblocks_restrictions',
376 [ 'ir_ipb_id' => 0 ],
379 $this->assertSame( 0, $count );
383 * @dataProvider provideCheckUnblockSelf
384 * @covers ::checkUnblockSelf
386 public function testCheckUnblockSelf(
394 $this->setGroupPermissions( 'sysop', 'unblockself', true );
395 $this->setGroupPermissions( 'user', 'block', true );
396 // Getting errors about creating users in db in provider.
397 // Need to use mutable to ensure different named testusers.
399 'u1' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
400 'u2' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
401 'u3' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
402 'u4' => TestUserRegistry
::getMutableTestUser( __CLASS__
, 'sysop' )->getUser(),
403 'nonsysop' => $this->getTestUser()->getUser()
405 foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
406 $
$var = $users[$
$var];
409 $block = new \
Block( [
410 'address' => $blockedUser->getName(),
411 'user' => $blockedUser->getId(),
412 'by' => $blockPerformer->getId(),
413 'expiry' => 'infinity',
415 'enableAutoblock' => true,
421 SpecialBlock
::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
427 public function provideCheckUnblockSelf() {
428 // 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
430 [ 'u1', 'u2', 'u3', 'u4', true, 'Unrelated users' ],
431 [ 'u1', 'u2', 'u1', 'u4', 'ipbblocked', 'Block unrelated while blocked' ],
432 [ 'u1', 'u2', 'u1', 'u1', true, 'Has unblockself' ],
433 [ 'nonsysop', 'u2', 'nonsysop', 'nonsysop', 'ipbnounblockself', 'no unblockself' ],
434 [ 'nonsysop', 'nonsysop', 'nonsysop', 'nonsysop', true, 'no unblockself but can de-selfblock' ],
435 [ 'u1', 'u2', 'u1', 'u2', true, 'Can block user who blocked' ],
439 protected function insertBlock() {
440 $badActor = $this->getTestUser()->getUser();
441 $sysop = $this->getTestSysop()->getUser();
443 $block = new \
Block( [
444 'address' => $badActor->getName(),
445 'user' => $badActor->getId(),
446 'by' => $sysop->getId(),
447 'expiry' => 'infinity',
449 'enableAutoblock' => true,
457 protected function resetTables() {
458 $this->db
->delete( 'ipblocks', '*', __METHOD__
);
459 $this->db
->delete( 'ipblocks_restrictions', '*', __METHOD__
);