This is the fourth patch of a series of patches to remove ParserOutput::getText() calls from core. This series of patches should be functionally equivalent to I2b4bcddb234f10fd8592570cb0496adf3271328e. Here we replace calls to getText where a ContentRenderer is available close by by temporary ParserOutput::runOutputPipeline that will eventually be replaced by a call to (probably) ContentRenderer (T371004). Doing this work in stages allows us to separate the work of "bring ParserOptions to the call site" from the work of "bringing ContentRenderer(ish) to the call site", since both need to be done for to make ParserOutput a value object (T293512). Change-Id: Ib4f9357293dc230df6e0ca2379a1e2a4cc1b91b7 Bug: T293512
122 lines
4 KiB
PHP
122 lines
4 KiB
PHP
<?php
|
|
|
|
use MediaWiki\Content\JsonContent;
|
|
use MediaWiki\Content\JsonContentHandler;
|
|
use MediaWiki\Content\ValidationParams;
|
|
use MediaWiki\Json\FormatJson;
|
|
use MediaWiki\Page\PageIdentity;
|
|
use MediaWiki\Page\PageIdentityValue;
|
|
use MediaWiki\Parser\ParserOutput;
|
|
use MediaWiki\Title\Title;
|
|
|
|
/**
|
|
* @covers \MediaWiki\Content\JsonContentHandler
|
|
*/
|
|
class JsonContentHandlerIntegrationTest extends MediaWikiLangTestCase {
|
|
|
|
public static function provideDataAndParserText() {
|
|
return [
|
|
[
|
|
[],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><td>' .
|
|
'<table class="mw-json"><tbody><tr><td class="mw-json-empty">Empty array</td></tr>'
|
|
. '</tbody></table></td></tr></tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><td class="mw-json-empty">Empty object</td></tr>' .
|
|
'</tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[ 'foo' ],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><th><span>0</span></th>' .
|
|
'<td class="mw-json-value">"foo"</td></tr></tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[ 'foo', 'bar' ],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><th><span>0</span></th>' .
|
|
'<td class="mw-json-value">"foo"</td></tr><tr><th><span>1</span></th>' .
|
|
'<td class="mw-json-value">"bar"</td></tr></tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[ 'baz' => 'foo', 'bar' ],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><th><span>baz</span></th>' .
|
|
'<td class="mw-json-value">"foo"</td></tr><tr><th><span>0</span></th>' .
|
|
'<td class="mw-json-value">"bar"</td></tr></tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[ 'baz' => 1000, 'bar' ],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><th><span>baz</span></th>' .
|
|
'<td class="mw-json-value">1000</td></tr><tr><th><span>0</span></th>' .
|
|
'<td class="mw-json-value">"bar"</td></tr></tbody></table></div>'
|
|
],
|
|
[
|
|
(object)[ '<script>alert("evil!")</script>' ],
|
|
'<div class="noresize"><table class="mw-json"><tbody><tr><th><span>0</span></th><td class="mw-json-value">"' .
|
|
'<script>alert("evil!")</script>"' .
|
|
'</td></tr></tbody></table></div>',
|
|
],
|
|
[
|
|
'{ broken JSON ]',
|
|
'Invalid JSON: $1',
|
|
],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @dataProvider provideDataAndParserText
|
|
*/
|
|
public function testFillParserOutput( $data, $expected ) {
|
|
if ( !is_string( $data ) ) {
|
|
$data = FormatJson::encode( $data );
|
|
}
|
|
|
|
$title = $this->createMock( Title::class );
|
|
$title->method( 'getPageLanguage' )
|
|
->willReturn( $this->getServiceContainer()->getContentLanguage() );
|
|
|
|
$content = new JsonContent( $data );
|
|
$contentRenderer = $this->getServiceContainer()->getContentRenderer();
|
|
$opts = ParserOptions::newFromAnon();
|
|
$parserOutput = $contentRenderer->getParserOutput(
|
|
$content,
|
|
$title,
|
|
null,
|
|
$opts,
|
|
true
|
|
);
|
|
$this->assertInstanceOf( ParserOutput::class, $parserOutput );
|
|
$this->assertEquals( $expected, $parserOutput->runOutputPipeline( $opts, [] )->getContentHolderText() );
|
|
}
|
|
|
|
public function testValidateSave() {
|
|
$handler = new JsonContentHandler();
|
|
$validationParams = new ValidationParams(
|
|
PageIdentityValue::localIdentity( 123, NS_MEDIAWIKI, 'Config.json' ),
|
|
0
|
|
);
|
|
|
|
$validJson = new JsonContent( FormatJson::encode( [ 'test' => 'value' ] ) );
|
|
$invalidJson = new JsonContent( '{"key":' );
|
|
|
|
$this->assertStatusGood( $handler->validateSave( $validJson, $validationParams ) );
|
|
$this->assertStatusError( 'invalid-json-data',
|
|
$handler->validateSave( $invalidJson, $validationParams ) );
|
|
|
|
$this->setTemporaryHook(
|
|
'JsonValidateSave',
|
|
static function ( JsonContent $content, PageIdentity $pageIdentity, StatusValue $status )
|
|
{
|
|
if ( $pageIdentity->getDBkey() === 'Config.json' &&
|
|
!isset( $content->getData()->getValue()->foo ) ) {
|
|
$status->fatal( 'missing-key-foo' );
|
|
}
|
|
}
|
|
);
|
|
|
|
$this->assertStatusError( 'invalid-json-data',
|
|
$handler->validateSave( $invalidJson, $validationParams ) );
|
|
$this->assertStatusError( 'missing-key-foo',
|
|
$handler->validateSave( $validJson, $validationParams ) );
|
|
}
|
|
}
|