Merge "Chinese Conversion Table Update 2018-4"
[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 Wikimedia\TestingAccessWrapper;
6
7 /**
8 * @group Blocking
9 * @group Database
10 * @coversDefaultClass SpecialBlock
11 */
12 class SpecialBlockTest extends SpecialPageTestBase {
13 /**
14 * {@inheritdoc}
15 */
16 protected function newSpecialPage() {
17 return new SpecialBlock();
18 }
19
20 public function tearDown() {
21 parent::tearDown();
22 $this->resetTables();
23 }
24
25 /**
26 * @covers ::getFormFields()
27 */
28 public function testGetFormFields() {
29 $this->setMwGlobals( [
30 'wgEnablePartialBlocks' => false,
31 ] );
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 );
45
46 $this->assertArrayNotHasKey( 'EditingRestriction', $fields );
47 $this->assertArrayNotHasKey( 'PageRestrictions', $fields );
48 }
49
50 /**
51 * @covers ::getFormFields()
52 */
53 public function testGetFormFieldsPartialBlocks() {
54 $this->setMwGlobals( [
55 'wgEnablePartialBlocks' => true,
56 ] );
57 $page = $this->newSpecialPage();
58 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
59 $fields = $wrappedPage->getFormFields();
60
61 $this->assertArrayHasKey( 'EditingRestriction', $fields );
62 $this->assertArrayHasKey( 'PageRestrictions', $fields );
63 }
64
65 /**
66 * @covers ::maybeAlterFormDefaults()
67 */
68 public function testMaybeAlterFormDefaults() {
69 $this->setMwGlobals( [
70 'wgEnablePartialBlocks' => false,
71 ] );
72
73 $block = $this->insertBlock();
74
75 // Refresh the block from the database.
76 $block = Block::newFromTarget( $block->getTarget() );
77
78 $page = $this->newSpecialPage();
79
80 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
81 $wrappedPage->target = $block->getTarget();
82 $fields = $wrappedPage->getFormFields();
83
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'] );
91 }
92
93 /**
94 * @covers ::maybeAlterFormDefaults()
95 */
96 public function testMaybeAlterFormDefaultsPartial() {
97 $this->setMwGlobals( [
98 'wgEnablePartialBlocks' => true,
99 ] );
100
101 $badActor = $this->getTestUser()->getUser();
102 $sysop = $this->getTestSysop()->getUser();
103 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
104 $pageMars = $this->getExistingTestPage( 'Mars' );
105
106 $block = new \Block( [
107 'address' => $badActor->getName(),
108 'user' => $badActor->getId(),
109 'by' => $sysop->getId(),
110 'expiry' => 'infinity',
111 'sitewide' => 0,
112 'enableAutoblock' => true,
113 ] );
114
115 $block->setRestrictions( [
116 new PageRestriction( 0, $pageSaturn->getId() ),
117 new PageRestriction( 0, $pageMars->getId() ),
118 ] );
119
120 $block->insert();
121
122 // Refresh the block from the database.
123 $block = Block::newFromTarget( $block->getTarget() );
124
125 $page = $this->newSpecialPage();
126
127 $wrappedPage = TestingAccessWrapper::newFromObject( $page );
128 $wrappedPage->target = $block->getTarget();
129 $fields = $wrappedPage->getFormFields();
130
131 $titles = [
132 $pageMars->getTitle()->getPrefixedText(),
133 $pageSaturn->getTitle()->getPrefixedText(),
134 ];
135
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'] );
139 }
140
141 /**
142 * @covers ::processForm()
143 */
144 public function testProcessForm() {
145 $this->setMwGlobals( [
146 'wgEnablePartialBlocks' => false,
147 ] );
148 $badActor = $this->getTestUser()->getUser();
149 $context = RequestContext::getMain();
150
151 $page = $this->newSpecialPage();
152 $reason = 'test';
153 $expiry = 'infinity';
154 $data = [
155 'Target' => (string)$badActor,
156 'Expiry' => 'infinity',
157 'Reason' => [
158 $reason,
159 ],
160 'Confirm' => '1',
161 'CreateAccount' => '0',
162 'DisableUTEdit' => '0',
163 'DisableEmail' => '0',
164 'HardBlock' => '0',
165 'AutoBlock' => '1',
166 'HideUser' => '0',
167 'Watch' => '0',
168 ];
169 $result = $page->processForm( $data, $context );
170
171 $this->assertTrue( $result );
172
173 $block = Block::newFromTarget( $badActor );
174 $this->assertSame( $reason, $block->mReason );
175 $this->assertSame( $expiry, $block->getExpiry() );
176 }
177
178 /**
179 * @covers ::processForm()
180 */
181 public function testProcessFormExisting() {
182 $this->setMwGlobals( [
183 'wgEnablePartialBlocks' => false,
184 ] );
185 $badActor = $this->getTestUser()->getUser();
186 $sysop = $this->getTestSysop()->getUser();
187 $context = RequestContext::getMain();
188
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',
195 'sitewide' => 0,
196 'enableAutoblock' => false,
197 ] );
198 $block->insert();
199
200 $page = $this->newSpecialPage();
201 $reason = 'test';
202 $expiry = 'infinity';
203 $data = [
204 'Target' => (string)$badActor,
205 'Expiry' => 'infinity',
206 'Reason' => [
207 $reason,
208 ],
209 'Confirm' => '1',
210 'CreateAccount' => '0',
211 'DisableUTEdit' => '0',
212 'DisableEmail' => '0',
213 'HardBlock' => '0',
214 'AutoBlock' => '1',
215 'HideUser' => '0',
216 'Watch' => '0',
217 ];
218 $result = $page->processForm( $data, $context );
219
220 $this->assertTrue( $result );
221
222 $block = Block::newFromTarget( $badActor );
223 $this->assertSame( $reason, $block->mReason );
224 $this->assertSame( $expiry, $block->getExpiry() );
225 $this->assertSame( '1', $block->isAutoblocking() );
226 }
227
228 /**
229 * @covers ::processForm()
230 */
231 public function testProcessFormRestictions() {
232 $this->setMwGlobals( [
233 'wgEnablePartialBlocks' => true,
234 ] );
235 $badActor = $this->getTestUser()->getUser();
236 $context = RequestContext::getMain();
237
238 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
239 $pageMars = $this->getExistingTestPage( 'Mars' );
240
241 $titles = [
242 $pageSaturn->getTitle()->getText(),
243 $pageMars->getTitle()->getText(),
244 ];
245
246 $page = $this->newSpecialPage();
247 $reason = 'test';
248 $expiry = 'infinity';
249 $data = [
250 'Target' => (string)$badActor,
251 'Expiry' => 'infinity',
252 'Reason' => [
253 $reason,
254 ],
255 'Confirm' => '1',
256 'CreateAccount' => '0',
257 'DisableUTEdit' => '0',
258 'DisableEmail' => '0',
259 'HardBlock' => '0',
260 'AutoBlock' => '1',
261 'HideUser' => '0',
262 'Watch' => '0',
263 'EditingRestriction' => 'partial',
264 'PageRestrictions' => implode( "\n", $titles ),
265 ];
266 $result = $page->processForm( $data, $context );
267
268 $this->assertTrue( $result );
269
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() ),
277 ] ) );
278 }
279
280 /**
281 * @covers ::processForm()
282 */
283 public function testProcessFormRestrictionsChange() {
284 $this->setMwGlobals( [
285 'wgEnablePartialBlocks' => true,
286 ] );
287 $badActor = $this->getTestUser()->getUser();
288 $context = RequestContext::getMain();
289
290 $pageSaturn = $this->getExistingTestPage( 'Saturn' );
291 $pageMars = $this->getExistingTestPage( 'Mars' );
292
293 $titles = [
294 $pageSaturn->getTitle()->getText(),
295 $pageMars->getTitle()->getText(),
296 ];
297
298 // Create a partial block.
299 $page = $this->newSpecialPage();
300 $reason = 'test';
301 $expiry = 'infinity';
302 $data = [
303 'Target' => (string)$badActor,
304 'Expiry' => 'infinity',
305 'Reason' => [
306 $reason,
307 ],
308 'Confirm' => '1',
309 'CreateAccount' => '0',
310 'DisableUTEdit' => '0',
311 'DisableEmail' => '0',
312 'HardBlock' => '0',
313 'AutoBlock' => '1',
314 'HideUser' => '0',
315 'Watch' => '0',
316 'EditingRestriction' => 'partial',
317 'PageRestrictions' => implode( "\n", $titles ),
318 ];
319 $result = $page->processForm( $data, $context );
320
321 $this->assertTrue( $result );
322
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() ),
331 ] ) );
332
333 // Remove a page from the partial block.
334 $data['PageRestrictions'] = $pageMars->getTitle()->getText();
335 $result = $page->processForm( $data, $context );
336
337 $this->assertTrue( $result );
338
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() ),
346 ] ) );
347
348 // Remove the last page from the block.
349 $data['PageRestrictions'] = '';
350 $result = $page->processForm( $data, $context );
351
352 $this->assertTrue( $result );
353
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() );
359
360 // Change to sitewide.
361 $data['EditingRestriction'] = 'sitewide';
362 $result = $page->processForm( $data, $context );
363
364 $this->assertTrue( $result );
365
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() );
371
372 // Ensure that there are no restrictions where the blockId is 0.
373 $count = $this->db->selectRowCount(
374 'ipblocks_restrictions',
375 '*',
376 [ 'ir_ipb_id' => 0 ],
377 __METHOD__
378 );
379 $this->assertSame( 0, $count );
380 }
381
382 /**
383 * @dataProvider provideCheckUnblockSelf
384 * @covers ::checkUnblockSelf
385 */
386 public function testCheckUnblockSelf(
387 $blockedUser,
388 $blockPerformer,
389 $adjustPerformer,
390 $adjustTarget,
391 $expectedResult,
392 $reason
393 ) {
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.
398 $users = [
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()
404 ];
405 foreach ( [ 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget' ] as $var ) {
406 $$var = $users[$$var];
407 }
408
409 $block = new \Block( [
410 'address' => $blockedUser->getName(),
411 'user' => $blockedUser->getId(),
412 'by' => $blockPerformer->getId(),
413 'expiry' => 'infinity',
414 'sitewide' => 1,
415 'enableAutoblock' => true,
416 ] );
417
418 $block->insert();
419
420 $this->assertSame(
421 SpecialBlock::checkUnblockSelf( $adjustTarget, $adjustPerformer ),
422 $expectedResult,
423 $reason
424 );
425 }
426
427 public function provideCheckUnblockSelf() {
428 // 'blockedUser', 'blockPerformer', 'adjustPerformer', 'adjustTarget'
429 return [
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' ],
436 ];
437 }
438
439 protected function insertBlock() {
440 $badActor = $this->getTestUser()->getUser();
441 $sysop = $this->getTestSysop()->getUser();
442
443 $block = new \Block( [
444 'address' => $badActor->getName(),
445 'user' => $badActor->getId(),
446 'by' => $sysop->getId(),
447 'expiry' => 'infinity',
448 'sitewide' => 1,
449 'enableAutoblock' => true,
450 ] );
451
452 $block->insert();
453
454 return $block;
455 }
456
457 protected function resetTables() {
458 $this->db->delete( 'ipblocks', '*', __METHOD__ );
459 $this->db->delete( 'ipblocks_restrictions', '*', __METHOD__ );
460 }
461 }