Merge "Document Uri.js constructor and methods throwing Errors"
[lhc/web/wiklou.git] / tests / phpunit / includes / specials / SpecialBlockTest.php
1 <?php
2
3 use MediaWiki\Block\BlockRestriction;
4 use MediaWiki\Block\Restriction\PageRestriction;
5 use MediaWiki\Block\Restriction\NamespaceRestriction;
6 use Wikimedia\TestingAccessWrapper;
7
8 /**
9 * @group Blocking
10 * @group Database
11 * @coversDefaultClass SpecialBlock
12 */
13 class SpecialBlockTest extends SpecialPageTestBase {
14 /**
15 * {@inheritdoc}
16 */
17 protected function newSpecialPage() {
18 return new SpecialBlock();
19 }
20
21 public function tearDown() {
22 parent::tearDown();
23 $this->resetTables();
24 }
25
26 /**
27 * @covers ::getFormFields()
28 */
29 public function testGetFormFields() {
30 $this->setMwGlobals( [
31 'wgEnablePartialBlocks' => false,
32 ] );
33 $page = $this->newSpecialPage();
34 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
35 $fields = $wrappedPage->getFormFields();
36 $this->assertInternalType( 'array', $fields );
37 $this->assertArrayHasKey( 'Target', $fields );
38 $this->assertArrayHasKey( 'Expiry', $fields );
39 $this->assertArrayHasKey( 'Reason', $fields );
40 $this->assertArrayHasKey( 'CreateAccount', $fields );
41 $this->assertArrayHasKey( 'DisableUTEdit', $fields );
42 $this->assertArrayHasKey( 'AutoBlock', $fields );
43 $this->assertArrayHasKey( 'HardBlock', $fields );
44 $this->assertArrayHasKey( 'PreviousTarget', $fields );
45 $this->assertArrayHasKey( 'Confirm', $fields );
46
47 $this->assertArrayNotHasKey( 'EditingRestriction', $fields );
48 $this->assertArrayNotHasKey( 'PageRestrictions', $fields );
49 $this->assertArrayNotHasKey( 'NamespaceRestrictions', $fields );
50 }
51
52 /**
53 * @covers ::getFormFields()
54 */
55 public function testGetFormFieldsPartialBlocks() {
56 $this->setMwGlobals( [
57 'wgEnablePartialBlocks' => true,
58 ] );
59 $page = $this->newSpecialPage();
60 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
61 $fields = $wrappedPage->getFormFields();
62
63 $this->assertArrayHasKey( 'EditingRestriction', $fields );
64 $this->assertArrayHasKey( 'PageRestrictions', $fields );
65 $this->assertArrayHasKey( 'NamespaceRestrictions', $fields );
66 }
67
68 /**
69 * @covers ::maybeAlterFormDefaults()
70 */
71 public function testMaybeAlterFormDefaults() {
72 $this->setMwGlobals( [
73 'wgEnablePartialBlocks' => false,
74 ] );
75
76 $block = $this->insertBlock();
77
78 // Refresh the block from the database.
79 $block = Block::newFromTarget( $block->getTarget() );
80
81 $page = $this->newSpecialPage();
82
83 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
84 $wrappedPage->target = $block->getTarget();
85 $fields = $wrappedPage->getFormFields();
86
87 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
88 $this->assertSame( $block->isHardblock(), $fields['HardBlock']['default'] );
89 $this->assertSame( $block->prevents( 'createaccount' ), $fields['CreateAccount']['default'] );
90 $this->assertSame( $block->isAutoblocking(), $fields['AutoBlock']['default'] );
91 $this->assertSame( $block->prevents( 'editownusertalk' ), $fields['DisableUTEdit']['default'] );
92 $this->assertSame( $block->mReason, $fields['Reason']['default'] );
93 $this->assertSame( 'infinite', $fields['Expiry']['default'] );
94 }
95
96 /**
97 * @covers ::maybeAlterFormDefaults()
98 */
99 public function testMaybeAlterFormDefaultsPartial() {
100 $this->setMwGlobals( [
101 'wgEnablePartialBlocks' => true,
102 ] );
103
104 $badActor = $this->getTestUser()->getUser();
105 $sysop = $this->getTestSysop()->getUser();
106 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
107 $pageMars = $this->getExistingTestPage( 'Mars' );
108
109 $block = new \Block( [
110 'address' => $badActor->getName(),
111 'user' => $badActor->getId(),
112 'by' => $sysop->getId(),
113 'expiry' => 'infinity',
114 'sitewide' => 0,
115 'enableAutoblock' => true,
116 ] );
117
118 $block->setRestrictions( [
119 new PageRestriction( 0, $pageSaturn->getId() ),
120 new PageRestriction( 0, $pageMars->getId() ),
121 new NamespaceRestriction( 0, NS_TALK ),
122 ] );
123
124 $block->insert();
125
126 // Refresh the block from the database.
127 $block = Block::newFromTarget( $block->getTarget() );
128
129 $page = $this->newSpecialPage();
130
131 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
132 $wrappedPage->target = $block->getTarget();
133 $fields = $wrappedPage->getFormFields();
134
135 $titles = [
136 $pageMars->getTitle()->getPrefixedText(),
137 $pageSaturn->getTitle()->getPrefixedText(),
138 ];
139
140 $this->assertSame( (string)$block->getTarget(), $fields['Target']['default'] );
141 $this->assertSame( 'partial', $fields['EditingRestriction']['default'] );
142 $this->assertSame( implode( "\n", $titles ), $fields['PageRestrictions']['default'] );
143 }
144
145 /**
146 * @covers ::processForm()
147 */
148 public function testProcessForm() {
149 $this->setMwGlobals( [
150 'wgEnablePartialBlocks' => false,
151 ] );
152 $badActor = $this->getTestUser()->getUser();
153 $context = RequestContext::getMain();
154
155 $page = $this->newSpecialPage();
156 $reason = 'test';
157 $expiry = 'infinity';
158 $data = [
159 'Target' => (string)$badActor,
160 'Expiry' => 'infinity',
161 'Reason' => [
162 $reason,
163 ],
164 'Confirm' => '1',
165 'CreateAccount' => '0',
166 'DisableUTEdit' => '0',
167 'DisableEmail' => '0',
168 'HardBlock' => '0',
169 'AutoBlock' => '1',
170 'HideUser' => '0',
171 'Watch' => '0',
172 ];
173 $result = $page->processForm( $data, $context );
174
175 $this->assertTrue( $result );
176
177 $block = Block::newFromTarget( $badActor );
178 $this->assertSame( $reason, $block->mReason );
179 $this->assertSame( $expiry, $block->getExpiry() );
180 }
181
182 /**
183 * @covers ::processForm()
184 */
185 public function testProcessFormExisting() {
186 $this->setMwGlobals( [
187 'wgEnablePartialBlocks' => false,
188 ] );
189 $badActor = $this->getTestUser()->getUser();
190 $sysop = $this->getTestSysop()->getUser();
191 $context = RequestContext::getMain();
192
193 // Create a block that will be updated.
194 $block = new \Block( [
195 'address' => $badActor->getName(),
196 'user' => $badActor->getId(),
197 'by' => $sysop->getId(),
198 'expiry' => 'infinity',
199 'sitewide' => 0,
200 'enableAutoblock' => false,
201 ] );
202 $block->insert();
203
204 $page = $this->newSpecialPage();
205 $reason = 'test';
206 $expiry = 'infinity';
207 $data = [
208 'Target' => (string)$badActor,
209 'Expiry' => 'infinity',
210 'Reason' => [
211 $reason,
212 ],
213 'Confirm' => '1',
214 'CreateAccount' => '0',
215 'DisableUTEdit' => '0',
216 'DisableEmail' => '0',
217 'HardBlock' => '0',
218 'AutoBlock' => '1',
219 'HideUser' => '0',
220 'Watch' => '0',
221 ];
222 $result = $page->processForm( $data, $context );
223
224 $this->assertTrue( $result );
225
226 $block = Block::newFromTarget( $badActor );
227 $this->assertSame( $reason, $block->mReason );
228 $this->assertSame( $expiry, $block->getExpiry() );
229 $this->assertSame( '1', $block->isAutoblocking() );
230 }
231
232 /**
233 * @covers ::processForm()
234 */
235 public function testProcessFormRestrictions() {
236 $this->setMwGlobals( [
237 'wgEnablePartialBlocks' => true,
238 ] );
239 $badActor = $this->getTestUser()->getUser();
240 $context = RequestContext::getMain();
241
242 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
243 $pageMars = $this->getExistingTestPage( 'Mars' );
244
245 $titles = [
246 $pageSaturn->getTitle()->getText(),
247 $pageMars->getTitle()->getText(),
248 ];
249
250 $page = $this->newSpecialPage();
251 $reason = 'test';
252 $expiry = 'infinity';
253 $data = [
254 'Target' => (string)$badActor,
255 'Expiry' => 'infinity',
256 'Reason' => [
257 $reason,
258 ],
259 'Confirm' => '1',
260 'CreateAccount' => '0',
261 'DisableUTEdit' => '0',
262 'DisableEmail' => '0',
263 'HardBlock' => '0',
264 'AutoBlock' => '1',
265 'HideUser' => '0',
266 'Watch' => '0',
267 'EditingRestriction' => 'partial',
268 'PageRestrictions' => implode( "\n", $titles ),
269 'NamespaceRestrictions' => '',
270 ];
271 $result = $page->processForm( $data, $context );
272
273 $this->assertTrue( $result );
274
275 $block = Block::newFromTarget( $badActor );
276 $this->assertSame( $reason, $block->mReason );
277 $this->assertSame( $expiry, $block->getExpiry() );
278 $this->assertCount( 2, $block->getRestrictions() );
279 $this->assertTrue( BlockRestriction::equals( $block->getRestrictions(), [
280 new PageRestriction( $block->getId(), $pageMars->getId() ),
281 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
282 ] ) );
283 }
284
285 /**
286 * @covers ::processForm()
287 */
288 public function testProcessFormRestrictionsChange() {
289 $this->setMwGlobals( [
290 'wgEnablePartialBlocks' => true,
291 ] );
292 $badActor = $this->getTestUser()->getUser();
293 $context = RequestContext::getMain();
294
295 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
296 $pageMars = $this->getExistingTestPage( 'Mars' );
297
298 $titles = [
299 $pageSaturn->getTitle()->getText(),
300 $pageMars->getTitle()->getText(),
301 ];
302
303 // Create a partial block.
304 $page = $this->newSpecialPage();
305 $reason = 'test';
306 $expiry = 'infinity';
307 $data = [
308 'Target' => (string)$badActor,
309 'Expiry' => 'infinity',
310 'Reason' => [
311 $reason,
312 ],
313 'Confirm' => '1',
314 'CreateAccount' => '0',
315 'DisableUTEdit' => '0',
316 'DisableEmail' => '0',
317 'HardBlock' => '0',
318 'AutoBlock' => '1',
319 'HideUser' => '0',
320 'Watch' => '0',
321 'EditingRestriction' => 'partial',
322 'PageRestrictions' => implode( "\n", $titles ),
323 'NamespaceRestrictions' => '',
324 ];
325 $result = $page->processForm( $data, $context );
326
327 $this->assertTrue( $result );
328
329 $block = Block::newFromTarget( $badActor );
330 $this->assertSame( $reason, $block->mReason );
331 $this->assertSame( $expiry, $block->getExpiry() );
332 $this->assertFalse( $block->isSitewide() );
333 $this->assertCount( 2, $block->getRestrictions() );
334 $this->assertTrue( BlockRestriction::equals( $block->getRestrictions(), [
335 new PageRestriction( $block->getId(), $pageMars->getId() ),
336 new PageRestriction( $block->getId(), $pageSaturn->getId() ),
337 ] ) );
338
339 // Remove a page from the partial block.
340 $data['PageRestrictions'] = $pageMars->getTitle()->getText();
341 $result = $page->processForm( $data, $context );
342
343 $this->assertTrue( $result );
344
345 $block = Block::newFromTarget( $badActor );
346 $this->assertSame( $reason, $block->mReason );
347 $this->assertSame( $expiry, $block->getExpiry() );
348 $this->assertFalse( $block->isSitewide() );
349 $this->assertCount( 1, $block->getRestrictions() );
350 $this->assertTrue( BlockRestriction::equals( $block->getRestrictions(), [
351 new PageRestriction( $block->getId(), $pageMars->getId() ),
352 ] ) );
353
354 // Remove the last page from the block.
355 $data['PageRestrictions'] = '';
356 $result = $page->processForm( $data, $context );
357
358 $this->assertTrue( $result );
359
360 $block = Block::newFromTarget( $badActor );
361 $this->assertSame( $reason, $block->mReason );
362 $this->assertSame( $expiry, $block->getExpiry() );
363 $this->assertFalse( $block->isSitewide() );
364 $this->assertCount( 0, $block->getRestrictions() );
365
366 // Change to sitewide.
367 $data['EditingRestriction'] = 'sitewide';
368 $result = $page->processForm( $data, $context );
369
370 $this->assertTrue( $result );
371
372 $block = Block::newFromTarget( $badActor );
373 $this->assertSame( $reason, $block->mReason );
374 $this->assertSame( $expiry, $block->getExpiry() );
375 $this->assertTrue( $block->isSitewide() );
376 $this->assertCount( 0, $block->getRestrictions() );
377
378 // Ensure that there are no restrictions where the blockId is 0.
379 $count = $this->db->selectRowCount(
380 'ipblocks_restrictions',
381 '*',
382 [ 'ir_ipb_id' => 0 ],
383 __METHOD__
384 );
385 $this->assertSame( 0, $count );
386 }
387
388 /**
389 * @dataProvider provideCheckUnblockSelf
390 * @covers ::checkUnblockSelf
391 */
392 public function testCheckUnblockSelf(
393 $blockedUser,
394 $blockPerformer,
395 $adjustPerformer,
396 $adjustTarget,
397 $expectedResult,
398 $reason
399 ) {
400 $this->setGroupPermissions( 'sysop', 'unblockself', true );
401 $this->setGroupPermissions( 'user', 'block', true );
402 // Getting errors about creating users in db in provider.
403 // Need to use mutable to ensure different named testusers.
404 $users = [
405 'u1' => TestUserRegistry::getMutableTestUser( __CLASS__, 'sysop' )->getUser(),
406 'u2' => TestUserRegistry::getMutableTestUser( __CLASS__, 'sysop' )->getUser(),
407 'u3' => TestUserRegistry::getMutableTestUser( __CLASS__, 'sysop' )->getUser(),
408 'u4' => TestUserRegistry::getMutableTestUser( __CLASS__, 'sysop' )->getUser(),
409 'nonsysop' => $this->getTestUser()->getUser()
410 ];
411 foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
412 $$var = $users[$$var];
413 }
414
415 $block = new \Block( [
416 'address' => $blockedUser->getName(),
417 'user' => $blockedUser->getId(),
418 'by' => $blockPerformer->getId(),
419 'expiry' => 'infinity',
420 'sitewide' => 1,
421 'enableAutoblock' => true,
422 ] );
423
424 $block->insert();
425
426 $this->assertSame(
427 SpecialBlock::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
428 $expectedResult,
429 $reason
430 );
431 }
432
433 public function provideCheckUnblockSelf() {
434 // 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
435 return [
436 [ 'u1', 'u2', 'u3', 'u4', true, 'Unrelated users' ],
437 [ 'u1', 'u2', 'u1', 'u4', 'ipbblocked', 'Block unrelated while blocked' ],
438 [ 'u1', 'u2', 'u1', 'u1', true, 'Has unblockself' ],
439 [ 'nonsysop', 'u2', 'nonsysop', 'nonsysop', 'ipbnounblockself', 'no unblockself' ],
440 [ 'nonsysop', 'nonsysop', 'nonsysop', 'nonsysop', true, 'no unblockself but can de-selfblock' ],
441 [ 'u1', 'u2', 'u1', 'u2', true, 'Can block user who blocked' ],
442 ];
443 }
444
445 protected function insertBlock() {
446 $badActor = $this->getTestUser()->getUser();
447 $sysop = $this->getTestSysop()->getUser();
448
449 $block = new \Block( [
450 'address' => $badActor->getName(),
451 'user' => $badActor->getId(),
452 'by' => $sysop->getId(),
453 'expiry' => 'infinity',
454 'sitewide' => 1,
455 'enableAutoblock' => true,
456 ] );
457
458 $block->insert();
459
460 return $block;
461 }
462
463 protected function resetTables() {
464 $this->db->delete( 'ipblocks', '*', __METHOD__ );
465 $this->db->delete( 'ipblocks_restrictions', '*', __METHOD__ );
466 }
467 }