Add new core tags
Add tags to types of edits that get automatic edit summaries: - Making a page a redirect - Changing redirect target - Changing an existing redirect into a non-redirect - Blanking of the page - Removing nearly all (more than 90%) content - Rolling back an edit Bug: T167656 Bug: T73236 Change-Id: Ie7f637fcec5ee659c1086e28e8ba21f470c45160
This commit is contained in:
parent
1ec7e520d3
commit
62713be990
10 changed files with 506 additions and 68 deletions
|
|
@ -6961,6 +6961,29 @@ $wgAllowCategorizedRecentChanges = false;
|
|||
*/
|
||||
$wgUseTagFilter = true;
|
||||
|
||||
/**
|
||||
* List of core tags to enable. Available tags are:
|
||||
* - 'mw-contentmodelchange': Edit changes content model of a page
|
||||
* - 'mw-new-redirect': Edit makes new redirect page (new page or by changing content page)
|
||||
* - 'mw-removed-redirect': Edit changes an existing redirect into a non-redirect
|
||||
* - 'mw-changed-redirect-target': Edit changes redirect target
|
||||
* - 'mw-blank': Edit completely blanks the page
|
||||
* - 'mw-replace': Edit removes more than 90% of the content
|
||||
* - 'mw-rollback': Edit is a rollback, made through the rollback link or rollback API
|
||||
*
|
||||
* @var array
|
||||
* @since 1.31
|
||||
*/
|
||||
$wgSoftwareTags = [
|
||||
'mw-contentmodelchange' => true,
|
||||
'mw-new-redirect' => true,
|
||||
'mw-removed-redirect' => true,
|
||||
'mw-changed-redirect-target' => true,
|
||||
'mw-blank' => true,
|
||||
'mw-replace' => true,
|
||||
'mw-rollback' => true
|
||||
];
|
||||
|
||||
/**
|
||||
* If set to an integer, pages that are watched by this many users or more
|
||||
* will not require the unwatchedpages permission to view the number of
|
||||
|
|
|
|||
|
|
@ -32,10 +32,44 @@ class ChangeTags {
|
|||
*/
|
||||
const MAX_DELETE_USES = 5000;
|
||||
|
||||
private static $definedSoftwareTags = [
|
||||
'mw-contentmodelchange',
|
||||
'mw-new-redirect',
|
||||
'mw-removed-redirect',
|
||||
'mw-changed-redirect-target',
|
||||
'mw-blank',
|
||||
'mw-replace',
|
||||
'mw-rollback'
|
||||
];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* Loads defined core tags, checks for invalid types (if not array),
|
||||
* and filters for supported and enabled (if $all is false) tags only.
|
||||
*
|
||||
* @param bool $all If true, return all valid defined tags. Otherwise, return only enabled ones.
|
||||
* @return array Array of all defined/enabled tags.
|
||||
*/
|
||||
private static $coreTags = [ 'mw-contentmodelchange' ];
|
||||
public static function getSoftwareTags( $all = false ) {
|
||||
global $wgSoftwareTags;
|
||||
$softwareTags = [];
|
||||
|
||||
if ( !is_array( $wgSoftwareTags ) ) {
|
||||
wfWarn( 'wgSoftwareTags should be associative array of enabled tags.
|
||||
Please refer to documentation for the list of tags you can enable' );
|
||||
return $softwareTags;
|
||||
}
|
||||
|
||||
$availableSoftwareTags = !$all ?
|
||||
array_keys( array_filter( $wgSoftwareTags ) ) :
|
||||
array_keys( $wgSoftwareTags );
|
||||
|
||||
$softwareTags = array_intersect(
|
||||
$availableSoftwareTags,
|
||||
self::$definedSoftwareTags
|
||||
);
|
||||
|
||||
return $softwareTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates HTML for the given tags
|
||||
|
|
@ -1210,7 +1244,7 @@ class ChangeTags {
|
|||
*/
|
||||
public static function listSoftwareActivatedTags() {
|
||||
// core active tags
|
||||
$tags = self::$coreTags;
|
||||
$tags = self::getSoftwareTags();
|
||||
if ( !Hooks::isRegistered( 'ChangeTagsListActive' ) ) {
|
||||
return $tags;
|
||||
}
|
||||
|
|
@ -1301,7 +1335,7 @@ class ChangeTags {
|
|||
*/
|
||||
public static function listSoftwareDefinedTags() {
|
||||
// core defined tags
|
||||
$tags = self::$coreTags;
|
||||
$tags = self::getSoftwareTags( true );
|
||||
if ( !Hooks::isRegistered( 'ListDefinedTags' ) ) {
|
||||
return $tags;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -754,82 +754,190 @@ abstract class ContentHandler {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type of change if one exists for the given edit.
|
||||
*
|
||||
* @since 1.31
|
||||
*
|
||||
* @param Content|null $oldContent The previous text of the page.
|
||||
* @param Content|null $newContent The submitted text of the page.
|
||||
* @param int $flags Bit mask: a bit mask of flags submitted for the edit.
|
||||
*
|
||||
* @return string|null String key representing type of change, or null.
|
||||
*/
|
||||
private function getChangeType(
|
||||
Content $oldContent = null,
|
||||
Content $newContent = null,
|
||||
$flags = 0
|
||||
) {
|
||||
$oldTarget = $oldContent !== null ? $oldContent->getRedirectTarget() : null;
|
||||
$newTarget = $newContent !== null ? $newContent->getRedirectTarget() : null;
|
||||
|
||||
// We check for the type of change in the given edit, and return string key accordingly
|
||||
|
||||
// Blanking of a page
|
||||
if ( $oldContent && $oldContent->getSize() > 0 &&
|
||||
$newContent && $newContent->getSize() === 0
|
||||
) {
|
||||
return 'blank';
|
||||
}
|
||||
|
||||
// Redirects
|
||||
if ( $newTarget ) {
|
||||
if ( !$oldTarget ) {
|
||||
// New redirect page (by creating new page or by changing content page)
|
||||
return 'new-redirect';
|
||||
} elseif ( !$newTarget->equals( $oldTarget ) ||
|
||||
$oldTarget->getFragment() !== $newTarget->getFragment()
|
||||
) {
|
||||
// Redirect target changed
|
||||
return 'changed-redirect-target';
|
||||
}
|
||||
} elseif ( $oldTarget ) {
|
||||
// Changing an existing redirect into a non-redirect
|
||||
return 'removed-redirect';
|
||||
}
|
||||
|
||||
// New page created
|
||||
if ( $flags & EDIT_NEW && $newContent && $newContent->getSize() > 0 ) {
|
||||
return 'newpage';
|
||||
}
|
||||
|
||||
// New blank page
|
||||
if ( $flags & EDIT_NEW && $newContent && $newContent->getSize() === 0 ) {
|
||||
return 'newblank';
|
||||
}
|
||||
|
||||
// Removing more than 90% of the page
|
||||
if ( $oldContent && $newContent && $oldContent->getSize() > 10 * $newContent->getSize() ) {
|
||||
return 'replace';
|
||||
}
|
||||
|
||||
// Content model changed
|
||||
if ( $oldContent && $newContent && $oldContent->getModel() !== $newContent->getModel() ) {
|
||||
return 'contentmodelchange';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an applicable auto-summary if one exists for the given edit.
|
||||
*
|
||||
* @since 1.21
|
||||
*
|
||||
* @param Content $oldContent The previous text of the page.
|
||||
* @param Content $newContent The submitted text of the page.
|
||||
* @param Content|null $oldContent The previous text of the page.
|
||||
* @param Content|null $newContent The submitted text of the page.
|
||||
* @param int $flags Bit mask: a bit mask of flags submitted for the edit.
|
||||
*
|
||||
* @return string An appropriate auto-summary, or an empty string.
|
||||
*/
|
||||
public function getAutosummary( Content $oldContent = null, Content $newContent = null,
|
||||
$flags ) {
|
||||
public function getAutosummary(
|
||||
Content $oldContent = null,
|
||||
Content $newContent = null,
|
||||
$flags = 0
|
||||
) {
|
||||
$changeType = $this->getChangeType( $oldContent, $newContent, $flags );
|
||||
|
||||
// There's no applicable auto-summary for our case, so our auto-summary is empty.
|
||||
if ( !$changeType ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Decide what kind of auto-summary is needed.
|
||||
|
||||
// Redirect auto-summaries
|
||||
|
||||
/**
|
||||
* @var $ot Title
|
||||
* @var $rt Title
|
||||
*/
|
||||
|
||||
$ot = !is_null( $oldContent ) ? $oldContent->getRedirectTarget() : null;
|
||||
$rt = !is_null( $newContent ) ? $newContent->getRedirectTarget() : null;
|
||||
|
||||
if ( is_object( $rt ) ) {
|
||||
if ( !is_object( $ot )
|
||||
|| !$rt->equals( $ot )
|
||||
|| $ot->getFragment() != $rt->getFragment()
|
||||
) {
|
||||
switch ( $changeType ) {
|
||||
case 'new-redirect':
|
||||
$newTarget = $newContent->getRedirectTarget();
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
250
|
||||
- strlen( wfMessage( 'autoredircomment' )->inContentLanguage()->text() )
|
||||
- strlen( $rt->getFullText() ) );
|
||||
- strlen( $newTarget->getFullText() )
|
||||
);
|
||||
|
||||
return wfMessage( 'autoredircomment', $rt->getFullText() )
|
||||
return wfMessage( 'autoredircomment', $newTarget->getFullText() )
|
||||
->rawParams( $truncatedtext )->inContentLanguage()->text();
|
||||
}
|
||||
case 'changed-redirect-target':
|
||||
$oldTarget = $oldContent->getRedirectTarget();
|
||||
$newTarget = $newContent->getRedirectTarget();
|
||||
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
250
|
||||
- strlen( wfMessage( 'autosumm-changed-redirect-target' )
|
||||
->inContentLanguage()->text() )
|
||||
- strlen( $oldTarget->getFullText() )
|
||||
- strlen( $newTarget->getFullText() )
|
||||
);
|
||||
|
||||
return wfMessage( 'autosumm-changed-redirect-target',
|
||||
$oldTarget->getFullText(),
|
||||
$newTarget->getFullText() )
|
||||
->rawParams( $truncatedtext )->inContentLanguage()->text();
|
||||
case 'removed-redirect':
|
||||
$oldTarget = $oldContent->getRedirectTarget();
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
250
|
||||
- strlen( wfMessage( 'autosumm-removed-redirect' )
|
||||
->inContentLanguage()->text() )
|
||||
- strlen( $oldTarget->getFullText() ) );
|
||||
|
||||
return wfMessage( 'autosumm-removed-redirect', $oldTarget->getFullText() )
|
||||
->rawParams( $truncatedtext )->inContentLanguage()->text();
|
||||
case 'newpage':
|
||||
// If they're making a new article, give its text, truncated, in the summary.
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
case 'blank':
|
||||
return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
|
||||
case 'replace':
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
case 'newblank':
|
||||
return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an applicable tag if one exists for the given edit or return null.
|
||||
*
|
||||
* @since 1.31
|
||||
*
|
||||
* @param Content|null $oldContent The previous text of the page.
|
||||
* @param Content|null $newContent The submitted text of the page.
|
||||
* @param int $flags Bit mask: a bit mask of flags submitted for the edit.
|
||||
*
|
||||
* @return string|null An appropriate tag, or null.
|
||||
*/
|
||||
public function getChangeTag(
|
||||
Content $oldContent = null,
|
||||
Content $newContent = null,
|
||||
$flags = 0
|
||||
) {
|
||||
$changeType = $this->getChangeType( $oldContent, $newContent, $flags );
|
||||
|
||||
// There's no applicable tag for this change.
|
||||
if ( !$changeType ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// New page auto-summaries
|
||||
if ( $flags & EDIT_NEW && $newContent->getSize() > 0 ) {
|
||||
// If they're making a new article, give its text, truncated, in
|
||||
// the summary.
|
||||
// Core tags use the same keys as ones returned from $this->getChangeType()
|
||||
// but prefixed with pseudo namespace 'mw-', so we add the prefix before checking
|
||||
// if this type of change should be tagged
|
||||
$tag = 'mw-' . $changeType;
|
||||
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMessage( 'autosumm-new' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMessage( 'autosumm-new' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
// Not all change types are tagged, so we check against the list of defined tags.
|
||||
if ( in_array( $tag, ChangeTags::getSoftwareTags() ) ) {
|
||||
return $tag;
|
||||
}
|
||||
|
||||
// Blanking auto-summaries
|
||||
if ( !empty( $oldContent ) && $oldContent->getSize() > 0 && $newContent->getSize() == 0 ) {
|
||||
return wfMessage( 'autosumm-blank' )->inContentLanguage()->text();
|
||||
} elseif ( !empty( $oldContent )
|
||||
&& $oldContent->getSize() > 10 * $newContent->getSize()
|
||||
&& $newContent->getSize() < 500
|
||||
) {
|
||||
// Removing more than 90% of the article
|
||||
|
||||
$truncatedtext = $newContent->getTextForSummary(
|
||||
200 - strlen( wfMessage( 'autosumm-replace' )->inContentLanguage()->text() ) );
|
||||
|
||||
return wfMessage( 'autosumm-replace' )->rawParams( $truncatedtext )
|
||||
->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
// New blank article auto-summary
|
||||
if ( $flags & EDIT_NEW && $newContent->isEmpty() ) {
|
||||
return wfMessage( 'autosumm-newblank' )->inContentLanguage()->text();
|
||||
}
|
||||
|
||||
// If we reach this point, there's no applicable auto-summary for our
|
||||
// case, so our auto-summary is empty.
|
||||
return '';
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1617,13 +1617,15 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
$old_revision = $this->getRevision(); // current revision
|
||||
$old_content = $this->getContent( Revision::RAW ); // current revision's content
|
||||
|
||||
if ( $old_content && $old_content->getModel() !== $content->getModel() ) {
|
||||
$tags[] = 'mw-contentmodelchange';
|
||||
$handler = $content->getContentHandler();
|
||||
$tag = $handler->getChangeTag( $old_content, $content, $flags );
|
||||
// If there is no applicable tag, null is returned, so we need to check
|
||||
if ( $tag ) {
|
||||
$tags[] = $tag;
|
||||
}
|
||||
|
||||
// Provide autosummaries if one is not provided and autosummaries are enabled
|
||||
// Provide autosummaries if summary is not provided and autosummaries are enabled
|
||||
if ( $wgUseAutomaticEditSummaries && ( $flags & EDIT_AUTOSUMMARY ) && $summary == '' ) {
|
||||
$handler = $content->getContentHandler();
|
||||
$summary = $handler->getAutosummary( $old_content, $content, $flags );
|
||||
}
|
||||
|
||||
|
|
@ -3211,6 +3213,10 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
$targetContent = $target->getContent();
|
||||
$changingContentModel = $targetContent->getModel() !== $current->getContentModel();
|
||||
|
||||
if ( in_array( 'mw-rollback', ChangeTags::getSoftwareTags() ) ) {
|
||||
$tags[] = 'mw-rollback';
|
||||
}
|
||||
|
||||
// Actually store the edit
|
||||
$status = $this->doEditContent(
|
||||
$targetContent,
|
||||
|
|
@ -3287,7 +3293,8 @@ class WikiPage implements Page, IDBAccessObject {
|
|||
'summary' => $summary,
|
||||
'current' => $current,
|
||||
'target' => $target,
|
||||
'newid' => $revId
|
||||
'newid' => $revId,
|
||||
'tags' => $tags
|
||||
];
|
||||
|
||||
return [];
|
||||
|
|
|
|||
|
|
@ -3641,6 +3641,8 @@
|
|||
"autosumm-blank": "Blanked the page",
|
||||
"autosumm-replace": "Replaced content with \"$1\"",
|
||||
"autoredircomment": "Redirected page to [[$1]]",
|
||||
"autosumm-removed-redirect": "Removed redirect to [[$1]]",
|
||||
"autosumm-changed-redirect-target": "Changed redirect target from [[$1]] to [[$2]]",
|
||||
"autosumm-new": "Created page with \"$1\"",
|
||||
"autosumm-newblank": "Created blank page",
|
||||
"autoblock_whitelist": "",
|
||||
|
|
@ -3866,6 +3868,18 @@
|
|||
"tag-list-wrapper": "([[Special:Tags|{{PLURAL:$1|Tag|Tags}}]]: $2)",
|
||||
"tag-mw-contentmodelchange": "content model change",
|
||||
"tag-mw-contentmodelchange-description": "Edits that [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:ChangeContentModel change the content model] of a page",
|
||||
"tag-mw-new-redirect": "New redirect",
|
||||
"tag-mw-new-redirect-description": "Edits that create a new redirect or change a page to a redirect",
|
||||
"tag-mw-removed-redirect": "Removed redirect",
|
||||
"tag-mw-removed-redirect-description": "Edits that change an existing redirect to a non-redirect",
|
||||
"tag-mw-changed-redirect-target": "Redirect target changed",
|
||||
"tag-mw-changed-redirect-target-description": "Edits that change the target of a redirect",
|
||||
"tag-mw-blank": "Blanking",
|
||||
"tag-mw-blank-description": "Edits that blank a page",
|
||||
"tag-mw-replace": "Replaced",
|
||||
"tag-mw-replace-description": "Edits that remove more than 90% of the content of a page",
|
||||
"tag-mw-rollback": "Rollback",
|
||||
"tag-mw-rollback-description": "Edits that roll back previous edits using the rollback link",
|
||||
"tags-title": "Tags",
|
||||
"tags-intro": "This page lists the tags that the software may mark an edit with, and their meaning.",
|
||||
"tags-tag": "Tag name",
|
||||
|
|
|
|||
|
|
@ -3835,6 +3835,8 @@
|
|||
"autosumm-blank": "The auto summary when blanking the whole page. This is not the same as deleting the page.",
|
||||
"autosumm-replace": "The auto summary when a user removes a lot of characters in the page.\n\nParameters:\n* $1 - truncated text",
|
||||
"autoredircomment": "The auto summary when making a redirect. Parameters:\n* $1 - the page where it redirects to\n* $2 - (Optional) the first X number of characters of the redirect ($2 is usually only used when end users customize the message)\n{{Identical|Redirect}}",
|
||||
"autosumm-removed-redirect": "The auto summary when making a redirect. Parameters:\n* $1 - the page where it redirects to\n* $2 - (Optional) the first X number of characters of the redirect ($2 is usually only used when end users customize the message)\n{{Identical|Redirect}}",
|
||||
"autosumm-changed-redirect-target": "The auto summary when making a redirect. Parameters:\n* $1 - the page where it redirects to\n* $2 - (Optional) the first X number of characters of the redirect ($2 is usually only used when end users customize the message)\n{{Identical|Redirect}}",
|
||||
"autosumm-new": "The auto summary when creating a new page. $1 are the first X number of characters of the new page.",
|
||||
"autosumm-newblank": "The automatic edit summary when creating a blank page. This is not the same as blanking a page.",
|
||||
"autoblock_whitelist": "{{notranslate}}",
|
||||
|
|
@ -4060,6 +4062,18 @@
|
|||
"tag-list-wrapper": "Wrapper for the list of tags shown on recent changes, watchlists, history pages and diffs.\n\nParameters:\n* $1 - number of distinct tags for given edit\n* $2 - comma-separated list of tags for given edit",
|
||||
"tag-mw-contentmodelchange": "Change tag for edits that change the content model of a page",
|
||||
"tag-mw-contentmodelchange-description": "Description for \"content model change\" change tag",
|
||||
"tag-mw-new-redirect": "Change tag for edits that make the page a redirect (either redirect creation or editing an existing page)",
|
||||
"tag-mw-new-redirect-description": "Description for \"New redirect\" change tag",
|
||||
"tag-mw-removed-redirect": "Change tag for edits that change an existing redirect into a non-redirect",
|
||||
"tag-mw-removed-redirect-description": "Description for \"Removed redirect\" change tag",
|
||||
"tag-mw-changed-redirect-target": "Change tag for edits that change the target of a redirect",
|
||||
"tag-mw-changed-redirect-target-description": "Description for \"Redirect target changed\" change tag",
|
||||
"tag-mw-blank": "Change tag for edits that blank a page with existing content",
|
||||
"tag-mw-blank-description": "Description for \"blank\" change tag",
|
||||
"tag-mw-replace": "Change tag for edits removing more than 90% of the content of a page",
|
||||
"tag-mw-replace-description": "Description for \"replace\" change tag",
|
||||
"tag-mw-rollback": "Change tag for rolling back an edit",
|
||||
"tag-mw-rollback-description": "Description for \"rollback\" change tag",
|
||||
"tags-title": "The title of [[Special:Tags]].\n{{Identical|Tag}}",
|
||||
"tags-intro": "Explanation on top of [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
|
||||
"tags-tag": "Caption of a column in [[Special:Tags]]. For more information on tags see [[mw:Manual:Tags|MediaWiki]].",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
class ChangeTagsTest extends MediaWikiTestCase {
|
||||
|
||||
// TODO only modifyDisplayQuery is tested, nothing else is
|
||||
// TODO only modifyDisplayQuery and getSoftwareTags are tested, nothing else is
|
||||
|
||||
/** @dataProvider provideModifyDisplayQuery */
|
||||
public function testModifyDisplayQuery( $origQuery, $filter_tag, $useTags, $modifiedQuery ) {
|
||||
|
|
@ -244,4 +244,66 @@ class ChangeTagsTest extends MediaWikiTestCase {
|
|||
];
|
||||
}
|
||||
|
||||
public static function dataGetSoftwareTags() {
|
||||
return [
|
||||
[
|
||||
[
|
||||
'mw-contentModelChange' => true,
|
||||
'mw-redirect' => true,
|
||||
'mw-rollback' => true,
|
||||
'mw-blank' => true,
|
||||
'mw-replace' => true
|
||||
],
|
||||
[
|
||||
'mw-rollback',
|
||||
'mw-replace',
|
||||
'mw-blank'
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
[
|
||||
'mw-contentmodelchanged' => true,
|
||||
'mw-replace' => true,
|
||||
'mw-new-redirects' => true,
|
||||
'mw-changed-redirect-target' => true,
|
||||
'mw-rolback' => true,
|
||||
'mw-blanking' => false
|
||||
],
|
||||
[
|
||||
'mw-replace',
|
||||
'mw-changed-redirect-target'
|
||||
]
|
||||
],
|
||||
|
||||
[
|
||||
[
|
||||
null,
|
||||
false,
|
||||
'Lorem ipsum',
|
||||
'mw-translation'
|
||||
],
|
||||
[]
|
||||
],
|
||||
|
||||
[
|
||||
[],
|
||||
[]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetSoftwareTags
|
||||
* @covers ChangeTags::getSoftwareTags
|
||||
*/
|
||||
public function testGetSoftwareTags( $softwareTags, $expected ) {
|
||||
$this->setMwGlobals( 'wgSoftwareTags', $softwareTags );
|
||||
|
||||
$actual = ChangeTags::getSoftwareTags();
|
||||
// Order of tags in arrays is not important
|
||||
sort( $expected );
|
||||
sort( $actual );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,15 +342,32 @@ class ContentHandlerTest extends MediaWikiTestCase {
|
|||
$content = new DummyContentHandlerForTesting( CONTENT_MODEL_WIKITEXT );
|
||||
$title = Title::newFromText( 'Help:Test' );
|
||||
// Create a new content object with no content
|
||||
$newContent = ContentHandler::makeContent( '', $title, null, null, CONTENT_MODEL_WIKITEXT );
|
||||
$newContent = ContentHandler::makeContent( '', $title, CONTENT_MODEL_WIKITEXT, null );
|
||||
// first check, if we become a blank page created summary with the right bitmask
|
||||
$autoSummary = $content->getAutosummary( null, $newContent, 97 );
|
||||
$this->assertEquals( $autoSummary, 'Created blank page' );
|
||||
$this->assertEquals( $autoSummary,
|
||||
wfMessage( 'autosumm-newblank' )->inContentLanguage()->text() );
|
||||
// now check, what we become with another bitmask
|
||||
$autoSummary = $content->getAutosummary( null, $newContent, 92 );
|
||||
$this->assertEquals( $autoSummary, '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test software tag that is added when content model of the page changes
|
||||
* @covers ContentHandler::getChangeTag
|
||||
*/
|
||||
public function testGetChangeTag() {
|
||||
$this->setMwGlobals( 'wgSoftwareTags', [ 'mw-contentmodelchange' => true ] );
|
||||
$wikitextContentHandler = new DummyContentHandlerForTesting( CONTENT_MODEL_WIKITEXT );
|
||||
// Create old content object with javascript content model
|
||||
$oldContent = ContentHandler::makeContent( '', null, CONTENT_MODEL_JAVASCRIPT, null );
|
||||
// Create new content object with wikitext content model
|
||||
$newContent = ContentHandler::makeContent( '', null, CONTENT_MODEL_WIKITEXT, null );
|
||||
// Get the tag for this edit
|
||||
$tag = $wikitextContentHandler->getChangeTag( $oldContent, $newContent, EDIT_UPDATE );
|
||||
$this->assertSame( $tag, 'mw-contentmodelchange' );
|
||||
}
|
||||
|
||||
/*
|
||||
public function testSupportsSections() {
|
||||
$this->markTestIncomplete( "not yet implemented" );
|
||||
|
|
|
|||
|
|
@ -185,6 +185,13 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
|
|||
'/^Created page .*Hello/'
|
||||
],
|
||||
|
||||
[
|
||||
null,
|
||||
'',
|
||||
EDIT_NEW,
|
||||
'/^Created blank page$/'
|
||||
],
|
||||
|
||||
[
|
||||
'Hello there, world!',
|
||||
'',
|
||||
|
|
@ -227,6 +234,104 @@ class WikitextContentHandlerTest extends MediaWikiLangTestCase {
|
|||
);
|
||||
}
|
||||
|
||||
public static function dataGetChangeTag() {
|
||||
return [
|
||||
[
|
||||
null,
|
||||
'#REDIRECT [[Foo]]',
|
||||
0,
|
||||
'mw-new-redirect'
|
||||
],
|
||||
|
||||
[
|
||||
'Lorem ipsum dolor',
|
||||
'#REDIRECT [[Foo]]',
|
||||
0,
|
||||
'mw-new-redirect'
|
||||
],
|
||||
|
||||
[
|
||||
'#REDIRECT [[Foo]]',
|
||||
'Lorem ipsum dolor',
|
||||
0,
|
||||
'mw-removed-redirect'
|
||||
],
|
||||
|
||||
[
|
||||
'#REDIRECT [[Foo]]',
|
||||
'#REDIRECT [[Bar]]',
|
||||
0,
|
||||
'mw-changed-redirect-target'
|
||||
],
|
||||
|
||||
[
|
||||
null,
|
||||
'Lorem ipsum dolor',
|
||||
EDIT_NEW,
|
||||
null // mw-newpage is not defined as a tag
|
||||
],
|
||||
|
||||
[
|
||||
null,
|
||||
'',
|
||||
EDIT_NEW,
|
||||
null // mw-newblank is not defined as a tag
|
||||
],
|
||||
|
||||
[
|
||||
'Lorem ipsum dolor',
|
||||
'',
|
||||
0,
|
||||
'mw-blank'
|
||||
],
|
||||
|
||||
[
|
||||
'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
|
||||
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
|
||||
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
|
||||
'Ipsum',
|
||||
0,
|
||||
'mw-replace'
|
||||
],
|
||||
|
||||
[
|
||||
'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
|
||||
eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
|
||||
voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
|
||||
clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
|
||||
'Duis purus odio, rhoncus et finibus dapibus, facilisis ac urna. Pellentesque
|
||||
arcu, tristique nec tempus nec, suscipit vel arcu. Sed non dolor nec ligula
|
||||
congue tempor. Quisque pellentesque finibus orci a molestie. Nam maximus, purus
|
||||
euismod finibus mollis, dui ante malesuada felis, dignissim rutrum diam sapien.',
|
||||
0,
|
||||
null
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataGetChangeTag
|
||||
* @covers WikitextContentHandler::getChangeTag
|
||||
*/
|
||||
public function testGetChangeTag( $old, $new, $flags, $expected ) {
|
||||
$this->setMwGlobals( 'wgSoftwareTags', [
|
||||
'mw-new-redirect' => true,
|
||||
'mw-removed-redirect' => true,
|
||||
'mw-changed-redirect-target' => true,
|
||||
'mw-newpage' => true,
|
||||
'mw-newblank' => true,
|
||||
'mw-blank' => true,
|
||||
'mw-replace' => true,
|
||||
] );
|
||||
$oldContent = is_null( $old ) ? null : new WikitextContent( $old );
|
||||
$newContent = is_null( $new ) ? null : new WikitextContent( $new );
|
||||
|
||||
$tag = $this->handler->getChangeTag( $oldContent, $newContent, $flags );
|
||||
|
||||
$this->assertSame( $expected, $tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* @todo Text case requires database, should be done by a test class in the Database group
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -993,6 +993,60 @@ more stuff
|
|||
$this->assertEquals( "one", $page->getContent()->getNativeData() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests tagging for edits that do rollback action
|
||||
* @covers WikiPage::doRollback
|
||||
*/
|
||||
public function testDoRollbackTagging() {
|
||||
if ( !in_array( 'mw-rollback', ChangeTags::getSoftwareTags() ) ) {
|
||||
$this->markTestSkipped( 'Rollback tag deactivated, skipped the test.' );
|
||||
}
|
||||
|
||||
$admin = new User();
|
||||
$admin->setName( 'Administrator' );
|
||||
$admin->addToDatabase();
|
||||
|
||||
$text = 'First line';
|
||||
$page = $this->newPage( 'WikiPageTest_testDoRollbackTagging' );
|
||||
$page->doEditContent(
|
||||
ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
|
||||
'Added first line',
|
||||
EDIT_NEW,
|
||||
false,
|
||||
$admin
|
||||
);
|
||||
|
||||
$secondUser = new User();
|
||||
$secondUser->setName( '92.65.217.32' );
|
||||
$text .= '\n\nSecond line';
|
||||
$page = new WikiPage( $page->getTitle() );
|
||||
$page->doEditContent(
|
||||
ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
|
||||
'Adding second line',
|
||||
0,
|
||||
false,
|
||||
$secondUser
|
||||
);
|
||||
|
||||
// Now, try the rollback
|
||||
$admin->addGroup( 'sysop' ); // Make the test user a sysop
|
||||
$token = $admin->getEditToken( 'rollback' );
|
||||
$errors = $page->doRollback(
|
||||
$secondUser->getName(),
|
||||
'testing rollback',
|
||||
$token,
|
||||
false,
|
||||
$resultDetails,
|
||||
$admin
|
||||
);
|
||||
|
||||
// If doRollback completed without errors
|
||||
if ( $errors === [] ) {
|
||||
$tags = $resultDetails[ 'tags' ];
|
||||
$this->assertContains( 'mw-rollback', $tags );
|
||||
}
|
||||
}
|
||||
|
||||
public static function provideGetAutoDeleteReason() {
|
||||
return [
|
||||
[
|
||||
|
|
|
|||
Loading…
Reference in a new issue