Merge "Drop cache interwiki"
[mediawiki.git] / tests / phpunit / includes / logging / ProtectLogFormatterTest.php
blobecdb77583f7b9188170013a36c806d43e855dc74
1 <?php
3 use MediaWiki\Cache\LinkCache;
4 use MediaWiki\Context\RequestContext;
5 use MediaWiki\Linker\LinkRendererFactory;
6 use MediaWiki\Tests\Unit\Permissions\MockAuthorityTrait;
7 use MediaWiki\Title\Title;
8 use MediaWiki\Title\TitleFactory;
9 use MediaWiki\User\UserIdentityValue;
10 use Wikimedia\Rdbms\IDatabase;
11 use Wikimedia\Rdbms\LBFactory;
13 /**
14 * @covers \ProtectLogFormatter
16 class ProtectLogFormatterTest extends LogFormatterTestCase {
18 use MockAuthorityTrait;
20 protected function setUp(): void {
21 parent::setUp();
23 $db = $this->createNoOpMock( IDatabase::class, [ 'getInfinity' ] );
24 $db->method( 'getInfinity' )->willReturn( 'infinity' );
25 $lbFactory = $this->createMock( LBFactory::class );
26 $lbFactory->method( 'getReplicaDatabase' )->willReturn( $db );
27 $this->setService( 'DBLoadBalancerFactory', $lbFactory );
30 /**
31 * Provide different rows from the logging table to test
32 * for backward compatibility.
33 * Do not change the existing data, just add a new database row
35 public static function provideProtectLogDatabaseRows() {
36 return [
37 // Current format
40 'type' => 'protect',
41 'action' => 'protect',
42 'comment' => 'protect comment',
43 'namespace' => NS_MAIN,
44 'title' => 'ProtectPage',
45 'params' => [
46 '4::description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
47 '5:bool:cascade' => false,
48 'details' => [
50 'type' => 'edit',
51 'level' => 'sysop',
52 'expiry' => 'infinity',
53 'cascade' => false,
56 'type' => 'move',
57 'level' => 'sysop',
58 'expiry' => 'infinity',
59 'cascade' => false,
65 'text' => 'User protected ProtectPage [Edit=Allow only administrators] ' .
66 '(indefinite) [Move=Allow only administrators] (indefinite)',
67 'api' => [
68 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
69 'cascade' => false,
70 'details' => [
72 'type' => 'edit',
73 'level' => 'sysop',
74 'expiry' => 'infinite',
75 'cascade' => false,
78 'type' => 'move',
79 'level' => 'sysop',
80 'expiry' => 'infinite',
81 'cascade' => false,
88 // Current format with cascade
91 'type' => 'protect',
92 'action' => 'protect',
93 'comment' => 'protect comment',
94 'namespace' => NS_MAIN,
95 'title' => 'ProtectPage',
96 'params' => [
97 '4::description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
98 '5:bool:cascade' => true,
99 'details' => [
101 'type' => 'edit',
102 'level' => 'sysop',
103 'expiry' => 'infinity',
104 'cascade' => true,
107 'type' => 'move',
108 'level' => 'sysop',
109 'expiry' => 'infinity',
110 'cascade' => false,
116 'text' => 'User protected ProtectPage [Edit=Allow only administrators] ' .
117 '(indefinite) [Move=Allow only administrators] (indefinite) [cascading]',
118 'api' => [
119 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
120 'cascade' => true,
121 'details' => [
123 'type' => 'edit',
124 'level' => 'sysop',
125 'expiry' => 'infinite',
126 'cascade' => true,
129 'type' => 'move',
130 'level' => 'sysop',
131 'expiry' => 'infinite',
132 'cascade' => false,
139 // Legacy format
142 'type' => 'protect',
143 'action' => 'protect',
144 'comment' => 'protect comment',
145 'namespace' => NS_MAIN,
146 'title' => 'ProtectPage',
147 'params' => [
148 '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
153 'legacy' => true,
154 'text' => 'User protected ProtectPage [edit=sysop] (indefinite)[move=sysop] (indefinite)',
155 'api' => [
156 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
157 'cascade' => false,
162 // Legacy format with cascade
165 'type' => 'protect',
166 'action' => 'protect',
167 'comment' => 'protect comment',
168 'namespace' => NS_MAIN,
169 'title' => 'ProtectPage',
170 'params' => [
171 '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
172 'cascade',
176 'legacy' => true,
177 'text' => 'User protected ProtectPage [edit=sysop] ' .
178 '(indefinite)[move=sysop] (indefinite) [cascading]',
179 'api' => [
180 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
181 'cascade' => true,
189 * @dataProvider provideProtectLogDatabaseRows
191 public function testProtectLogDatabaseRows( $row, $extra ) {
192 $this->doTestLogFormatter( $row, $extra );
196 * Provide different rows from the logging table to test
197 * for backward compatibility.
198 * Do not change the existing data, just add a new database row
200 public static function provideModifyLogDatabaseRows() {
201 return [
202 // Current format
205 'type' => 'protect',
206 'action' => 'modify',
207 'comment' => 'protect comment',
208 'namespace' => NS_MAIN,
209 'title' => 'ProtectPage',
210 'params' => [
211 '4::description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
212 '5:bool:cascade' => false,
213 'details' => [
215 'type' => 'edit',
216 'level' => 'sysop',
217 'expiry' => 'infinity',
218 'cascade' => false,
221 'type' => 'move',
222 'level' => 'sysop',
223 'expiry' => 'infinity',
224 'cascade' => false,
230 'text' => 'User changed protection settings for ProtectPage ' .
231 '[Edit=Allow only administrators] ' .
232 '(indefinite) [Move=Allow only administrators] (indefinite)',
233 'api' => [
234 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
235 'cascade' => false,
236 'details' => [
238 'type' => 'edit',
239 'level' => 'sysop',
240 'expiry' => 'infinite',
241 'cascade' => false,
244 'type' => 'move',
245 'level' => 'sysop',
246 'expiry' => 'infinite',
247 'cascade' => false,
254 // Current format with cascade
257 'type' => 'protect',
258 'action' => 'modify',
259 'comment' => 'protect comment',
260 'namespace' => NS_MAIN,
261 'title' => 'ProtectPage',
262 'params' => [
263 '4::description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
264 '5:bool:cascade' => true,
265 'details' => [
267 'type' => 'edit',
268 'level' => 'sysop',
269 'expiry' => 'infinity',
270 'cascade' => true,
273 'type' => 'move',
274 'level' => 'sysop',
275 'expiry' => 'infinity',
276 'cascade' => false,
282 'text' => 'User changed protection settings for ProtectPage ' .
283 '[Edit=Allow only administrators] (indefinite) ' .
284 '[Move=Allow only administrators] (indefinite) [cascading]',
285 'api' => [
286 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
287 'cascade' => true,
288 'details' => [
290 'type' => 'edit',
291 'level' => 'sysop',
292 'expiry' => 'infinite',
293 'cascade' => true,
296 'type' => 'move',
297 'level' => 'sysop',
298 'expiry' => 'infinite',
299 'cascade' => false,
306 // Legacy format
309 'type' => 'protect',
310 'action' => 'modify',
311 'comment' => 'protect comment',
312 'namespace' => NS_MAIN,
313 'title' => 'ProtectPage',
314 'params' => [
315 '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
320 'legacy' => true,
321 'text' => 'User changed protection settings for ProtectPage ' .
322 '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
323 'api' => [
324 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
325 'cascade' => false,
330 // Legacy format with cascade
333 'type' => 'protect',
334 'action' => 'modify',
335 'comment' => 'protect comment',
336 'namespace' => NS_MAIN,
337 'title' => 'ProtectPage',
338 'params' => [
339 '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
340 'cascade',
344 'legacy' => true,
345 'text' => 'User changed protection settings for ProtectPage ' .
346 '[edit=sysop] (indefinite)[move=sysop] (indefinite) [cascading]',
347 'api' => [
348 'description' => '[edit=sysop] (indefinite)[move=sysop] (indefinite)',
349 'cascade' => true,
357 * @dataProvider provideModifyLogDatabaseRows
359 public function testModifyLogDatabaseRows( $row, $extra ) {
360 $this->doTestLogFormatter( $row, $extra );
364 * Provide different rows from the logging table to test
365 * for backward compatibility.
366 * Do not change the existing data, just add a new database row
368 public static function provideUnprotectLogDatabaseRows() {
369 return [
370 // Current format
373 'type' => 'protect',
374 'action' => 'unprotect',
375 'comment' => 'unprotect comment',
376 'namespace' => NS_MAIN,
377 'title' => 'ProtectPage',
378 'params' => [],
381 'text' => 'User removed protection from ProtectPage',
382 'api' => [],
389 * @dataProvider provideUnprotectLogDatabaseRows
391 public function testUnprotectLogDatabaseRows( $row, $extra ) {
392 $this->doTestLogFormatter( $row, $extra );
396 * Provide different rows from the logging table to test
397 * for backward compatibility.
398 * Do not change the existing data, just add a new database row
400 public static function provideMoveProtLogDatabaseRows() {
401 return [
402 // Current format
405 'type' => 'protect',
406 'action' => 'move_prot',
407 'comment' => 'Move comment',
408 'namespace' => NS_MAIN,
409 'title' => 'NewPage',
410 'params' => [
411 '4::oldtitle' => 'OldPage',
415 'text' => 'User moved protection settings from OldPage to NewPage',
416 'api' => [
417 'oldtitle_ns' => 0,
418 'oldtitle_title' => 'OldPage',
423 // Legacy format
426 'type' => 'protect',
427 'action' => 'move_prot',
428 'comment' => 'Move comment',
429 'namespace' => NS_MAIN,
430 'title' => 'NewPage',
431 'params' => [
432 'OldPage',
436 'legacy' => true,
437 'text' => 'User moved protection settings from OldPage to NewPage',
438 'api' => [
439 'oldtitle_ns' => 0,
440 'oldtitle_title' => 'OldPage',
448 * @dataProvider provideMoveProtLogDatabaseRows
450 public function testMoveProtLogDatabaseRows( $row, $extra ) {
451 $this->doTestLogFormatter( $row, $extra );
454 public static function provideGetActionLinks() {
455 yield [
456 [ 'protect' ],
457 true
459 yield [
461 false
466 * @param string[] $permissions
467 * @param bool $shouldMatch
468 * @dataProvider provideGetActionLinks
469 * @covers \ProtectLogFormatter::getActionLinks
471 public function testGetActionLinks( array $permissions, $shouldMatch ) {
472 RequestContext::resetMain();
473 $user = $this->mockUserAuthorityWithPermissions( new UserIdentityValue( 42, __METHOD__ ), $permissions );
474 $row = $this->expandDatabaseRow( [
475 'type' => 'protect',
476 'action' => 'unprotect',
477 'comment' => 'unprotect comment',
478 'namespace' => NS_MAIN,
479 'title' => 'ProtectPage',
480 'params' => [],
481 ], false );
482 $context = new RequestContext();
483 $context->setAuthority( $user );
484 $context->setLanguage( 'en' );
485 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromRow( $row );
486 $formatter->setContext( $context );
487 $titleFactory = $this->createMock( TitleFactory::class );
488 $titleFactory->method( 'makeTitle' )->willReturnCallback( static function ( ...$params ) {
489 $ret = Title::makeTitle( ...$params );
490 $ret->resetArticleID( 0 );
491 return $ret;
492 } );
493 $this->setService( 'TitleFactory', $titleFactory );
494 $formatter->setLinkRenderer( ( new LinkRendererFactory(
495 $this->getServiceContainer()->getTitleFormatter(),
496 $this->createMock( LinkCache::class ),
497 $this->getServiceContainer()->getSpecialPageFactory(),
498 $this->getServiceContainer()->getHookContainer()
499 ) )->create() );
500 if ( $shouldMatch ) {
501 $this->assertStringMatchesFormat(
502 '%Aaction=protect%A', $formatter->getActionLinks() );
503 } else {
504 $this->assertStringNotMatchesFormat(
505 '%Aaction=protect%A', $formatter->getActionLinks() );