Merge "Update UploadWizard-specific messages"
[lhc/web/wiklou.git] / tests / phpunit / includes / logging / LogFormatterTest.php
1 <?php
2
3 /**
4 * @group Database
5 */
6 class LogFormatterTest extends MediaWikiLangTestCase {
7
8 /**
9 * @var User
10 */
11 protected $user;
12
13 /**
14 * @var Title
15 */
16 protected $title;
17
18 /**
19 * @var RequestContext
20 */
21 protected $context;
22
23 /**
24 * @var Title
25 */
26 protected $target;
27
28 /**
29 * @var string
30 */
31 protected $user_comment;
32
33 protected function setUp() {
34 parent::setUp();
35
36 global $wgLang;
37
38 $this->setMwGlobals( array(
39 'wgLogTypes' => array( 'phpunit' ),
40 'wgLogActionsHandlers' => array( 'phpunit/test' => 'LogFormatter',
41 'phpunit/param' => 'LogFormatter' ),
42 'wgUser' => User::newFromName( 'Testuser' ),
43 'wgExtensionMessagesFiles' => array( 'LogTests' => __DIR__ . '/LogTests.i18n.php' ),
44 ) );
45
46 Language::getLocalisationCache()->recache( $wgLang->getCode() );
47
48 $this->user = User::newFromName( 'Testuser' );
49 $this->title = Title::newFromText( 'SomeTitle' );
50 $this->target = Title::newFromText( 'TestTarget' );
51
52 $this->context = new RequestContext();
53 $this->context->setUser( $this->user );
54 $this->context->setTitle( $this->title );
55 $this->context->setLanguage( $wgLang );
56
57 $this->user_comment = '<User comment about action>';
58 }
59
60 protected function tearDown() {
61 parent::tearDown();
62
63 global $wgLang;
64 Language::getLocalisationCache()->recache( $wgLang->getCode() );
65 }
66
67 public function newLogEntry( $action, $params ) {
68 $logEntry = new ManualLogEntry( 'phpunit', $action );
69 $logEntry->setPerformer( $this->user );
70 $logEntry->setTarget( $this->title );
71 $logEntry->setComment( 'A very good reason' );
72
73 $logEntry->setParameters( $params );
74
75 return $logEntry;
76 }
77
78 /**
79 * @covers LogFormatter::newFromEntry
80 */
81 public function testNormalLogParams() {
82 $entry = $this->newLogEntry( 'test', array() );
83 $formatter = LogFormatter::newFromEntry( $entry );
84 $formatter->setContext( $this->context );
85
86 $formatter->setShowUserToolLinks( false );
87 $paramsWithoutTools = $formatter->getMessageParametersForTesting();
88 unset( $formatter->parsedParameters );
89
90 $formatter->setShowUserToolLinks( true );
91 $paramsWithTools = $formatter->getMessageParametersForTesting();
92
93 $userLink = Linker::userLink(
94 $this->user->getId(),
95 $this->user->getName()
96 );
97
98 $userTools = Linker::userToolLinksRedContribs(
99 $this->user->getId(),
100 $this->user->getName(),
101 $this->user->getEditCount()
102 );
103
104 $titleLink = Linker::link( $this->title, null, array(), array() );
105
106 // $paramsWithoutTools and $paramsWithTools should be only different
107 // in index 0
108 $this->assertEquals( $paramsWithoutTools[1], $paramsWithTools[1] );
109 $this->assertEquals( $paramsWithoutTools[2], $paramsWithTools[2] );
110
111 $this->assertEquals( $userLink, $paramsWithoutTools[0]['raw'] );
112 $this->assertEquals( $userLink . $userTools, $paramsWithTools[0]['raw'] );
113
114 $this->assertEquals( $this->user->getName(), $paramsWithoutTools[1] );
115
116 $this->assertEquals( $titleLink, $paramsWithoutTools[2]['raw'] );
117 }
118
119 /**
120 * @covers LogFormatter::newFromEntry
121 * @covers LogFormatter::getActionText
122 */
123 public function testLogParamsTypeRaw() {
124 $params = array( '4:raw:raw' => Linker::link( $this->title, null, array(), array() ) );
125 $expected = Linker::link( $this->title, null, array(), array() );
126
127 $entry = $this->newLogEntry( 'param', $params );
128 $formatter = LogFormatter::newFromEntry( $entry );
129 $formatter->setContext( $this->context );
130
131 $logParam = $formatter->getActionText();
132
133 $this->assertEquals( $expected, $logParam );
134 }
135
136 /**
137 * @covers LogFormatter::newFromEntry
138 * @covers LogFormatter::getActionText
139 */
140 public function testLogParamsTypeMsg() {
141 $params = array( '4:msg:msg' => 'log-description-phpunit' );
142 $expected = wfMessage( 'log-description-phpunit' )->text();
143
144 $entry = $this->newLogEntry( 'param', $params );
145 $formatter = LogFormatter::newFromEntry( $entry );
146 $formatter->setContext( $this->context );
147
148 $logParam = $formatter->getActionText();
149
150 $this->assertEquals( $expected, $logParam );
151 }
152
153 /**
154 * @covers LogFormatter::newFromEntry
155 * @covers LogFormatter::getActionText
156 */
157 public function testLogParamsTypeMsgContent() {
158 $params = array( '4:msg-content:msgContent' => 'log-description-phpunit' );
159 $expected = wfMessage( 'log-description-phpunit' )->inContentLanguage()->text();
160
161 $entry = $this->newLogEntry( 'param', $params );
162 $formatter = LogFormatter::newFromEntry( $entry );
163 $formatter->setContext( $this->context );
164
165 $logParam = $formatter->getActionText();
166
167 $this->assertEquals( $expected, $logParam );
168 }
169
170 /**
171 * @covers LogFormatter::newFromEntry
172 * @covers LogFormatter::getActionText
173 */
174 public function testLogParamsTypeNumber() {
175 global $wgLang;
176
177 $params = array( '4:number:number' => 123456789 );
178 $expected = $wgLang->formatNum( 123456789 );
179
180 $entry = $this->newLogEntry( 'param', $params );
181 $formatter = LogFormatter::newFromEntry( $entry );
182 $formatter->setContext( $this->context );
183
184 $logParam = $formatter->getActionText();
185
186 $this->assertEquals( $expected, $logParam );
187 }
188
189 /**
190 * @covers LogFormatter::newFromEntry
191 * @covers LogFormatter::getActionText
192 */
193 public function testLogParamsTypeUserLink() {
194 $params = array( '4:user-link:userLink' => $this->user->getName() );
195 $expected = Linker::userLink(
196 $this->user->getId(),
197 $this->user->getName()
198 );
199
200 $entry = $this->newLogEntry( 'param', $params );
201 $formatter = LogFormatter::newFromEntry( $entry );
202 $formatter->setContext( $this->context );
203
204 $logParam = $formatter->getActionText();
205
206 $this->assertEquals( $expected, $logParam );
207 }
208
209 /**
210 * @covers LogFormatter::newFromEntry
211 * @covers LogFormatter::getActionText
212 */
213 public function testLogParamsTypeTitleLink() {
214 $params = array( '4:title-link:titleLink' => $this->title->getText() );
215 $expected = Linker::link( $this->title, null, array(), array() );
216
217 $entry = $this->newLogEntry( 'param', $params );
218 $formatter = LogFormatter::newFromEntry( $entry );
219 $formatter->setContext( $this->context );
220
221 $logParam = $formatter->getActionText();
222
223 $this->assertEquals( $expected, $logParam );
224 }
225
226 /**
227 * @covers LogFormatter::newFromEntry
228 * @covers LogFormatter::getActionText
229 */
230 public function testLogParamsTypePlain() {
231 $params = array( '4:plain:plain' => 'Some plain text' );
232 $expected = 'Some plain text';
233
234 $entry = $this->newLogEntry( 'param', $params );
235 $formatter = LogFormatter::newFromEntry( $entry );
236 $formatter->setContext( $this->context );
237
238 $logParam = $formatter->getActionText();
239
240 $this->assertEquals( $expected, $logParam );
241 }
242
243 /**
244 * @covers LogFormatter::newFromEntry
245 * @covers LogFormatter::getComment
246 */
247 public function testLogComment() {
248 $entry = $this->newLogEntry( 'test', array() );
249 $formatter = LogFormatter::newFromEntry( $entry );
250 $formatter->setContext( $this->context );
251
252 $comment = ltrim( Linker::commentBlock( $entry->getComment() ) );
253
254 $this->assertEquals( $comment, $formatter->getComment() );
255 }
256
257 /**
258 * @dataProvider provideApiParamFormatting
259 * @covers LogFormatter::formatParametersForApi
260 * @covers LogFormatter::formatParameterValueForApi
261 */
262 public function testApiParamFormatting( $key, $value, $expected ) {
263 $entry = $this->newLogEntry( 'param', array( $key => $value ) );
264 $formatter = LogFormatter::newFromEntry( $entry );
265 $formatter->setContext( $this->context );
266
267 ApiResult::setIndexedTagName( $expected, 'param' );
268 ApiResult::setArrayType( $expected, 'assoc' );
269
270 $this->assertEquals( $expected, $formatter->formatParametersForApi() );
271 }
272
273 public static function provideApiParamFormatting() {
274 return array(
275 array( 0, 'value', array( 'value' ) ),
276 array( 'named', 'value', array( 'named' => 'value' ) ),
277 array( '::key', 'value', array( 'key' => 'value' ) ),
278 array( '4::key', 'value', array( 'key' => 'value' ) ),
279 array( '4:raw:key', 'value', array( 'key' => 'value' ) ),
280 array( '4:plain:key', 'value', array( 'key' => 'value' ) ),
281 array( '4:bool:key', '1', array( 'key' => true ) ),
282 array( '4:bool:key', '0', array( 'key' => false ) ),
283 array( '4:number:key', '123', array( 'key' => 123 ) ),
284 array( '4:number:key', '123.5', array( 'key' => 123.5 ) ),
285 array( '4:array:key', array(), array( 'key' => array( ApiResult::META_TYPE => 'array' ) ) ),
286 array( '4:assoc:key', array(), array( 'key' => array( ApiResult::META_TYPE => 'assoc' ) ) ),
287 array( '4:kvp:key', array(), array( 'key' => array( ApiResult::META_TYPE => 'kvp' ) ) ),
288 array( '4:timestamp:key', '20150102030405', array( 'key' => '2015-01-02T03:04:05Z' ) ),
289 array( '4:msg:key', 'parentheses', array(
290 'key_key' => 'parentheses',
291 'key_text' => wfMessage( 'parentheses' )->text(),
292 ) ),
293 array( '4:msg-content:key', 'parentheses', array(
294 'key_key' => 'parentheses',
295 'key_text' => wfMessage( 'parentheses' )->inContentLanguage()->text(),
296 ) ),
297 array( '4:title:key', 'project:foo', array(
298 'key_ns' => NS_PROJECT,
299 'key_title' => Title::newFromText( 'project:foo' )->getFullText(),
300 ) ),
301 array( '4:title-link:key', 'project:foo', array(
302 'key_ns' => NS_PROJECT,
303 'key_title' => Title::newFromText( 'project:foo' )->getFullText(),
304 ) ),
305 array( '4:user:key', 'foo', array( 'key' => 'Foo' ) ),
306 array( '4:user-link:key', 'foo', array( 'key' => 'Foo' ) ),
307 );
308 }
309
310 /**
311 * @covers LogFormatter::getIRCActionComment
312 * @covers LogFormatter::getIRCActionText
313 */
314 public function testIrcMsgForLogTypeBlock() {
315 $sep = $this->context->msg( 'colon-separator' )->text();
316
317 # block/block
318 $this->assertIRCComment(
319 $this->context->msg( 'blocklogentry', 'SomeTitle', 'duration', '(flags)' )->plain()
320 . $sep . $this->user_comment,
321 'block', 'block',
322 array(
323 '5::duration' => 'duration',
324 '6::flags' => 'flags',
325 ),
326 $this->user_comment
327 );
328 # block/block - legacy
329 $this->assertIRCComment(
330 $this->context->msg( 'blocklogentry', 'SomeTitle', 'duration', '(flags)' )->plain()
331 . $sep . $this->user_comment,
332 'block', 'block',
333 array(
334 'duration',
335 'flags',
336 ),
337 $this->user_comment,
338 '',
339 true
340 );
341 # block/unblock
342 $this->assertIRCComment(
343 $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
344 'block', 'unblock',
345 array(),
346 $this->user_comment
347 );
348 # block/reblock
349 $this->assertIRCComment(
350 $this->context->msg( 'reblock-logentry', 'SomeTitle', 'duration', '(flags)' )->plain()
351 . $sep . $this->user_comment,
352 'block', 'reblock',
353 array(
354 '5::duration' => 'duration',
355 '6::flags' => 'flags',
356 ),
357 $this->user_comment
358 );
359 }
360
361 /**
362 * @covers LogFormatter::getIRCActionComment
363 * @covers LogFormatter::getIRCActionText
364 */
365 public function testIrcMsgForLogTypeDelete() {
366 $sep = $this->context->msg( 'colon-separator' )->text();
367
368 # delete/delete
369 $this->assertIRCComment(
370 $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
371 'delete', 'delete',
372 array(),
373 $this->user_comment
374 );
375
376 # delete/restore
377 $this->assertIRCComment(
378 $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
379 'delete', 'restore',
380 array(),
381 $this->user_comment
382 );
383 }
384
385 /**
386 * @covers LogFormatter::getIRCActionComment
387 * @covers LogFormatter::getIRCActionText
388 */
389 public function testIrcMsgForLogTypeNewusers() {
390 $this->assertIRCComment(
391 'New user account',
392 'newusers', 'newusers',
393 array()
394 );
395 $this->assertIRCComment(
396 'New user account',
397 'newusers', 'create',
398 array()
399 );
400 $this->assertIRCComment(
401 'created new account SomeTitle',
402 'newusers', 'create2',
403 array()
404 );
405 $this->assertIRCComment(
406 'Account created automatically',
407 'newusers', 'autocreate',
408 array()
409 );
410 }
411
412 /**
413 * @covers LogFormatter::getIRCActionComment
414 * @covers LogFormatter::getIRCActionText
415 */
416 public function testIrcMsgForLogTypeMove() {
417 $move_params = array(
418 '4::target' => $this->target->getPrefixedText(),
419 '5::noredir' => 0,
420 );
421 $sep = $this->context->msg( 'colon-separator' )->text();
422
423 # move/move
424 $this->assertIRCComment(
425 $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )
426 ->plain() . $sep . $this->user_comment,
427 'move', 'move',
428 $move_params,
429 $this->user_comment
430 );
431
432 # move/move_redir
433 $this->assertIRCComment(
434 $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )
435 ->plain() . $sep . $this->user_comment,
436 'move', 'move_redir',
437 $move_params,
438 $this->user_comment
439 );
440 }
441
442 /**
443 * @covers LogFormatter::getIRCActionComment
444 * @covers LogFormatter::getIRCActionText
445 */
446 public function testIrcMsgForLogTypePatrol() {
447 # patrol/patrol
448 $this->assertIRCComment(
449 $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(),
450 'patrol', 'patrol',
451 array(
452 '4::curid' => '777',
453 '5::previd' => '666',
454 '6::auto' => 0,
455 )
456 );
457 }
458
459 /**
460 * @covers LogFormatter::getIRCActionComment
461 * @covers LogFormatter::getIRCActionText
462 */
463 public function testIrcMsgForLogTypeProtect() {
464 $protectParams = array(
465 '[edit=sysop] (indefinite) ‎[move=sysop] (indefinite)'
466 );
467 $sep = $this->context->msg( 'colon-separator' )->text();
468
469 # protect/protect
470 $this->assertIRCComment(
471 $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams[0] )
472 ->plain() . $sep . $this->user_comment,
473 'protect', 'protect',
474 $protectParams,
475 $this->user_comment
476 );
477
478 # protect/unprotect
479 $this->assertIRCComment(
480 $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
481 'protect', 'unprotect',
482 array(),
483 $this->user_comment
484 );
485
486 # protect/modify
487 $this->assertIRCComment(
488 $this->context->msg( 'modifiedarticleprotection', 'SomeTitle ' . $protectParams[0] )
489 ->plain() . $sep . $this->user_comment,
490 'protect', 'modify',
491 $protectParams,
492 $this->user_comment
493 );
494
495 # protect/move_prot
496 $this->assertIRCComment(
497 $this->context->msg( 'movedarticleprotection', 'SomeTitle', 'OldTitle' )
498 ->plain() . $sep . $this->user_comment,
499 'protect', 'move_prot',
500 array(
501 '4::oldtitle' => 'OldTitle'
502 ),
503 $this->user_comment
504 );
505 }
506
507 /**
508 * @covers LogFormatter::getIRCActionComment
509 * @covers LogFormatter::getIRCActionText
510 */
511 public function testIrcMsgForLogTypeUpload() {
512 $sep = $this->context->msg( 'colon-separator' )->text();
513
514 # upload/upload
515 $this->assertIRCComment(
516 $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
517 'upload', 'upload',
518 array(),
519 $this->user_comment
520 );
521
522 # upload/overwrite
523 $this->assertIRCComment(
524 $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
525 'upload', 'overwrite',
526 array(),
527 $this->user_comment
528 );
529 }
530
531 /**
532 * @covers LogFormatter::getIRCActionComment
533 * @covers LogFormatter::getIRCActionText
534 */
535 public function testIrcMsgForLogTypeMerge() {
536 $sep = $this->context->msg( 'colon-separator' )->text();
537
538 # merge/merge
539 $this->assertIRCComment(
540 $this->context->msg( 'pagemerge-logentry', 'SomeTitle', 'Dest', 'timestamp' )->plain()
541 . $sep . $this->user_comment,
542 'merge', 'merge',
543 array(
544 '4::dest' => 'Dest',
545 '5::mergepoint' => 'timestamp',
546 ),
547 $this->user_comment
548 );
549 }
550
551 /**
552 * @covers LogFormatter::getIRCActionComment
553 * @covers LogFormatter::getIRCActionText
554 */
555 public function testIrcMsgForLogTypeImport() {
556 $sep = $this->context->msg( 'colon-separator' )->text();
557
558 # import/upload
559 $msg = $this->context->msg( 'import-logentry-upload', 'SomeTitle' )->plain() .
560 $sep .
561 $this->user_comment;
562 $this->assertIRCComment(
563 $msg,
564 'import', 'upload',
565 array(),
566 $this->user_comment
567 );
568
569 # import/interwiki
570 $msg = $this->context->msg( 'import-logentry-interwiki', 'SomeTitle' )->plain() .
571 $sep .
572 $this->user_comment;
573 $this->assertIRCComment(
574 $msg,
575 'import', 'interwiki',
576 array(),
577 $this->user_comment
578 );
579 }
580
581 /**
582 * @param string $expected Expected IRC text without colors codes
583 * @param string $type Log type (move, delete, suppress, patrol ...)
584 * @param string $action A log type action
585 * @param array $params
586 * @param string $comment (optional) A comment for the log action
587 * @param string $msg (optional) A message for PHPUnit :-)
588 */
589 protected function assertIRCComment( $expected, $type, $action, $params,
590 $comment = null, $msg = '', $legacy = false
591 ) {
592 $logEntry = new ManualLogEntry( $type, $action );
593 $logEntry->setPerformer( $this->user );
594 $logEntry->setTarget( $this->title );
595 if ( $comment !== null ) {
596 $logEntry->setComment( $comment );
597 }
598 $logEntry->setParameters( $params );
599 $logEntry->setLegacy( $legacy );
600
601 $formatter = LogFormatter::newFromEntry( $logEntry );
602 $formatter->setContext( $this->context );
603
604 // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment
605 $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() );
606
607 $this->assertEquals(
608 $expected,
609 $ircRcComment,
610 $msg
611 );
612 }
613
614 }