Localisation updates from https://translatewiki.net.
[mediawiki.git] / tests / phpunit / includes / logging / LogFormatterTest.php
blob268e69f69ac0f79a9a25247b7dfbf7655db1cc7c
1 <?php
3 use MediaWiki\Api\ApiResult;
4 use MediaWiki\Context\DerivativeContext;
5 use MediaWiki\Context\RequestContext;
6 use MediaWiki\Linker\Linker;
7 use MediaWiki\MainConfigNames;
8 use MediaWiki\Message\Message;
9 use MediaWiki\Permissions\SimpleAuthority;
10 use MediaWiki\RCFeed\IRCColourfulRCFeedFormatter;
11 use MediaWiki\SpecialPage\SpecialPage;
12 use MediaWiki\Title\Title;
13 use MediaWiki\User\User;
14 use MediaWiki\User\UserIdentityValue;
16 /**
17 * @group Database
19 class LogFormatterTest extends MediaWikiLangTestCase {
20 /** @var array */
21 private static $oldExtMsgFiles;
23 /**
24 * @var User
26 protected $user;
28 /**
29 * @var Title
31 protected $title;
33 /**
34 * @var RequestContext
36 protected $context;
38 /**
39 * @var Title
41 protected $target;
43 /**
44 * @var string
46 protected $user_comment;
48 public static function setUpBeforeClass(): void {
49 parent::setUpBeforeClass();
51 global $wgExtensionMessagesFiles;
52 self::$oldExtMsgFiles = $wgExtensionMessagesFiles;
53 $wgExtensionMessagesFiles['LogTests'] = __DIR__ . '/LogTests.i18n.php';
56 public static function tearDownAfterClass(): void {
57 global $wgExtensionMessagesFiles;
58 $wgExtensionMessagesFiles = self::$oldExtMsgFiles;
60 parent::tearDownAfterClass();
63 protected function setUp(): void {
64 parent::setUp();
66 $this->overrideConfigValues( [
67 MainConfigNames::LogTypes => [ 'phpunit' ],
68 MainConfigNames::LogActionsHandlers => [ 'phpunit/test' => LogFormatter::class,
69 'phpunit/param' => LogFormatter::class ],
70 ] );
72 $this->user = User::newFromName( 'Testuser' );
73 $this->title = Title::makeTitle( NS_MAIN, 'SomeTitle' );
74 $this->target = Title::makeTitle( NS_MAIN, 'TestTarget' );
76 $this->context = new RequestContext();
77 $this->context->setUser( $this->user );
78 $this->context->setTitle( $this->title );
79 $this->context->setLanguage( RequestContext::getMain()->getLanguage() );
81 $this->user_comment = '<User comment about action>';
84 public function newLogEntry( $action, $params ) {
85 $logEntry = new ManualLogEntry( 'phpunit', $action );
86 $logEntry->setPerformer( $this->user );
87 $logEntry->setTarget( $this->title );
88 $logEntry->setComment( 'A very good reason' );
90 $logEntry->setParameters( $params );
92 return $logEntry;
95 /**
96 * @covers \LogFormatter::setShowUserToolLinks
98 public function testNormalLogParams() {
99 $entry = $this->newLogEntry( 'test', [] );
100 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
101 $formatter->setContext( $this->context );
103 $formatter->setShowUserToolLinks( false );
104 $paramsWithoutTools = $formatter->getMessageParametersForTesting();
106 $formatter2 = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
107 $formatter2->setContext( $this->context );
108 $formatter2->setShowUserToolLinks( true );
109 $paramsWithTools = $formatter2->getMessageParametersForTesting();
111 $userLink = Linker::userLink(
112 $this->user->getId(),
113 $this->user->getName()
116 $userTools = Linker::userToolLinksRedContribs(
117 $this->user->getId(),
118 $this->user->getName(),
119 $this->user->getEditCount(),
120 false
123 $titleLink = Linker::link( $this->title, null, [], [] );
125 // $paramsWithoutTools and $paramsWithTools should be only different
126 // in index 0
127 $this->assertEquals( $paramsWithoutTools[1], $paramsWithTools[1] );
128 $this->assertEquals( $paramsWithoutTools[2], $paramsWithTools[2] );
130 $this->assertEquals( Message::rawParam( $userLink ), $paramsWithoutTools[0] );
131 $this->assertEquals( Message::rawParam( $userLink . $userTools ), $paramsWithTools[0] );
133 $this->assertEquals( $this->user->getName(), $paramsWithoutTools[1] );
135 $this->assertEquals( Message::rawParam( $titleLink ), $paramsWithoutTools[2] );
139 * @covers \LogFormatter::getActionText
141 public function testLogParamsTypeRaw() {
142 $params = [ '4:raw:raw' => Linker::link( $this->title, null, [], [] ) ];
143 $expected = Linker::link( $this->title, null, [], [] );
145 $entry = $this->newLogEntry( 'param', $params );
146 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
147 $formatter->setContext( $this->context );
149 $logParam = $formatter->getActionText();
151 $this->assertEquals( $expected, $logParam );
155 * @covers \LogFormatter::getActionText
157 public function testLogParamsTypeMsg() {
158 $params = [ '4:msg:msg' => 'log-description-phpunit' ];
159 $expected = wfMessage( 'log-description-phpunit' )->text();
161 $entry = $this->newLogEntry( 'param', $params );
162 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
163 $formatter->setContext( $this->context );
165 $logParam = $formatter->getActionText();
167 $this->assertEquals( $expected, $logParam );
171 * @covers \LogFormatter::getActionText
173 public function testLogParamsTypeMsgContent() {
174 $params = [ '4:msg-content:msgContent' => 'log-description-phpunit' ];
175 $expected = wfMessage( 'log-description-phpunit' )->inContentLanguage()->text();
177 $entry = $this->newLogEntry( 'param', $params );
178 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
179 $formatter->setContext( $this->context );
181 $logParam = $formatter->getActionText();
183 $this->assertEquals( $expected, $logParam );
187 * @covers \LogFormatter::getActionText
189 public function testLogParamsTypeNumber() {
190 global $wgLang;
192 $params = [ '4:number:number' => 123456789 ];
193 $expected = $wgLang->formatNum( 123456789 );
195 $entry = $this->newLogEntry( 'param', $params );
196 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
197 $formatter->setContext( $this->context );
199 $logParam = $formatter->getActionText();
201 $this->assertEquals( $expected, $logParam );
205 * @covers \LogFormatter::getActionText
207 public function testLogParamsTypeUserLink() {
208 $params = [ '4:user-link:userLink' => $this->user->getName() ];
209 $expected = Linker::userLink(
210 $this->user->getId(),
211 $this->user->getName()
214 $entry = $this->newLogEntry( 'param', $params );
215 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
216 $formatter->setContext( $this->context );
218 $logParam = $formatter->getActionText();
220 $this->assertEquals( $expected, $logParam );
224 * @covers \LogFormatter::getActionText
226 public function testLogParamsTypeUserLink_empty() {
227 $params = [ '4:user-link:userLink' => ':' ];
229 $entry = $this->newLogEntry( 'param', $params );
230 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
232 $this->context->setLanguage( 'qqx' );
233 $formatter->setContext( $this->context );
235 $logParam = $formatter->getActionText();
236 $this->assertStringContainsString( '(empty-username)', $logParam );
240 * @covers \LogFormatter::getActionText
242 public function testLogParamsTypeTitleLink() {
243 $params = [ '4:title-link:titleLink' => $this->title->getText() ];
244 $expected = Linker::link( $this->title, null, [], [] );
246 $entry = $this->newLogEntry( 'param', $params );
247 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
248 $formatter->setContext( $this->context );
250 $logParam = $formatter->getActionText();
252 $this->assertEquals( $expected, $logParam );
256 * @covers \LogFormatter::getActionText
258 public function testLogParamsTypePlain() {
259 $params = [ '4:plain:plain' => 'Some plain text' ];
260 $expected = 'Some plain text';
262 $entry = $this->newLogEntry( 'param', $params );
263 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
264 $formatter->setContext( $this->context );
266 $logParam = $formatter->getActionText();
268 $this->assertEquals( $expected, $logParam );
272 * @covers \LogFormatter::getPerformerElement
273 * @dataProvider provideLogElement
275 public function testGetPerformerElement( $deletedFlag, $allowedAction ) {
276 $entry = $this->newLogEntry( 'param', [] );
277 $entry->setPerformer( new UserIdentityValue( 1328435, 'Test' ) );
278 if ( $deletedFlag !== 'none' ) {
279 $entry->setDeleted(
280 LogPage::DELETED_USER |
281 ( $deletedFlag === 'suppressed' ? LogPage::DELETED_RESTRICTED : 0 )
285 $context = new DerivativeContext( $this->context );
286 if ( $allowedAction !== 'none' ) {
287 $context->setAuthority( new SimpleAuthority(
288 $this->context->getUser(),
289 [ $deletedFlag === 'suppressed' ? 'suppressrevision' : 'deletedhistory' ]
290 ) );
293 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
294 $formatter->setContext( $context );
295 if ( $allowedAction === 'view-for-user' ) {
296 $formatter->setAudience( LogFormatter::FOR_THIS_USER );
299 $element = $formatter->getPerformerElement();
300 if ( $allowedAction === 'none' ||
301 ( $deletedFlag !== 'none' && $allowedAction === 'view-public' )
303 $this->assertStringNotContainsString( 'User:Test', $element );
304 } else {
305 $this->assertStringContainsString( 'User:Test', $element );
308 if ( $deletedFlag === 'none' ) {
309 $this->assertStringNotContainsString( 'history-deleted', $element );
310 } else {
311 $this->assertStringContainsString( 'history-deleted', $element );
313 if ( $deletedFlag === 'suppressed' ) {
314 $this->assertStringContainsString( 'mw-history-suppressed', $element );
315 } else {
316 $this->assertStringNotContainsString( 'mw-history-suppressed', $element );
321 * @covers \LogFormatter::getComment
322 * @dataProvider provideLogElement
324 public function testLogComment( $deletedFlag, $allowedAction ) {
325 $entry = $this->newLogEntry( 'test', [] );
326 if ( $deletedFlag !== 'none' ) {
327 $entry->setDeleted(
328 LogPage::DELETED_COMMENT |
329 ( $deletedFlag === 'suppressed' ? LogPage::DELETED_RESTRICTED : 0 )
333 $context = new DerivativeContext( $this->context );
334 if ( $allowedAction !== 'none' ) {
335 $context->setAuthority( new SimpleAuthority(
336 $this->context->getUser(),
337 [ $deletedFlag === 'suppressed' ? 'suppressrevision' : 'deletedhistory' ]
338 ) );
341 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
342 $formatter->setContext( $context );
343 if ( $allowedAction === 'view-for-user' ) {
344 $formatter->setAudience( LogFormatter::FOR_THIS_USER );
347 $expectedComment = ltrim( $this->getServiceContainer()->getCommentFormatter()->formatBlock( $entry->getComment() ) );
348 $comment = $formatter->getComment();
350 if ( $allowedAction === 'none' ||
351 ( $deletedFlag !== 'none' && $allowedAction === 'view-public' )
353 $this->assertStringNotContainsString( $expectedComment, $comment );
354 } else {
355 $this->assertStringContainsString( $expectedComment, $comment );
357 if ( $deletedFlag === 'none' ) {
358 $this->assertStringNotContainsString( 'history-deleted', $comment );
359 } else {
360 $this->assertStringContainsString( 'history-deleted', $comment );
362 if ( $deletedFlag === 'suppressed' ) {
363 $this->assertStringContainsString( 'mw-history-suppressed', $comment );
364 } else {
365 $this->assertStringNotContainsString( 'mw-history-suppressed', $comment );
369 public static function provideLogElement() {
370 return [
371 [ 'none', 'view' ],
372 [ 'deleted', 'none' ],
373 [ 'deleted', 'view-for-user' ],
374 [ 'deleted', 'view-public' ],
375 [ 'suppressed', 'none' ],
376 [ 'suppressed', 'view-for-user' ],
377 [ 'suppressed', 'view-public' ],
382 * @dataProvider provideApiParamFormatting
383 * @covers \LogFormatter::formatParametersForApi
384 * @covers \LogFormatter::formatParameterValueForApi
386 public function testApiParamFormatting( $key, $value, $expected ) {
387 $entry = $this->newLogEntry( 'param', [ $key => $value ] );
388 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $entry );
389 $formatter->setContext( $this->context );
391 ApiResult::setIndexedTagName( $expected, 'param' );
392 ApiResult::setArrayType( $expected, 'assoc' );
394 $this->assertEquals( $expected, $formatter->formatParametersForApi() );
397 public static function provideApiParamFormatting() {
398 return [
399 [ 0, 'value', [ 'value' ] ],
400 [ 'named', 'value', [ 'named' => 'value' ] ],
401 [ '::key', 'value', [ 'key' => 'value' ] ],
402 [ '4::key', 'value', [ 'key' => 'value' ] ],
403 [ '4:raw:key', 'value', [ 'key' => 'value' ] ],
404 [ '4:plain:key', 'value', [ 'key' => 'value' ] ],
405 [ '4:bool:key', '1', [ 'key' => true ] ],
406 [ '4:bool:key', '0', [ 'key' => false ] ],
407 [ '4:number:key', '123', [ 'key' => 123 ] ],
408 [ '4:number:key', '123.5', [ 'key' => 123.5 ] ],
409 [ '4:array:key', [], [ 'key' => [ ApiResult::META_TYPE => 'array' ] ] ],
410 [ '4:assoc:key', [], [ 'key' => [ ApiResult::META_TYPE => 'assoc' ] ] ],
411 [ '4:kvp:key', [], [ 'key' => [ ApiResult::META_TYPE => 'kvp' ] ] ],
412 [ '4:timestamp:key', '20150102030405', [ 'key' => '2015-01-02T03:04:05Z' ] ],
413 [ '4:msg:key', 'parentheses', [
414 'key_key' => 'parentheses',
415 'key_text' => wfMessage( 'parentheses' )->text(),
416 ] ],
417 [ '4:msg-content:key', 'parentheses', [
418 'key_key' => 'parentheses',
419 'key_text' => wfMessage( 'parentheses' )->inContentLanguage()->text(),
420 ] ],
421 [ '4:title:key', 'project:foo', [
422 'key_ns' => NS_PROJECT,
423 'key_title' => Title::makeTitle( NS_PROJECT, 'Foo' )->getFullText(),
424 ] ],
425 [ '4:title-link:key', 'project:foo', [
426 'key_ns' => NS_PROJECT,
427 'key_title' => Title::makeTitle( NS_PROJECT, 'Foo' )->getFullText(),
428 ] ],
429 [ '4:title-link:key', '<invalid>', [
430 'key_ns' => NS_SPECIAL,
431 'key_title' => SpecialPage::getTitleFor( 'Badtitle', '<invalid>' )->getFullText(),
432 ] ],
433 [ '4:user:key', 'foo', [ 'key' => 'Foo' ] ],
434 [ '4:user-link:key', 'foo', [ 'key' => 'Foo' ] ],
439 * The testIrcMsgForAction* tests are supposed to cover the hacky
440 * LogFormatter::getIRCActionText / T36508
442 * Third parties bots listen to those messages. They are clever enough
443 * to fetch the i18n messages from the wiki and then analyze the IRC feed
444 * to reverse engineer the $1, $2 messages.
445 * One thing bots cannot detect is when MediaWiki change the meaning of
446 * a message like what happened when we deployed 1.19. $1 became the user
447 * performing the action which broke basically all bots around.
449 * Should cover the following log actions (which are most commonly used by bots):
450 * - block/block
451 * - block/unblock
452 * - block/reblock
453 * - delete/delete
454 * - delete/restore
455 * - newusers/create
456 * - newusers/create2
457 * - newusers/autocreate
458 * - move/move
459 * - move/move_redir
460 * - protect/protect
461 * - protect/modifyprotect
462 * - protect/unprotect
463 * - protect/move_prot
464 * - upload/upload
465 * - merge/merge
466 * - import/upload
467 * - import/interwiki
469 * As well as the following Auto Edit Summaries:
470 * - blank
471 * - replace
472 * - rollback
473 * - undo
477 * @covers \LogFormatter::getIRCActionComment
478 * @covers \LogFormatter::getIRCActionText
480 public function testIrcMsgForLogTypeBlock() {
481 $sep = $this->context->msg( 'colon-separator' )->text();
483 # block/block
484 $this->assertIRCComment(
485 $this->context->msg( 'blocklogentry', 'SomeTitle', 'duration', '(flags)' )->plain()
486 . $sep . $this->user_comment,
487 'block', 'block',
489 '5::duration' => 'duration',
490 '6::flags' => 'flags',
492 $this->user_comment
494 # block/block - legacy
495 $this->assertIRCComment(
496 $this->context->msg( 'blocklogentry', 'SomeTitle', 'duration', '(flags)' )->plain()
497 . $sep . $this->user_comment,
498 'block', 'block',
500 'duration',
501 'flags',
503 $this->user_comment,
505 true
507 # block/unblock
508 $this->assertIRCComment(
509 $this->context->msg( 'unblocklogentry', 'SomeTitle' )->plain() . $sep . $this->user_comment,
510 'block', 'unblock',
512 $this->user_comment
514 # block/reblock
515 $this->assertIRCComment(
516 $this->context->msg( 'reblock-logentry', 'SomeTitle', 'duration', '(flags)' )->plain()
517 . $sep . $this->user_comment,
518 'block', 'reblock',
520 '5::duration' => 'duration',
521 '6::flags' => 'flags',
523 $this->user_comment
528 * @covers \LogFormatter::getIRCActionComment
529 * @covers \LogFormatter::getIRCActionText
531 public function testIrcMsgForLogTypeDelete() {
532 $sep = $this->context->msg( 'colon-separator' )->text();
534 # delete/delete
535 $this->assertIRCComment(
536 $this->context->msg( 'deletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
537 'delete', 'delete',
539 $this->user_comment
542 # delete/restore
543 $this->assertIRCComment(
544 $this->context->msg( 'undeletedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
545 'delete', 'restore',
547 $this->user_comment
552 * @covers \LogFormatter::getIRCActionComment
553 * @covers \LogFormatter::getIRCActionText
555 public function testIrcMsgForLogTypeNewusers() {
556 $this->assertIRCComment(
557 'New user account',
558 'newusers', 'newusers',
561 $this->assertIRCComment(
562 'New user account',
563 'newusers', 'create',
566 $this->assertIRCComment(
567 'created new account SomeTitle',
568 'newusers', 'create2',
571 $this->assertIRCComment(
572 'Account created automatically',
573 'newusers', 'autocreate',
579 * @covers \LogFormatter::getIRCActionComment
580 * @covers \LogFormatter::getIRCActionText
582 public function testIrcMsgForLogTypeMove() {
583 $move_params = [
584 '4::target' => $this->target->getPrefixedText(),
585 '5::noredir' => 0,
587 $sep = $this->context->msg( 'colon-separator' )->text();
589 # move/move
590 $this->assertIRCComment(
591 $this->context->msg( '1movedto2', 'SomeTitle', 'TestTarget' )
592 ->plain() . $sep . $this->user_comment,
593 'move', 'move',
594 $move_params,
595 $this->user_comment
598 # move/move_redir
599 $this->assertIRCComment(
600 $this->context->msg( '1movedto2_redir', 'SomeTitle', 'TestTarget' )
601 ->plain() . $sep . $this->user_comment,
602 'move', 'move_redir',
603 $move_params,
604 $this->user_comment
609 * @covers \LogFormatter::getIRCActionComment
610 * @covers \LogFormatter::getIRCActionText
612 public function testIrcMsgForLogTypePatrol() {
613 # patrol/patrol
614 $this->assertIRCComment(
615 $this->context->msg( 'patrol-log-line', 'revision 777', '[[SomeTitle]]', '' )->plain(),
616 'patrol', 'patrol',
618 '4::curid' => '777',
619 '5::previd' => '666',
620 '6::auto' => 0,
626 * @covers \LogFormatter::getIRCActionComment
627 * @covers \LogFormatter::getIRCActionText
629 public function testIrcMsgForLogTypeProtect() {
630 $protectParams = [
631 '4::description' => '[edit=sysop] (indefinite) ‎[move=sysop] (indefinite)'
633 $sep = $this->context->msg( 'colon-separator' )->text();
635 # protect/protect
636 $this->assertIRCComment(
637 $this->context->msg( 'protectedarticle', 'SomeTitle ' . $protectParams['4::description'] )
638 ->plain() . $sep . $this->user_comment,
639 'protect', 'protect',
640 $protectParams,
641 $this->user_comment
644 # protect/unprotect
645 $this->assertIRCComment(
646 $this->context->msg( 'unprotectedarticle', 'SomeTitle' )->plain() . $sep . $this->user_comment,
647 'protect', 'unprotect',
649 $this->user_comment
652 # protect/modify
653 $this->assertIRCComment(
654 $this->context->msg(
655 'modifiedarticleprotection',
656 'SomeTitle ' . $protectParams['4::description']
657 )->plain() . $sep . $this->user_comment,
658 'protect', 'modify',
659 $protectParams,
660 $this->user_comment
663 # protect/move_prot
664 $this->assertIRCComment(
665 $this->context->msg( 'movedarticleprotection', 'SomeTitle', 'OldTitle' )
666 ->plain() . $sep . $this->user_comment,
667 'protect', 'move_prot',
669 '4::oldtitle' => 'OldTitle'
671 $this->user_comment
676 * @covers \LogFormatter::getIRCActionComment
677 * @covers \LogFormatter::getIRCActionText
679 public function testIrcMsgForLogTypeUpload() {
680 $sep = $this->context->msg( 'colon-separator' )->text();
682 # upload/upload
683 $this->assertIRCComment(
684 $this->context->msg( 'uploadedimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
685 'upload', 'upload',
687 $this->user_comment
690 # upload/overwrite
691 $this->assertIRCComment(
692 $this->context->msg( 'overwroteimage', 'SomeTitle' )->plain() . $sep . $this->user_comment,
693 'upload', 'overwrite',
695 $this->user_comment
700 * @covers \LogFormatter::getIRCActionComment
701 * @covers \LogFormatter::getIRCActionText
703 public function testIrcMsgForLogTypeMerge() {
704 $sep = $this->context->msg( 'colon-separator' )->text();
706 # merge/merge
707 $this->assertIRCComment(
708 $this->context->msg( 'pagemerge-logentry', 'SomeTitle', 'Dest', 'timestamp' )->plain()
709 . $sep . $this->user_comment,
710 'merge', 'merge',
712 '4::dest' => 'Dest',
713 '5::mergepoint' => 'timestamp',
715 $this->user_comment
720 * @covers \LogFormatter::getIRCActionComment
721 * @covers \LogFormatter::getIRCActionText
723 public function testIrcMsgForLogTypeImport() {
724 $sep = $this->context->msg( 'colon-separator' )->text();
726 # import/upload
727 $msg = $this->context->msg( 'import-logentry-upload', 'SomeTitle' )->plain() .
728 $sep .
729 $this->user_comment;
730 $this->assertIRCComment(
731 $msg,
732 'import', 'upload',
734 $this->user_comment
737 # import/interwiki
738 $msg = $this->context->msg( 'import-logentry-interwiki', 'SomeTitle' )->plain() .
739 $sep .
740 $this->user_comment;
741 $this->assertIRCComment(
742 $msg,
743 'import', 'interwiki',
745 $this->user_comment
750 * @param string $expected Expected IRC text without colors codes
751 * @param string $type Log type (move, delete, suppress, patrol ...)
752 * @param string $action A log type action
753 * @param array $params
754 * @param string|null $comment A comment for the log action
755 * @param string $msg
756 * @param bool $legacy
758 protected function assertIRCComment( $expected, $type, $action, $params,
759 $comment = null, $msg = '', $legacy = false
761 $logEntry = new ManualLogEntry( $type, $action );
762 $logEntry->setPerformer( $this->user );
763 $logEntry->setTarget( $this->title );
764 if ( $comment !== null ) {
765 $logEntry->setComment( $comment );
767 $logEntry->setParameters( $params );
768 $logEntry->setLegacy( $legacy );
770 $formatter = $this->getServiceContainer()->getLogFormatterFactory()->newFromEntry( $logEntry );
771 $formatter->setContext( $this->context );
773 // Apply the same transformation as done in IRCColourfulRCFeedFormatter::getLine for rc_comment
774 $ircRcComment = IRCColourfulRCFeedFormatter::cleanupForIRC( $formatter->getIRCActionComment() );
776 $this->assertEquals(
777 $expected,
778 $ircRcComment,
779 $msg