Remove deprecated Linker methods

The removed tests in LinkerTest were ported (or were previously
ported) to the new CommentFormatter framework in the CommentParserTest
class; some references to the LinkerTest class have been removed since
CommentParserTest is now the canonical location for these.

Cleaned up a bit more from the removed DummyLinker class as well
(I69689b2037269af3320b6203fc44755f93713489).

Followup-To: I69689b2037269af3320b6203fc44755f93713489
Change-Id: Ia743d13c4fe7f4e3e2bd11274895a261adbfd8e2
This commit is contained in:
C. Scott Ananian 2024-05-01 12:32:58 -04:00 committed by C. Scott Ananian
parent 189d41676f
commit ab660966d2
5 changed files with 168 additions and 751 deletions

View file

@ -211,6 +211,12 @@ because of Phabricator reports.
* SpecialBlock::getTargetAndType, deprecated since 1.36, has been removed.
* ApiQueryBlockInfoTrait::addBlockInfoToQuery(), deprecated since 1.42, has been
removed.
* Linker::makeHeadline(), Linker::generateTOC(), Linker::tocIndent(),
Linker::tocUnindent(), Linker::tocLine(), Linker::tocLineEnd(), and
Linker::tocList(), deprecated in 1.42, have been removed.
* Linker::formatComment(), Linker::formatLinksInComment(),
Linker::commentBlock(), and Linker::revComment(), deprecated in 1.38,
have been removed.
* DummyLinker has been removed. The former DummyLinker parameter
to the 'ImageBeforeProduceHTML' hook is now null.
* …

View file

@ -21,7 +21,7 @@ interface ImageBeforeProduceHTMLHook {
*
* @since 1.35
*
* @param mixed $linker Unused (always null)
* @param null $unused Will always be null
* @param Title &$title Title object of the image
* @param File|false &$file File object, or false if it doesn't exist
* @param array &$frameParams Various parameters with special meanings; see documentation in
@ -36,7 +36,7 @@ interface ImageBeforeProduceHTMLHook {
* @param string &$widthOption Used by the parser to remember the user preference thumbnailsize
* @return bool|void True or no return value to continue or false to skip the default logic
*/
public function onImageBeforeProduceHTML( $linker, &$title, &$file,
public function onImageBeforeProduceHTML( $unused, &$title, &$file,
&$frameParams, &$handlerParams, &$time, &$res, $parser, &$query, &$widthOption
);
}

View file

@ -24,7 +24,6 @@ namespace MediaWiki\Linker;
use File;
use HtmlArmor;
use Language;
use MediaTransformError;
use MediaTransformOutput;
use MediaWiki\Context\ContextSource;
@ -48,7 +47,6 @@ use MediaWiki\User\UserIdentityValue;
use MessageLocalizer;
use Wikimedia\Assert\Assert;
use Wikimedia\IPUtils;
use Wikimedia\Parsoid\Core\TOCData;
use Wikimedia\Rdbms\SelectQueryBuilder;
use Wikimedia\RemexHtml\Serializer\SerializerNode;
use Xml;
@ -332,9 +330,8 @@ class Linker {
) {
$title = Title::newFromLinkTarget( $title );
$res = null;
$dummy = null;
$hookRunner = new HookRunner( MediaWikiServices::getInstance()->getHookContainer() );
if ( !$hookRunner->onImageBeforeProduceHTML( $dummy, $title,
if ( !$hookRunner->onImageBeforeProduceHTML( null, $title,
// @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
$file, $frameParams, $handlerParams, $time, $res,
// @phan-suppress-next-line PhanTypeMismatchArgument Type mismatch on pass-by-ref args
@ -1571,61 +1568,6 @@ class Linker {
);
}
/**
* This function is called by all recent changes variants, by the page history,
* and by the user contributions list. It is responsible for formatting edit
* summaries. It escapes any HTML in the summary, but adds some CSS to format
* auto-generated comments (from section editing) and formats [[wikilinks]].
*
* This method produces HTML that can require CSS styles in mediawiki.interface.helpers.styles.
*
* @since 1.16.3. $wikiId added in 1.26
* @deprecated since 1.38 use CommentFormatter, hard-deprecated in 1.41
*
* @param string $comment
* @param LinkTarget|null $title LinkTarget object (to generate link to the section in
* autocomment) or null
* @param bool $local Whether section links should refer to local page
* @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to.
* For use with external changes.
*
* @return string HTML
*/
public static function formatComment(
$comment, $title = null, $local = false, $wikiId = null
) {
wfDeprecated( __METHOD__, '1.41' );
$formatter = MediaWikiServices::getInstance()->getCommentFormatter();
return $formatter->format( $comment, $title, $local, $wikiId );
}
/**
* Formats wiki links and media links in text; all other wiki formatting
* is ignored
*
* @since 1.16.3. $wikiId added in 1.26
* @deprecated since 1.38 use CommentFormatter, hard-deprecated in 1.41
*
* @param string $comment Text to format links in. WARNING! Since the output of this
* function is html, $comment must be sanitized for use as html. You probably want
* to pass $comment through Sanitizer::escapeHtmlAllowEntities() before calling
* this function.
* @param LinkTarget|null $title An optional LinkTarget object used to links to sections
* @param bool $local Whether section links should refer to local page
* @param string|null $wikiId Id of the wiki to link to (if not the local wiki),
* as used by WikiMap.
*
* @return string HTML
* @return-taint onlysafefor_html
*/
public static function formatLinksInComment(
$comment, $title = null, $local = false, $wikiId = null
) {
wfDeprecated( __METHOD__, '1.41' );
$formatter = MediaWikiServices::getInstance()->getCommentFormatter();
return $formatter->formatLinksUnsafe( $comment, $title, $local, $wikiId );
}
/**
* @param LinkTarget|null $contextTitle
* @param string $target
@ -1710,60 +1652,6 @@ class Linker {
return $ret;
}
/**
* Wrap a comment in standard punctuation and formatting if
* it's non-empty, otherwise return empty string.
*
* This method produces HTML that requires CSS styles in mediawiki.interface.helpers.styles.
*
* @since 1.16.3. $wikiId added in 1.26
* @deprecated since 1.38 use CommentFormatter, hard-deprecated in 1.41
*
* @param string $comment
* @param LinkTarget|null $title LinkTarget object (to generate link to section in autocomment)
* or null
* @param bool $local Whether section links should refer to local page
* @param string|null $wikiId Id (as used by WikiMap) of the wiki to generate links to.
* For use with external changes.
* @param bool $useParentheses Whether the comment is wrapped in parentheses
*
* @return string
*/
public static function commentBlock(
$comment, $title = null, $local = false, $wikiId = null, $useParentheses = true
) {
wfDeprecated( __METHOD__, '1.41' );
return MediaWikiServices::getInstance()->getCommentFormatter()
->formatBlock( $comment, $title, $local, $wikiId, $useParentheses );
}
/**
* Wrap and format the given revision's comment block, if the current
* user is allowed to view it.
*
* This method produces HTML that requires CSS styles in mediawiki.interface.helpers.styles.
*
* @since 1.16.3
* @deprecated since 1.38 use CommentFormatter, hard-deprecated in 1.41
* @param RevisionRecord $revRecord (Switched from the old Revision class to RevisionRecord
* since 1.35)
* @param bool $local Whether section links should refer to local page
* @param bool $isPublic Show only if all users can see it
* @param bool $useParentheses (optional) Wrap comments in parentheses where needed
* @return string HTML fragment
*/
public static function revComment(
RevisionRecord $revRecord,
$local = false,
$isPublic = false,
$useParentheses = true
) {
wfDeprecated( __METHOD__, '1.41' );
$authority = RequestContext::getMain()->getAuthority();
$formatter = MediaWikiServices::getInstance()->getCommentFormatter();
return $formatter->formatRevision( $revRecord, $authority, $local, $isPublic, $useParentheses );
}
/**
* @since 1.16.3
* @param int $size
@ -1778,201 +1666,6 @@ class Linker {
return "<span class=\"history-size mw-diff-bytes\" data-mw-bytes=\"$size\">$stxt</span>";
}
/**
* Add another level to the Table of Contents
*
* @deprecated since 1.42
* @since 1.16.3
* @return string
*/
public static function tocIndent() {
wfDeprecated( __METHOD__, '1.42' );
return "\n<ul>\n";
}
/**
* Finish one or more sublevels on the Table of Contents
*
* @deprecated since 1.42
* @since 1.16.3
* @param int $level
* @return string
*/
public static function tocUnindent( $level ) {
wfDeprecated( __METHOD__, '1.42' );
return "</li>\n" . str_repeat( "</ul>\n</li>\n", $level > 0 ? $level : 0 );
}
/**
* parameter level defines if we are on an indentation level
*
* @deprecated since 1.42
* @since 1.16.3
* @param string $linkAnchor Identifier
* @param string $tocline Properly escaped HTML
* @param string $tocnumber Unescaped text
* @param int $level
* @param string|false $sectionIndex
* @return string
*/
public static function tocLine( $linkAnchor, $tocline, $tocnumber, $level, $sectionIndex = false ) {
wfDeprecated( __METHOD__, '1.42' );
$classes = "toclevel-$level";
// Parser.php used to suppress tocLine by setting $sectionindex to false.
// In those circumstances, we can now encounter '' or a "T-" prefixed index
// for when the section comes from templates.
if ( $sectionIndex !== false && $sectionIndex !== '' && !str_starts_with( $sectionIndex, "T-" ) ) {
$classes .= " tocsection-$sectionIndex";
}
// <li class="$classes"><a href="#$linkAnchor"><span class="tocnumber">
// $tocnumber</span> <span class="toctext">$tocline</span></a>
return Html::openElement( 'li', [ 'class' => $classes ] )
. Html::rawElement( 'a',
[ 'href' => "#$linkAnchor" ],
Html::element( 'span', [ 'class' => 'tocnumber' ], $tocnumber )
. ' '
. Html::rawElement( 'span', [ 'class' => 'toctext' ], $tocline )
);
}
/**
* End a Table Of Contents line.
* tocUnindent() will be used instead if we're ending a line below
* the new level.
* @deprecated since 1.42
* @since 1.16.3
* @return string
*/
public static function tocLineEnd() {
wfDeprecated( __METHOD__, '1.42' );
return "</li>\n";
}
/**
* Wraps the TOC in a div with ARIA navigation role and provides the hide/collapse JavaScript.
*
* @deprecated since 1.42
* @since 1.16.3
* @param string $toc Html of the Table Of Contents
* @param Language|null $lang Language for the toc title, defaults to user language
* @return string Full html of the TOC
*/
public static function tocList( $toc, Language $lang = null ) {
wfDeprecated( __METHOD__, '1.42' );
$lang ??= RequestContext::getMain()->getLanguage();
$title = wfMessage( 'toc' )->inLanguage( $lang )->escaped();
return '<div id="toc" class="toc" role="navigation" aria-labelledby="mw-toc-heading">'
. Html::element( 'input', [
'type' => 'checkbox',
'role' => 'button',
'id' => 'toctogglecheckbox',
'class' => 'toctogglecheckbox',
'style' => 'display:none',
] )
. Html::openElement( 'div', [
'class' => 'toctitle',
'lang' => $lang->getHtmlCode(),
'dir' => $lang->getDir(),
] )
. '<h2 id="mw-toc-heading">' . $title . '</h2>'
. '<span class="toctogglespan">'
. Html::label( '', 'toctogglecheckbox', [
'class' => 'toctogglelabel',
] )
. '</span>'
. '</div>'
. $toc
. "</ul>\n</div>\n";
}
/**
* @internal For use by ParserOutput and API modules
* Generate a table of contents from a section tree.
*
* @deprecated since 1.42
* @since 1.16.3. $lang added in 1.17. Parameters changed in 1.40.
* @param ?TOCData $tocData Return value of ParserOutput::getSections()
* @param Language|null $lang Language for the toc title, defaults to user language
* @param array $options
* - 'maxtoclevel' Max TOC level to generate
* @return string HTML fragment
*/
public static function generateTOC( ?TOCData $tocData, Language $lang = null, array $options = [] ): string {
wfDeprecated( __METHOD__, '1.42' );
$toc = '';
$lastLevel = 0;
$maxTocLevel = $options['maxtoclevel'] ?? null;
if ( $maxTocLevel === null ) {
// Use wiki-configured default
$services = MediaWikiServices::getInstance();
$config = $services->getMainConfig();
$maxTocLevel = $config->get( MainConfigNames::MaxTocLevel );
}
foreach ( ( $tocData ? $tocData->getSections() : [] ) as $section ) {
$tocLevel = $section->tocLevel;
if ( $tocLevel < $maxTocLevel ) {
if ( $tocLevel > $lastLevel ) {
$toc .= self::tocIndent();
} elseif ( $tocLevel < $lastLevel ) {
if ( $lastLevel < $maxTocLevel ) {
$toc .= self::tocUnindent(
$lastLevel - $tocLevel );
} else {
$toc .= self::tocLineEnd();
}
} else {
$toc .= self::tocLineEnd();
}
$toc .= self::tocLine( $section->linkAnchor,
$section->line, $section->number,
$tocLevel, $section->index );
$lastLevel = $tocLevel;
}
}
if ( $lastLevel < $maxTocLevel && $lastLevel > 0 ) {
$toc .= self::tocUnindent( $lastLevel - 1 );
}
return self::tocList( $toc, $lang );
}
/**
* Create a headline for content
*
* @deprecated since 1.42
* @since 1.16.3
* @param int $level The level of the headline (1-6)
* @param string $attribs Any attributes for the headline, starting with
* a space and ending with '>'
* This *must* be at least '>' for no attribs
* @param string $anchor The anchor to give the headline (the bit after the #)
* @param string $html HTML for the text of the header
* @param string $link HTML to add for the section edit link
* @param string|false $fallbackAnchor A second, optional anchor to give for
* backward compatibility (false to omit)
*
* @return string HTML headline
*/
public static function makeHeadline( $level, $attribs, $anchor, $html,
$link, $fallbackAnchor = false
) {
wfDeprecated( __METHOD__, '1.42' );
$anchorEscaped = htmlspecialchars( $anchor, ENT_COMPAT );
$fallback = '';
if ( $fallbackAnchor !== false && $fallbackAnchor !== $anchor ) {
$fallbackAnchor = htmlspecialchars( $fallbackAnchor, ENT_COMPAT );
$fallback = "<span id=\"$fallbackAnchor\"></span>";
}
return "<h$level$attribs"
. "$fallback<span class=\"mw-headline\" id=\"$anchorEscaped\">$html</span>"
. $link
. "</h$level>";
}
/**
* Split a link trail, return the "inside" portion and the remainder of the trail
* as a two-element array

View file

@ -1,11 +1,9 @@
<?php
use MediaWiki\CommentStore\CommentStoreComment;
use MediaWiki\Config\SiteConfiguration;
use MediaWiki\Context\RequestContext;
use MediaWiki\Linker\Linker;
use MediaWiki\MainConfigNames;
use MediaWiki\Revision\MutableRevisionRecord;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Revision\SlotRecord;
use MediaWiki\SpecialPage\SpecialPage;
@ -257,258 +255,6 @@ class LinkerTest extends MediaWikiLangTestCase {
];
}
/**
* @dataProvider provideCasesForFormatComment
* @covers \MediaWiki\Linker\Linker::formatComment
* @covers \MediaWiki\Linker\Linker::formatLinksInComment
* @covers \MediaWiki\CommentFormatter\CommentParser
* @covers \MediaWiki\CommentFormatter\CommentFormatter
*/
public function testFormatComment(
$expected, $comment, $title = false, $local = false, $wikiId = null
) {
$this->hideDeprecated( 'MediaWiki\Linker\Linker::formatComment' );
$conf = new SiteConfiguration();
$conf->settings = [
'wgServer' => [
'foowiki' => '//foo.example.org',
],
'wgArticlePath' => [
'foowiki' => '/foo/$1',
],
];
$conf->suffixes = [ 'wiki' ];
$this->setMwGlobals( 'wgConf', $conf );
$this->overrideConfigValues( [
MainConfigNames::Script => '/w/index.php',
MainConfigNames::ArticlePath => '/wiki/$1',
MainConfigNames::CapitalLinks => true,
// TODO: update tests when the default changes
MainConfigNames::FragmentMode => [ 'legacy' ],
] );
if ( $title === false ) {
// We need a page title that exists
$title = Title::makeTitle( NS_SPECIAL, 'BlankPage' );
}
$this->assertEquals(
$expected,
Linker::formatComment( $comment, $title, $local, $wikiId )
);
}
public static function provideCasesForFormatComment() {
return [
// Linker::formatComment
[
'a&lt;script&gt;b',
'a<script>b',
],
[
'a—b',
'a&mdash;b',
],
[
"&#039;&#039;&#039;not bolded&#039;&#039;&#039;",
"'''not bolded'''",
],
[
"try &lt;script&gt;evil&lt;/scipt&gt; things",
"try <script>evil</scipt> things",
],
// Linker::formatAutocomments
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a></span></span>',
"/* autocomment */",
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#linkie.3F" title="Special:BlankPage">→‎&#91;[linkie?]]</a></span></span>',
"/* [[linkie?]] */",
],
[
'<span dir="auto"><span class="autocomment">: </span> // Edit via via</span>',
// Regression test for T222857
"/* */ // Edit via via",
],
[
'<span dir="auto"><span class="autocomment">: </span> foobar</span>',
// Regression test for T222857
"/**/ foobar",
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>: </span> post</span>',
"/* autocomment */ post",
],
[
'pre <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a></span></span>',
"pre /* autocomment */",
],
[
'pre <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>: </span> post</span>',
"pre /* autocomment */ post",
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a>: </span> multiple? <span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment2" title="Special:BlankPage">→autocomment2</a></span></span></span>',
"/* autocomment */ multiple? /* autocomment2 */",
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.2F.2A" title="Special:BlankPage">→autocomment containing /*</a>: </span> T70361</span>',
"/* autocomment containing /* */ T70361"
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.22quotes.22" title="Special:BlankPage">→autocomment containing &quot;quotes&quot;</a></span></span>',
"/* autocomment containing \"quotes\" */"
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment_containing_.3Cscript.3Etags.3C.2Fscript.3E" title="Special:BlankPage">→autocomment containing &lt;script&gt;tags&lt;/script&gt;</a></span></span>',
"/* autocomment containing <script>tags</script> */"
],
[
'<span dir="auto"><span class="autocomment"><a href="#autocomment">→autocomment</a></span></span>',
"/* autocomment */",
false, true
],
[
'<span dir="auto"><span class="autocomment">autocomment</span></span>',
"/* autocomment */",
null
],
[
'',
"/* */",
false, true
],
[
'',
"/* */",
null
],
[
'<span dir="auto"><span class="autocomment">[[</span></span>',
"/* [[ */",
false, true
],
[
'<span dir="auto"><span class="autocomment">[[</span></span>',
"/* [[ */",
null
],
[
"foo <span dir=\"auto\"><span class=\"autocomment\"><a href=\"#.23\">→‎&#91;[#_\t_]]</a></span></span>",
"foo /* [[#_\t_]] */",
false, true
],
[
"foo <span dir=\"auto\"><span class=\"autocomment\"><a href=\"#_.09\">#_\t_</a></span></span>",
"foo /* [[#_\t_]] */",
null
],
[
'<span dir="auto"><span class="autocomment"><a href="/wiki/Special:BlankPage#autocomment" title="Special:BlankPage">→autocomment</a></span></span>',
"/* autocomment */",
false, false
],
[
'<span dir="auto"><span class="autocomment"><a class="external" rel="nofollow" href="//foo.example.org/foo/Special:BlankPage#autocomment">→autocomment</a></span></span>',
"/* autocomment */",
false, false, 'foowiki'
],
// Linker::formatLinksInComment
[
'abc <a href="/w/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> def',
"abc [[link]] def",
],
[
'abc <a href="/w/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">text</a> def',
"abc [[link|text]] def",
],
[
'abc <a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a> def',
"abc [[Special:BlankPage|]] def",
],
[
'abc <a href="/w/index.php?title=%C4%84%C5%9B%C5%BC&amp;action=edit&amp;redlink=1" class="new" title="Ąśż (page does not exist)">ąśż</a> def',
"abc [[%C4%85%C5%9B%C5%BC]] def",
],
[
'abc <a href="/wiki/Special:BlankPage#section" title="Special:BlankPage">#section</a> def',
"abc [[#section]] def",
],
[
'abc <a href="/w/index.php?title=/subpage&amp;action=edit&amp;redlink=1" class="new" title="/subpage (page does not exist)">/subpage</a> def',
"abc [[/subpage]] def",
],
[
'abc <a href="/w/index.php?title=%22evil!%22&amp;action=edit&amp;redlink=1" class="new" title="&quot;evil!&quot; (page does not exist)">&quot;evil!&quot;</a> def',
"abc [[\"evil!\"]] def",
],
[
'abc [[&lt;script&gt;very evil&lt;/script&gt;]] def',
"abc [[<script>very evil</script>]] def",
],
[
'abc [[|]] def',
"abc [[|]] def",
],
[
'abc <a href="/w/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">link</a> def',
"abc [[link]] def",
false, false
],
[
'abc <a class="external" rel="nofollow" href="//foo.example.org/foo/Link">link</a> def',
"abc [[link]] def",
false, false, 'foowiki'
],
[
'<a href="/w/index.php?title=Special:Upload&amp;wpDestFile=LinkerTest.jpg" class="new" title="LinkerTest.jpg">Media:LinkerTest.jpg</a>',
'[[Media:LinkerTest.jpg]]'
],
[
'<a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>',
'[[:Special:BlankPage]]'
],
[
'<a href="/w/index.php?title=Link&amp;action=edit&amp;redlink=1" class="new" title="Link (page does not exist)">linktrail</a>...',
'[[link]]trail...'
]
];
// phpcs:enable
}
/**
* @covers \MediaWiki\Linker\Linker::formatLinksInComment
* @covers \MediaWiki\CommentFormatter\CommentParser
* @covers \MediaWiki\CommentFormatter\CommentFormatter
* @dataProvider provideCasesForFormatLinksInComment
*/
public function testFormatLinksInComment( $expected, $input, $wiki ) {
$this->hideDeprecated( 'MediaWiki\Linker\Linker::formatLinksInComment' );
$conf = new SiteConfiguration();
$conf->settings = [
'wgServer' => [
'foowiki' => '//foo.example.org'
],
'wgArticlePath' => [
'foowiki' => '/foo/$1',
],
];
$conf->suffixes = [ 'wiki' ];
$this->setMwGlobals( 'wgConf', $conf );
$this->overrideConfigValues( [
MainConfigNames::Script => '/w/index.php',
MainConfigNames::ArticlePath => '/wiki/$1',
MainConfigNames::CapitalLinks => true,
] );
$this->assertEquals(
$expected,
Linker::formatLinksInComment( $input, Title::newFromText( 'Special:BlankPage' ), false, $wiki )
);
}
/**
* @covers \MediaWiki\Linker\Linker::generateRollback
* @dataProvider provideCasesForRollbackGeneration
@ -575,47 +321,6 @@ class LinkerTest extends MediaWikiLangTestCase {
];
}
public static function provideCasesForFormatLinksInComment() {
return [
[
'foo bar <a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>',
'foo bar [[Special:BlankPage]]',
null,
],
[
'<a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>',
'[[ :Special:BlankPage]]',
null,
],
[
'<a href="/wiki/Special:BlankPage" title="Special:BlankPage">:Special:BlankPage</a>',
'[[::Special:BlankPage]]',
null,
],
[
'[[Foo<a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>',
'[[Foo[[Special:BlankPage]]',
null,
],
[
'<a class="external" rel="nofollow" href="//foo.example.org/foo/Foo%27bar">Foo\'bar</a>',
"[[Foo'bar]]",
'foowiki',
],
[
'foo bar <a class="external" rel="nofollow" href="//foo.example.org/foo/Special:BlankPage">Special:BlankPage</a>',
'foo bar [[Special:BlankPage]]',
'foowiki',
],
[
'foo bar <a class="external" rel="nofollow" href="//foo.example.org/foo/File:Example">Image:Example</a>',
'foo bar [[Image:Example]]',
'foowiki',
],
];
// phpcs:enable
}
public static function provideTooltipAndAccesskeyAttribs() {
return [
'Watch no expiry' => [
@ -653,146 +358,6 @@ class LinkerTest extends MediaWikiLangTestCase {
$this->assertEquals( $expected, $result );
}
/**
* @covers \MediaWiki\Linker\Linker::commentBlock
* @dataProvider provideCommentBlock
*/
public function testCommentBlock(
$expected, $comment, $title = null, $local = false, $wikiId = null, $useParentheses = true
) {
$this->hideDeprecated( 'MediaWiki\Linker\Linker::commentBlock' );
$conf = new SiteConfiguration();
$conf->settings = [
'wgServer' => [
'foowiki' => '//foo.example.org'
],
'wgArticlePath' => [
'foowiki' => '/foo/$1',
],
];
$conf->suffixes = [ 'wiki' ];
$this->setMwGlobals( 'wgConf', $conf );
$this->overrideConfigValues( [
MainConfigNames::Script => '/w/index.php',
MainConfigNames::ArticlePath => '/wiki/$1',
MainConfigNames::CapitalLinks => true,
] );
$this->assertEquals( $expected, Linker::commentBlock( $comment, $title, $local, $wikiId, $useParentheses ) );
}
public static function provideCommentBlock() {
return [
[
' <span class="comment">(Test)</span>',
'Test'
],
'Empty comment' => [ '', '' ],
'Backwards compatibility empty comment' => [ '', '*' ],
'No parenthesis' => [
' <span class="comment comment--without-parentheses">Test</span>',
'Test',
null, false, null,
false
],
'Page exist link' => [
' <span class="comment">(<a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>)</span>',
'[[Special:BlankPage]]'
],
'Page does not exist link' => [
' <span class="comment">(<a href="/w/index.php?title=Test&amp;action=edit&amp;redlink=1" class="new" title="Test (page does not exist)">Test</a>)</span>',
'[[Test]]'
],
'Link to other page section' => [
' <span class="comment">(<a href="/wiki/Special:BlankPage#Test" title="Special:BlankPage">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' )
],
'$local is true' => [
' <span class="comment">(<a href="#Test">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' ),
true
],
'Given wikiId' => [
' <span class="comment">(<a class="external" rel="nofollow" href="//foo.example.org/foo/Test">Test</a>)</span>',
'[[Test]]',
null, false,
'foowiki'
],
'Section link to external wiki page' => [
' <span class="comment">(<a class="external" rel="nofollow" href="//foo.example.org/foo/Special:BlankPage#Test">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' ),
false,
'foowiki'
],
];
}
/**
* @covers \MediaWiki\Linker\Linker::revComment
* @dataProvider provideRevComment
*/
public function testRevComment(
string $expected,
bool $isSysop = false,
int $visibility = 0,
bool $local = false,
bool $isPublic = false,
bool $useParentheses = true,
?string $comment = 'Some comment!'
) {
$this->hideDeprecated( 'MediaWiki\Linker\Linker::revComment' );
$pageData = $this->insertPage( 'RevCommentTestPage' );
$revisionRecord = new MutableRevisionRecord( $pageData['title'] );
if ( $comment ) {
$revisionRecord->setComment( CommentStoreComment::newUnsavedComment( $comment ) );
}
$revisionRecord->setVisibility( $visibility );
$context = RequestContext::getMain();
$user = $isSysop ? $this->getTestSysop()->getUser() : $this->getTestUser()->getUser();
$context->setUser( $user );
$this->assertEquals( $expected, Linker::revComment( $revisionRecord, $local, $isPublic, $useParentheses ) );
}
public static function provideRevComment() {
return [
'Should be visible' => [
' <span class="comment">(Some comment!)</span>'
],
'Should not have parenthesis' => [
' <span class="comment comment--without-parentheses">Some comment!</span>',
false, 0, false, false,
false
],
'Should be empty' => [
'',
false, 0, false, false, true,
null
],
'Deleted comment should not be visible to normal users' => [
' <span class="history-deleted comment"> <span class="comment">(edit summary removed)</span></span>',
false,
RevisionRecord::DELETED_COMMENT
],
'Deleted comment should not be visible to normal users even if public' => [
' <span class="history-deleted comment"> <span class="comment">(edit summary removed)</span></span>',
false,
RevisionRecord::DELETED_COMMENT,
false,
true
],
'Deleted comment should be visible to sysops' => [
' <span class="history-deleted comment"> <span class="comment">(Some comment!)</span></span>',
true,
RevisionRecord::DELETED_COMMENT
],
];
}
/**
* @covers \MediaWiki\Linker\Linker::specialLink
* @dataProvider provideSpecialLink

View file

@ -4,10 +4,16 @@ namespace MediaWiki\Tests\Integration\CommentFormatter;
use LinkCacheTestTrait;
use MediaWiki\Cache\LinkBatchFactory;
use MediaWiki\CommentFormatter\CommentFormatter;
use MediaWiki\CommentFormatter\CommentParser;
use MediaWiki\CommentFormatter\CommentParserFactory;
use MediaWiki\CommentStore\CommentStoreComment;
use MediaWiki\Config\SiteConfiguration;
use MediaWiki\Context\RequestContext;
use MediaWiki\Logger\LoggerFactory;
use MediaWiki\MainConfigNames;
use MediaWiki\Revision\MutableRevisionRecord;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Tests\Unit\DummyServicesTrait;
use MediaWiki\Title\Title;
use RepoGroup;
@ -45,6 +51,14 @@ class CommentParserTest extends \MediaWikiIntegrationTestCase {
);
}
private function getFormatter() {
$parserFactory = $this->createNoOpMock( CommentParserFactory::class, [ 'create' ] );
$parserFactory->method( 'create' )->willReturnCallback( function () {
return $this->getParser();
} );
return new CommentFormatter( $parserFactory );
}
/**
* @before
*/
@ -274,8 +288,6 @@ class CommentParserTest extends \MediaWikiIntegrationTestCase {
}
/**
* Adapted from LinkerTest
*
* @dataProvider provideFormatComment
*/
public function testFormatComment(
@ -322,9 +334,6 @@ class CommentParserTest extends \MediaWikiIntegrationTestCase {
$this->assertEquals( $expected, $result );
}
/**
* Adapted from LinkerTest
*/
public static function provideFormatLinksInComment() {
return [
[
@ -367,7 +376,88 @@ class CommentParserTest extends \MediaWikiIntegrationTestCase {
}
/**
* Adapted from LinkerTest. Note that we test the new HTML escaping variant.
* @covers \MediaWiki\CommentFormatter\CommentFormatter
* @covers \MediaWiki\CommentFormatter\CommentParser
* @dataProvider provideCommentBlock
*/
public function testCommentBlock(
$expected, $comment, $title = null, $local = false, $wikiId = null, $useParentheses = true
) {
$conf = new SiteConfiguration();
$conf->settings = [
'wgServer' => [
'foowiki' => '//foo.example.org'
],
'wgArticlePath' => [
'foowiki' => '/foo/$1',
],
];
$conf->suffixes = [ 'wiki' ];
$this->setMwGlobals( 'wgConf', $conf );
$this->overrideConfigValues( [
MainConfigNames::Script => '/w/index.php',
MainConfigNames::ArticlePath => '/wiki/$1',
MainConfigNames::CapitalLinks => true,
] );
$formatter = $this->getFormatter();
$this->assertEquals(
$expected,
$formatter->formatBlock( $comment, $title, $local, $wikiId, $useParentheses )
);
}
public static function provideCommentBlock() {
return [
[
' <span class="comment">(Test)</span>',
'Test'
],
'Empty comment' => [ '', '' ],
'Backwards compatibility empty comment' => [ '', '*' ],
'No parenthesis' => [
' <span class="comment comment--without-parentheses">Test</span>',
'Test',
null, false, null,
false
],
'Page exist link' => [
' <span class="comment">(<a href="/wiki/Special:BlankPage" title="Special:BlankPage">Special:BlankPage</a>)</span>',
'[[Special:BlankPage]]'
],
'Page does not exist link' => [
' <span class="comment">(<a href="/w/index.php?title=Test&amp;action=edit&amp;redlink=1" class="new" title="Test (page does not exist)">Test</a>)</span>',
'[[Test]]'
],
'Link to other page section' => [
' <span class="comment">(<a href="/wiki/Special:BlankPage#Test" title="Special:BlankPage">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' )
],
'$local is true' => [
' <span class="comment">(<a href="#Test">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' ),
true
],
'Given wikiId' => [
' <span class="comment">(<a class="external" rel="nofollow" href="//foo.example.org/foo/Test">Test</a>)</span>',
'[[Test]]',
null, false,
'foowiki'
],
'Section link to external wiki page' => [
' <span class="comment">(<a class="external" rel="nofollow" href="//foo.example.org/foo/Special:BlankPage#Test">#Test</a>)</span>',
'[[#Test]]',
Title::makeTitle( NS_SPECIAL, 'BlankPage' ),
false,
'foowiki'
],
];
}
/**
* Note that we test the new HTML escaping variant.
*
* @dataProvider provideFormatLinksInComment
*/
@ -474,4 +564,67 @@ class CommentParserTest extends \MediaWikiIntegrationTestCase {
);
}
/**
* @dataProvider provideRevComment
*/
public function testRevComment(
string $expected,
bool $isSysop = false,
int $visibility = 0,
bool $local = false,
bool $isPublic = false,
bool $useParentheses = true,
?string $comment = 'Some comment!'
) {
$pageData = $this->insertPage( 'RevCommentTestPage' );
$revisionRecord = new MutableRevisionRecord( $pageData['title'] );
if ( $comment ) {
$revisionRecord->setComment( CommentStoreComment::newUnsavedComment( $comment ) );
}
$revisionRecord->setVisibility( $visibility );
$context = RequestContext::getMain();
$user = $isSysop ? $this->getTestSysop()->getUser() : $this->getTestUser()->getUser();
$context->setUser( $user );
$formatter = $this->getFormatter();
$authority = RequestContext::getMain()->getAuthority();
$this->assertEquals( $expected, $formatter->formatRevision( $revisionRecord, $authority, $local, $isPublic, $useParentheses ) );
}
public static function provideRevComment() {
return [
'Should be visible' => [
' <span class="comment">(Some comment!)</span>'
],
'Should not have parenthesis' => [
' <span class="comment comment--without-parentheses">Some comment!</span>',
false, 0, false, false,
false
],
'Should be empty' => [
'',
false, 0, false, false, true,
null
],
'Deleted comment should not be visible to normal users' => [
' <span class="history-deleted comment"> <span class="comment">(edit summary removed)</span></span>',
false,
RevisionRecord::DELETED_COMMENT
],
'Deleted comment should not be visible to normal users even if public' => [
' <span class="history-deleted comment"> <span class="comment">(edit summary removed)</span></span>',
false,
RevisionRecord::DELETED_COMMENT,
false,
true
],
'Deleted comment should be visible to sysops' => [
' <span class="history-deleted comment"> <span class="comment">(Some comment!)</span></span>',
true,
RevisionRecord::DELETED_COMMENT
],
];
}
}