mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Cite
synced 2024-11-27 16:30:12 +00:00
Allow visualeditor-cite-tool-name-… messages to be missing
The information read from the …cite-tool-definition.json files is effectively user input, even if only interface administrators can edit it. Usually we carefully validate user input. But as of now this code starts failing with all kinds of uncatched errors. * An entry with no name, an empty name, or a name that's not a string will cause all kinds of undefined behavior. * An entry with an empty title results in an invisible button. * A missing message results in a technical <…> placeholder, even if the name is usually a sensible fallback. Note that hard-coding titles as plain text strings in the ….json file was already possible. Change-Id: Iddcedbe859e86ac4c3f79a53d36237daff86c0db
This commit is contained in:
parent
61880c7535
commit
2b32f15c8c
|
@ -30,13 +30,23 @@ class CitationToolDefinition {
|
|||
$citationTools = [];
|
||||
if ( is_array( $citationDefinition ) ) {
|
||||
foreach ( $citationDefinition as $tool ) {
|
||||
// The following messages are generated here:
|
||||
// * visualeditor-cite-tool-name-book
|
||||
// * visualeditor-cite-tool-name-journal
|
||||
// * visualeditor-cite-tool-name-news
|
||||
// * visualeditor-cite-tool-name-web
|
||||
$tool->title ??= $context->msg( 'visualeditor-cite-tool-name-' . $tool->name )
|
||||
->text();
|
||||
// Skip incomplete entries that don't even have a name
|
||||
if ( empty( $tool->name ) || !is_string( $tool->name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Users can hard-code titles in MediaWiki:Cite-tool-definition.json if they want
|
||||
if ( empty( $tool->title ) || !is_string( $tool->title ) ) {
|
||||
// The following messages are generated here:
|
||||
// * visualeditor-cite-tool-name-book
|
||||
// * visualeditor-cite-tool-name-journal
|
||||
// * visualeditor-cite-tool-name-news
|
||||
// * visualeditor-cite-tool-name-web
|
||||
$msg = $context->msg( 'visualeditor-cite-tool-name-' . $tool->name );
|
||||
// Fall back to the raw name if there is no message
|
||||
$tool->title = $msg->isDisabled() ? $tool->name : $msg->text();
|
||||
}
|
||||
|
||||
$citationTools[] = $tool;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,26 +15,45 @@ class CitationToolDefinitionTest extends \MediaWikiUnitTestCase {
|
|||
public function testGetScript() {
|
||||
$context = $this->createResourceLoaderContext();
|
||||
|
||||
$expected = [
|
||||
[ 'name' => 'no-message', 'title' => 'Hard-coded title' ],
|
||||
[ 'name' => 'missing-message', 'title' => 'missing-message' ],
|
||||
[ 'name' => 'n', 'title' => 't' ],
|
||||
];
|
||||
$this->assertSame(
|
||||
've.ui.mwCitationTools = [{"name":"n","title":"t"}];',
|
||||
've.ui.mwCitationTools = ' . json_encode( $expected ) . ';',
|
||||
CitationToolDefinition::makeScript( $context )
|
||||
);
|
||||
}
|
||||
|
||||
private function createResourceLoaderContext(): Context {
|
||||
$definition = [
|
||||
// We expect broken and incomplete entries to be skipped
|
||||
[],
|
||||
[ 'name' => '' ],
|
||||
|
||||
[ 'name' => 'no-message', 'title' => 'Hard-coded title' ],
|
||||
[ 'name' => 'missing-message' ],
|
||||
[ 'name' => 'n' ],
|
||||
];
|
||||
|
||||
$msg = $this->createMock( Message::class );
|
||||
$msg->method( 'inContentLanguage' )
|
||||
->willReturnSelf();
|
||||
$msg->method( 'plain' )
|
||||
->willReturnOnConsecutiveCalls( '', '[{"name":"n"}]' );
|
||||
->willReturn( json_encode( $definition ) );
|
||||
$msg->method( 'text' )
|
||||
->willReturn( 't' );
|
||||
|
||||
$disabled = $this->createMock( Message::class );
|
||||
$disabled->method( 'isDisabled' )->willReturn( true );
|
||||
|
||||
$context = $this->createStub( Context::class );
|
||||
$context->method( 'msg' )
|
||||
->willReturnMap( [
|
||||
[ 'cite-tool-definition.json', $msg ],
|
||||
[ 'visualeditor-cite-tool-definition.json', $msg ],
|
||||
[ 'visualeditor-cite-tool-name-missing-message', $disabled ],
|
||||
[ 'visualeditor-cite-tool-name-n', $msg ]
|
||||
] );
|
||||
$context->method( 'encodeJson' )->willReturnCallback( 'json_encode' );
|
||||
|
|
Loading…
Reference in a new issue