2020-01-18 20:25:04 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
use MediaWiki\Content\ContentHandlerFactory;
|
2020-01-18 20:25:04 +00:00
|
|
|
use Wikimedia\ObjectFactory;
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
/**
|
|
|
|
|
* @group ContentHandlerFactory
|
|
|
|
|
*/
|
2020-01-18 20:25:04 +00:00
|
|
|
class ContentHandlerFactoryTest extends MediaWikiUnitTestCase {
|
|
|
|
|
|
|
|
|
|
public function provideHandlerSpecs() {
|
|
|
|
|
return [
|
2020-01-18 20:25:04 +00:00
|
|
|
'typical list' => [
|
2020-01-18 20:25:04 +00:00
|
|
|
[
|
|
|
|
|
'ExistClassName' => DummyContentHandlerForTesting::class,
|
|
|
|
|
'ExistCallbackWithExistClassName' => function ( $modelID ) {
|
|
|
|
|
return new DummyContentHandlerForTesting( $modelID );
|
|
|
|
|
},
|
|
|
|
|
],
|
2020-01-18 20:25:04 +00:00
|
|
|
DummyContentHandlerForTesting::class,
|
2020-01-18 20:25:04 +00:00
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentHandler
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createForModelID
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHandlerSpec
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::validateContentHandler
|
2020-01-18 20:25:04 +00:00
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::__construct
|
2020-01-18 20:25:04 +00:00
|
|
|
*
|
|
|
|
|
* @param array $handlerSpecs
|
2020-01-18 20:25:04 +00:00
|
|
|
* @param string $contentHandlerClass
|
2020-01-18 20:25:04 +00:00
|
|
|
*
|
2020-01-18 20:25:04 +00:00
|
|
|
* @throws MWException
|
|
|
|
|
* @throws MWUnknownContentModelException
|
|
|
|
|
* @dataProvider provideHandlerSpecs $handlerSpecs
|
|
|
|
|
*/
|
|
|
|
|
public function testGetContentHandler_callWithProvider_same(
|
|
|
|
|
array $handlerSpecs, string $contentHandlerClass
|
|
|
|
|
): void {
|
|
|
|
|
$contentHandlerExpected = new $contentHandlerClass( 'dummy' );
|
|
|
|
|
$objectFactory = $this->createMockObjectFactory();
|
|
|
|
|
|
|
|
|
|
$factory = new ContentHandlerFactory( $handlerSpecs, $objectFactory );
|
|
|
|
|
$i = 0;
|
|
|
|
|
foreach ( $handlerSpecs as $modelID => $handlerSpec ) {
|
|
|
|
|
$objectFactory
|
|
|
|
|
->expects( $this->at( $i++ ) )
|
|
|
|
|
->method( 'createObject' )
|
|
|
|
|
->with( $handlerSpec,
|
|
|
|
|
[
|
|
|
|
|
'assertClass' => ContentHandler::class,
|
|
|
|
|
'allowCallable' => true,
|
|
|
|
|
'allowClassName' => true,
|
|
|
|
|
'extraArgs' => [ $modelID ],
|
|
|
|
|
] )
|
|
|
|
|
->willReturn( $contentHandlerExpected );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach ( $handlerSpecs as $modelID => $handlerSpec ) {
|
|
|
|
|
$this->assertSame( $contentHandlerExpected, $factory->getContentHandler( $modelID ) );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentHandler
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createForModelID
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHook
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::validateContentHandler
|
2020-01-18 20:25:04 +00:00
|
|
|
*
|
2020-01-18 20:25:04 +00:00
|
|
|
* @param array $handlerSpecs
|
|
|
|
|
* @param string $contentHandlerClass
|
|
|
|
|
*
|
|
|
|
|
* @throws MWException
|
|
|
|
|
* @throws MWUnknownContentModelException
|
2020-01-18 20:25:04 +00:00
|
|
|
* @dataProvider provideHandlerSpecs $handlerSpecs
|
|
|
|
|
*/
|
2020-01-18 20:25:04 +00:00
|
|
|
public function testGetContentHandler_hookWithProvider_same(
|
|
|
|
|
array $handlerSpecs,
|
|
|
|
|
string $contentHandlerClass
|
|
|
|
|
): void {
|
|
|
|
|
$contentHandlerExpected = new $contentHandlerClass( 'dummy' );
|
|
|
|
|
$factory = new ContentHandlerFactory( [], $this->createMockObjectFactory() );
|
|
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
foreach ( $handlerSpecs as $modelID => $handlerSpec ) {
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertFalse( $factory->isDefinedModel( $modelID ) );
|
|
|
|
|
$contentHandler = null;
|
|
|
|
|
$this->setTemporaryHook( 'ContentHandlerForModelID',
|
|
|
|
|
function ( $handlerSpec, &$contentHandler ) use (
|
|
|
|
|
$contentHandlerExpected
|
|
|
|
|
) {
|
|
|
|
|
$contentHandler = $contentHandlerExpected;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
$contentHandler = $factory->getContentHandler( $modelID );
|
|
|
|
|
$this->assertSame( $contentHandlerExpected, $contentHandler, $modelID );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $modelID ), $modelID );
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
public function provideHandlerSpecsWithMWException(): array {
|
2020-01-18 20:25:04 +00:00
|
|
|
return [
|
|
|
|
|
'MWException expected' => [
|
|
|
|
|
[
|
|
|
|
|
'ExistCallbackWithWrongType' => function () {
|
|
|
|
|
return true;
|
|
|
|
|
},
|
|
|
|
|
'ExistCallbackWithNull' => function () {
|
|
|
|
|
return null;
|
|
|
|
|
},
|
|
|
|
|
'ExistCallbackWithEmptyString' => function () {
|
|
|
|
|
return '';
|
|
|
|
|
},
|
|
|
|
|
'WrongClassName' => self::class,
|
|
|
|
|
'WrongType' => true,
|
|
|
|
|
'NullType' => null,
|
|
|
|
|
|
|
|
|
|
],
|
|
|
|
|
MWException::class,
|
|
|
|
|
],
|
|
|
|
|
'Error expected' => [
|
|
|
|
|
[
|
|
|
|
|
'WrongClassNameNotExist' => 'ClassNameNotExist',
|
|
|
|
|
'ExistCallbackWithNotExistClassName' => function () {
|
|
|
|
|
return ClassNameNotExist();
|
|
|
|
|
},
|
|
|
|
|
'EmptyString' => '',
|
|
|
|
|
],
|
|
|
|
|
Error::class,
|
|
|
|
|
],
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentHandler
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createForModelID
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHandlerSpec
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::validateContentHandler
|
|
|
|
|
*
|
|
|
|
|
* @dataProvider provideHandlerSpecsWithMWException
|
|
|
|
|
*
|
|
|
|
|
* @param array $handlerSpecs
|
2020-01-18 20:25:04 +00:00
|
|
|
* @param string $exceptionClassName
|
2020-01-18 20:25:04 +00:00
|
|
|
*/
|
|
|
|
|
public function testCreateContentHandlerForModelID_callWithProvider_throwsException(
|
2020-01-18 20:25:04 +00:00
|
|
|
array $handlerSpecs,
|
|
|
|
|
string $exceptionClassName
|
|
|
|
|
): void {
|
|
|
|
|
/**
|
|
|
|
|
* @var Exception $exceptionExpected
|
|
|
|
|
*/
|
|
|
|
|
$objectFactory = $this->createMockObjectFactory();
|
|
|
|
|
$objectFactory->method( 'createObject' )
|
|
|
|
|
->willThrowException( $this->createMock( $exceptionClassName ) );
|
|
|
|
|
$factory = new ContentHandlerFactory( $handlerSpecs, $objectFactory );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
|
|
|
|
foreach ( $handlerSpecs as $modelID => $handlerSpec ) {
|
|
|
|
|
try {
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory->getContentHandler( $modelID );
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertTrue( false );
|
|
|
|
|
}
|
|
|
|
|
catch ( \Throwable $exception ) {
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertInstanceOf( $exceptionClassName, $exception );
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createForModelID
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHandlerSpec
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::validateContentHandler
|
|
|
|
|
*/
|
|
|
|
|
public function testCreateContentHandlerForModelID_callNotExist_throwMWUCMException() {
|
|
|
|
|
$this->expectException( MWUnknownContentModelException::class );
|
|
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
( new ContentHandlerFactory( [], $this->createMockObjectFactory() ) )
|
|
|
|
|
->getContentHandler( 'ModelNameNotExist' );
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2020-01-18 20:25:04 +00:00
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::defineContentHandler
|
2020-01-18 20:25:04 +00:00
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentHandler
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createForModelID
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHandlerSpec
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::validateContentHandler
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::isDefinedModel
|
|
|
|
|
*/
|
|
|
|
|
public function testDefineContentHandler_flow_throwsException() {
|
2020-01-18 20:25:04 +00:00
|
|
|
$objectFactory = $this->createMockObjectFactory();
|
|
|
|
|
$objectFactory
|
|
|
|
|
->method( 'createObject' )
|
|
|
|
|
->willReturn( $this->createMock( DummyContentHandlerForTesting::class ) );
|
|
|
|
|
$factory = new ContentHandlerFactory( [], $objectFactory );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( 'define test' ) );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory->defineContentHandler( 'define test', DummyContentHandlerForTesting::class );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( 'define test' ) );
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertInstanceOf(
|
|
|
|
|
DummyContentHandlerForTesting::class,
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory->getContentHandler( 'define test' )
|
2020-01-18 20:25:04 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentModels
|
2020-01-18 20:25:04 +00:00
|
|
|
*
|
|
|
|
|
* @dataProvider provideValidDummySpecList
|
|
|
|
|
*
|
|
|
|
|
* @param string $name1
|
|
|
|
|
* @param string $name2
|
|
|
|
|
* @param string $name3
|
|
|
|
|
* @param string $name4
|
|
|
|
|
* @throws FatalError
|
|
|
|
|
* @throws MWException
|
2020-01-18 20:25:04 +00:00
|
|
|
*/
|
2020-01-18 20:25:04 +00:00
|
|
|
public function testGetContentModels_flow_same(
|
|
|
|
|
string $name1, string $name2, string $name3, string $name4
|
|
|
|
|
): void {
|
|
|
|
|
$factory = new ContentHandlerFactory( [
|
|
|
|
|
$name1 => DummyContentHandlerForTesting::class,
|
|
|
|
|
$name2 => DummyContentHandlerForTesting::class,
|
|
|
|
|
], $this->createMockObjectFactory() );
|
|
|
|
|
$this->assertArrayEquals(
|
|
|
|
|
[ $name1, $name2, ],
|
|
|
|
|
$factory->getContentModels() );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory->defineContentHandler(
|
|
|
|
|
$name3,
|
|
|
|
|
function () {
|
|
|
|
|
}
|
|
|
|
|
);
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertArrayEquals(
|
|
|
|
|
[ $name1, $name2, $name3, ],
|
|
|
|
|
$factory->getContentModels()
|
|
|
|
|
);
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->setTemporaryHook( 'GetContentModels',
|
|
|
|
|
function ( &$models ) use ( $name4 ) {
|
|
|
|
|
$models[] = $name4;
|
|
|
|
|
} );
|
|
|
|
|
$this->assertArrayEquals(
|
|
|
|
|
[ $name1, $name2, $name3, $name4, ],
|
|
|
|
|
$factory->getContentModels()
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::isDefinedModel
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::createContentHandlerFromHook
|
|
|
|
|
* @dataProvider provideValidDummySpecList
|
|
|
|
|
*
|
|
|
|
|
* @param string $name1
|
|
|
|
|
* @param string $name2
|
|
|
|
|
* @param string $name3
|
|
|
|
|
* @param string $name4
|
|
|
|
|
* @throws MWException
|
|
|
|
|
*/
|
|
|
|
|
public function testIsDefinedModel_flow_same(
|
|
|
|
|
string $name1, string $name2, string $name3, string $name4
|
|
|
|
|
): void {
|
|
|
|
|
$factory = new ContentHandlerFactory( [
|
|
|
|
|
$name1 => DummyContentHandlerForTesting::class,
|
|
|
|
|
$name2 => DummyContentHandlerForTesting::class,
|
|
|
|
|
], $this->createMockObjectFactory() );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name1 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name2 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( $name3 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( $name4 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( 'not exist name' ) );
|
|
|
|
|
|
|
|
|
|
$factory->defineContentHandler(
|
|
|
|
|
$name3,
|
|
|
|
|
function () {
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name1 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name2 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name3 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( $name4 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( 'not exist name' ) );
|
|
|
|
|
|
|
|
|
|
$this->setTemporaryHook(
|
|
|
|
|
'GetContentModels',
|
|
|
|
|
function ( &$models ) use ( $name4 ) {
|
|
|
|
|
$models[] = $name4;
|
|
|
|
|
} );
|
|
|
|
|
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name1 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name2 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name3 ) );
|
|
|
|
|
$this->assertTrue( $factory->isDefinedModel( $name4 ) );
|
|
|
|
|
$this->assertFalse( $factory->isDefinedModel( 'not exist name' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function provideValidDummySpecList() {
|
|
|
|
|
return [
|
|
|
|
|
'1-0-3' => [
|
|
|
|
|
'mock name 1',
|
|
|
|
|
'mock name 0',
|
|
|
|
|
'mock name 3',
|
|
|
|
|
'mock name 4',
|
|
|
|
|
],
|
|
|
|
|
];
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getContentModels
|
|
|
|
|
*/
|
|
|
|
|
public function testGetContentModels_empty_empty() {
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory = new ContentHandlerFactory( [], $this->createMockObjectFactory() );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$this->assertArrayEquals( [], $factory->getContentModels() );
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::getAllContentFormats
|
|
|
|
|
* @covers \MediaWiki\Content\ContentHandlerFactory::defineContentHandler
|
|
|
|
|
*/
|
|
|
|
|
public function testGetAllContentFormats_flow_same() {
|
2020-01-18 20:25:04 +00:00
|
|
|
$contentHandler1 = $this->createMock( DummyContentHandlerForTesting::class );
|
|
|
|
|
$contentHandler1->method( 'getSupportedFormats' )->willReturn( [ 'format 1' ] );
|
|
|
|
|
|
|
|
|
|
$contentHandler2 = $this->createMock( DummyContentHandlerForTesting::class );
|
|
|
|
|
$contentHandler2->method( 'getSupportedFormats' )->willReturn( [ 'format 0' ] );
|
|
|
|
|
|
|
|
|
|
$contentHandler3 = $this->createMock( DummyContentHandlerForTesting::class );
|
|
|
|
|
$contentHandler3->method( 'getSupportedFormats' )->willReturn( [ 'format 3' ] );
|
|
|
|
|
|
|
|
|
|
$objectFactory = $this->createMockObjectFactory();
|
|
|
|
|
$objectFactory->expects( $this->at( 0 ) )
|
|
|
|
|
->method( 'createObject' )
|
|
|
|
|
->willReturn( $contentHandler1 );
|
|
|
|
|
$objectFactory->expects( $this->at( 1 ) )
|
|
|
|
|
->method( 'createObject' )
|
|
|
|
|
->willReturn( $contentHandler2 );
|
|
|
|
|
$objectFactory->expects( $this->at( 2 ) )
|
|
|
|
|
->method( 'createObject' )
|
|
|
|
|
->willReturn( $contentHandler3 );
|
|
|
|
|
|
|
|
|
|
$factory = new ContentHandlerFactory( [
|
2020-01-18 20:25:04 +00:00
|
|
|
'mock name 1' => function () {
|
2020-01-18 20:25:04 +00:00
|
|
|
//return new DummyContentHandlerForTesting( 'mock 1', [ 'format 1' ] );
|
2020-01-18 20:25:04 +00:00
|
|
|
},
|
|
|
|
|
'mock name 2' => function () {
|
2020-01-18 20:25:04 +00:00
|
|
|
//return new DummyContentHandlerForTesting( 'mock 0', [ 'format 0' ] );
|
2020-01-18 20:25:04 +00:00
|
|
|
},
|
2020-01-18 20:25:04 +00:00
|
|
|
], $objectFactory );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
|
|
|
|
$this->assertArrayEquals( [
|
|
|
|
|
'format 1',
|
|
|
|
|
'format 0',
|
2020-01-18 20:25:04 +00:00
|
|
|
],
|
|
|
|
|
$factory->getAllContentFormats() );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
2020-01-18 20:25:04 +00:00
|
|
|
$factory->defineContentHandler( 'some new name',
|
|
|
|
|
function () {
|
|
|
|
|
//return new DummyContentHandlerForTesting( 'mock defined', [ 'format defined' ] );
|
|
|
|
|
} );
|
2020-01-18 20:25:04 +00:00
|
|
|
|
|
|
|
|
$this->assertArrayEquals( [
|
|
|
|
|
'format 1',
|
|
|
|
|
'format 0',
|
2020-01-18 20:25:04 +00:00
|
|
|
'format 3',
|
|
|
|
|
],
|
|
|
|
|
$factory->getAllContentFormats() );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return ObjectFactory|\PHPUnit\Framework\MockObject\MockObject
|
|
|
|
|
*/
|
|
|
|
|
private function createMockObjectFactory(): ObjectFactory {
|
|
|
|
|
return $this->createMock( ObjectFactory::class );
|
2020-01-18 20:25:04 +00:00
|
|
|
}
|
|
|
|
|
}
|