2015-11-16 15:40:07 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace PageImages\Tests\Hooks;
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
use LinksUpdate;
|
2015-11-16 15:40:07 +00:00
|
|
|
use PageImages;
|
2016-11-10 00:02:00 +00:00
|
|
|
use PageImages\Hooks\LinksUpdateHookHandler;
|
2015-11-16 15:40:07 +00:00
|
|
|
use ParserOutput;
|
2016-12-06 01:19:06 +00:00
|
|
|
use MediaWikiTestCase;
|
2016-03-07 22:48:15 +00:00
|
|
|
use RepoGroup;
|
2016-12-06 01:19:06 +00:00
|
|
|
use Title;
|
2017-04-20 07:48:48 +00:00
|
|
|
use Wikimedia\TestingAccessWrapper;
|
2015-11-16 15:40:07 +00:00
|
|
|
|
|
|
|
/**
|
2017-12-27 19:25:59 +00:00
|
|
|
* @covers \PageImages\Hooks\LinksUpdateHookHandler
|
2015-11-16 15:40:07 +00:00
|
|
|
*
|
|
|
|
* @group PageImages
|
|
|
|
*
|
|
|
|
* @license WTFPL 2.0
|
2017-11-24 07:33:49 +00:00
|
|
|
* @author Thiemo Kreuz
|
2015-11-16 15:40:07 +00:00
|
|
|
*/
|
2016-12-06 01:19:06 +00:00
|
|
|
class LinksUpdateHookHandlerTest extends MediaWikiTestCase {
|
2015-11-16 15:40:07 +00:00
|
|
|
|
2016-03-07 22:48:15 +00:00
|
|
|
public function tearDown() {
|
|
|
|
// remove mock added in testGetMetadata()
|
|
|
|
RepoGroup::destroySingleton();
|
|
|
|
parent::tearDown();
|
|
|
|
}
|
|
|
|
|
2017-04-16 01:26:58 +00:00
|
|
|
public function setUp() {
|
|
|
|
parent::setUp();
|
|
|
|
|
|
|
|
// Force LinksUpdateHookHandler::getPageImageCanditates to look at all
|
|
|
|
// sections.
|
|
|
|
$this->setMwGlobals( 'wgPageImagesLeadSectionOnly', false );
|
|
|
|
}
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
/**
|
2017-11-23 16:06:51 +00:00
|
|
|
* @param array[] $images
|
|
|
|
* @param array[]|bool $leadImages
|
|
|
|
*
|
2016-03-10 15:27:40 +00:00
|
|
|
* @return LinksUpdate
|
|
|
|
*/
|
2016-12-06 01:19:06 +00:00
|
|
|
private function getLinksUpdate( array $images, $leadImages = false ) {
|
2015-11-16 15:40:07 +00:00
|
|
|
$parserOutput = new ParserOutput();
|
2016-11-10 00:02:00 +00:00
|
|
|
$parserOutput->setExtensionData( 'pageImages', $images );
|
2016-12-06 01:19:06 +00:00
|
|
|
$parserOutputLead = new ParserOutput();
|
|
|
|
$parserOutputLead->setExtensionData( 'pageImages', $leadImages || $images );
|
|
|
|
|
|
|
|
$rev = $this->getMockBuilder( 'Revision' )
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
|
|
|
|
|
|
|
$content = $this->getMockBuilder( 'AbstractContent' )
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
|
|
|
|
|
|
|
$sectionContent = $this->getMockBuilder( 'AbstractContent' )
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
2015-11-16 15:40:07 +00:00
|
|
|
|
|
|
|
$linksUpdate = $this->getMockBuilder( 'LinksUpdate' )
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
2016-12-06 01:19:06 +00:00
|
|
|
|
|
|
|
$linksUpdate->expects( $this->any() )
|
|
|
|
->method( 'getTitle' )
|
|
|
|
->will( $this->returnValue( new Title( 'LinksUpdateHandlerTest' ) ) );
|
|
|
|
|
2015-11-16 15:40:07 +00:00
|
|
|
$linksUpdate->expects( $this->any() )
|
|
|
|
->method( 'getParserOutput' )
|
|
|
|
->will( $this->returnValue( $parserOutput ) );
|
|
|
|
|
2016-12-06 01:19:06 +00:00
|
|
|
$linksUpdate->expects( $this->any() )
|
|
|
|
->method( 'getRevision' )
|
|
|
|
->will( $this->returnValue( $rev ) );
|
|
|
|
|
|
|
|
$rev->expects( $this->any() )
|
|
|
|
->method( 'getContent' )
|
|
|
|
->will( $this->returnValue( $content ) );
|
|
|
|
|
|
|
|
$content->expects( $this->any() )
|
|
|
|
->method( 'getSection' )
|
|
|
|
->will( $this->returnValue( $sectionContent ) );
|
|
|
|
|
|
|
|
$sectionContent->expects( $this->any() )
|
|
|
|
->method( 'getParserOutput' )
|
|
|
|
->will( $this->returnValue( $parserOutputLead ) );
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
return $linksUpdate;
|
2015-11-16 15:40:07 +00:00
|
|
|
}
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
/**
|
2016-11-10 00:02:00 +00:00
|
|
|
* Required to make wfFindFile in LinksUpdateHookHandler::getScore return something.
|
2016-03-10 15:27:40 +00:00
|
|
|
* @return RepoGroup
|
|
|
|
*/
|
|
|
|
private function getRepoGroup() {
|
2016-03-07 22:48:15 +00:00
|
|
|
$file = $this->getMockBuilder( 'File' )
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
|
|
|
// ugly hack to avoid all the unmockable crap in FormatMetadata
|
|
|
|
$file->expects( $this->any() )
|
|
|
|
->method( 'isDeleted' )
|
|
|
|
->will( $this->returnValue( true ) );
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
$repoGroup = $this->getMockBuilder( 'RepoGroup' )
|
2016-03-07 22:48:15 +00:00
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
2016-03-10 15:27:40 +00:00
|
|
|
$repoGroup->expects( $this->any() )
|
2016-03-07 22:48:15 +00:00
|
|
|
->method( 'findFile' )
|
|
|
|
->will( $this->returnValue( $file ) );
|
|
|
|
|
2016-03-10 15:27:40 +00:00
|
|
|
return $repoGroup;
|
|
|
|
}
|
2016-03-07 22:48:15 +00:00
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideDoLinksUpdate
|
2017-12-27 19:25:59 +00:00
|
|
|
* @covers \PageImages\Hooks\LinksUpdateHookHandler::doLinksUpdate
|
2016-11-10 00:02:00 +00:00
|
|
|
*/
|
2017-05-30 20:36:57 +00:00
|
|
|
public function testDoLinksUpdate(
|
|
|
|
array $images,
|
|
|
|
$expectedFreeFileName,
|
|
|
|
$expectedNonFreeFileName
|
|
|
|
) {
|
2016-11-10 00:02:00 +00:00
|
|
|
$linksUpdate = $this->getLinksUpdate( $images );
|
|
|
|
$mock = TestingAccessWrapper::newFromObject(
|
|
|
|
$this->getMockBuilder( LinksUpdateHookHandler::class )
|
2016-12-02 00:49:13 +00:00
|
|
|
->setMethods( [ 'getScore', 'isImageFree' ] )
|
2016-11-10 00:02:00 +00:00
|
|
|
->getMock()
|
|
|
|
);
|
|
|
|
|
|
|
|
$scoreMap = [];
|
|
|
|
$isFreeMap = [];
|
|
|
|
$counter = 0;
|
|
|
|
foreach ( $images as $image ) {
|
2016-12-02 00:49:13 +00:00
|
|
|
array_push( $scoreMap, [ $image, $counter++, $image['score'] ] );
|
|
|
|
array_push( $isFreeMap, [ $image['filename'], $image['isFree'] ] );
|
2016-11-10 00:02:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'getScore' )
|
|
|
|
->will( $this->returnValueMap( $scoreMap ) );
|
|
|
|
|
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'isImageFree' )
|
|
|
|
->will( $this->returnValueMap( $isFreeMap ) );
|
2016-03-10 15:27:40 +00:00
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
$mock->doLinksUpdate( $linksUpdate );
|
2016-03-10 15:27:40 +00:00
|
|
|
|
|
|
|
$this->assertTrue( property_exists( $linksUpdate, 'mProperties' ), 'precondition' );
|
2016-11-10 00:02:00 +00:00
|
|
|
if ( is_null( $expectedFreeFileName ) ) {
|
2017-05-30 20:36:57 +00:00
|
|
|
$this->assertArrayNotHasKey( PageImages::PROP_NAME_FREE, $linksUpdate->mProperties );
|
2016-11-10 00:02:00 +00:00
|
|
|
} else {
|
2017-05-30 19:49:44 +00:00
|
|
|
$this->assertSame( $expectedFreeFileName,
|
|
|
|
$linksUpdate->mProperties[PageImages::PROP_NAME_FREE] );
|
2016-11-10 00:02:00 +00:00
|
|
|
}
|
|
|
|
if ( is_null( $expectedNonFreeFileName ) ) {
|
2017-05-30 20:36:57 +00:00
|
|
|
$this->assertArrayNotHasKey( PageImages::PROP_NAME, $linksUpdate->mProperties );
|
2016-11-10 00:02:00 +00:00
|
|
|
} else {
|
|
|
|
$this->assertSame( $expectedNonFreeFileName, $linksUpdate->mProperties[PageImages::PROP_NAME] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function provideDoLinksUpdate() {
|
|
|
|
return [
|
|
|
|
// both images are non-free
|
|
|
|
[
|
|
|
|
[
|
|
|
|
[ 'filename' => 'A.jpg', 'score' => 100, 'isFree' => false ],
|
|
|
|
[ 'filename' => 'B.jpg', 'score' => 90, 'isFree' => false ],
|
|
|
|
],
|
|
|
|
null,
|
|
|
|
'A.jpg'
|
|
|
|
],
|
|
|
|
// both images are free
|
|
|
|
[
|
|
|
|
[
|
|
|
|
[ 'filename' => 'A.jpg', 'score' => 100, 'isFree' => true ],
|
|
|
|
[ 'filename' => 'B.jpg', 'score' => 90, 'isFree' => true ],
|
|
|
|
],
|
|
|
|
'A.jpg',
|
|
|
|
null
|
|
|
|
],
|
|
|
|
// one free (with a higher score), one non-free image
|
|
|
|
[
|
|
|
|
[
|
|
|
|
[ 'filename' => 'A.jpg', 'score' => 100, 'isFree' => true ],
|
|
|
|
[ 'filename' => 'B.jpg', 'score' => 90, 'isFree' => false ],
|
|
|
|
],
|
|
|
|
'A.jpg',
|
|
|
|
null
|
|
|
|
],
|
|
|
|
// one non-free (with a higher score), one free image
|
|
|
|
[
|
|
|
|
[
|
|
|
|
[ 'filename' => 'A.jpg', 'score' => 100, 'isFree' => false ],
|
|
|
|
[ 'filename' => 'B.jpg', 'score' => 90, 'isFree' => true ],
|
|
|
|
],
|
|
|
|
'B.jpg',
|
|
|
|
'A.jpg'
|
|
|
|
]
|
|
|
|
];
|
2016-03-10 15:27:40 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 01:19:06 +00:00
|
|
|
/**
|
2017-12-27 19:25:59 +00:00
|
|
|
* @covers \PageImages\Hooks\LinksUpdateHookHandler::getPageImageCandidates
|
2016-12-06 01:19:06 +00:00
|
|
|
*/
|
|
|
|
public function testGetPageImageCandidates() {
|
|
|
|
$candidates = [
|
|
|
|
[ 'filename' => 'A.jpg', 'score' => 100, 'isFree' => false ],
|
|
|
|
[ 'filename' => 'B.jpg', 'score' => 90, 'isFree' => false ],
|
|
|
|
];
|
|
|
|
$linksUpdate = $this->getLinksUpdate( $candidates, array_slice( $candidates, 0, 1 ) );
|
|
|
|
|
|
|
|
// should get without lead.
|
|
|
|
$handler = new LinksUpdateHookHandler();
|
|
|
|
$this->setMwGlobals( 'wgPageImagesLeadSectionOnly', false );
|
|
|
|
$images = $handler->getPageImageCandidates( $linksUpdate );
|
|
|
|
$this->assertTrue( count( $images ) === 2, 'All images are returned.' );
|
|
|
|
|
|
|
|
$this->setMwGlobals( 'wgPageImagesLeadSectionOnly', true );
|
|
|
|
$images = $handler->getPageImageCandidates( $linksUpdate );
|
|
|
|
$this->assertTrue( count( $images ) === 1, 'Only lead images are returned.' );
|
|
|
|
}
|
|
|
|
|
2016-11-16 21:29:03 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideGetScore
|
|
|
|
*/
|
2016-11-10 00:02:00 +00:00
|
|
|
public function testGetScore( $image, $scoreFromTable, $position, $expected ) {
|
|
|
|
$mock = TestingAccessWrapper::newFromObject(
|
|
|
|
$this->getMockBuilder( LinksUpdateHookHandler::class )
|
2016-12-02 00:49:13 +00:00
|
|
|
->setMethods( [ 'scoreFromTable', 'getMetadata', 'getRatio', 'getBlacklist' ] )
|
2016-11-10 00:02:00 +00:00
|
|
|
->getMock()
|
|
|
|
);
|
2016-12-02 00:49:13 +00:00
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'scoreFromTable' )
|
2017-06-20 07:17:38 +00:00
|
|
|
->will( $this->returnValue( $scoreFromTable ) );
|
2016-11-16 21:29:03 +00:00
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'getRatio' )
|
|
|
|
->will( $this->returnValue( 0 ) );
|
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'getBlacklist' )
|
2016-12-02 00:49:13 +00:00
|
|
|
->will( $this->returnValue( [ 'blacklisted.jpg' => 1 ] ) );
|
2016-11-16 21:29:03 +00:00
|
|
|
|
|
|
|
$score = $mock->getScore( $image, $position );
|
|
|
|
$this->assertEquals( $expected, $score );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function provideGetScore() {
|
|
|
|
return [
|
|
|
|
[
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'filename' => 'A.jpg', 'handler' => [ 'width' => 100 ] ],
|
2016-11-16 21:29:03 +00:00
|
|
|
100,
|
|
|
|
0,
|
|
|
|
// width score + ratio score + position score
|
|
|
|
100 + 100 + 8
|
|
|
|
],
|
|
|
|
[
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'filename' => 'A.jpg', 'fullwidth' => 100 ],
|
2016-11-16 21:29:03 +00:00
|
|
|
50,
|
|
|
|
1,
|
|
|
|
// width score + ratio score + position score
|
|
|
|
106
|
|
|
|
],
|
|
|
|
[
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'filename' => 'A.jpg', 'fullwidth' => 100 ],
|
2016-11-16 21:29:03 +00:00
|
|
|
50,
|
|
|
|
2,
|
|
|
|
// width score + ratio score + position score
|
|
|
|
104
|
|
|
|
],
|
|
|
|
[
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'filename' => 'A.jpg', 'fullwidth' => 100 ],
|
2016-11-16 21:29:03 +00:00
|
|
|
50,
|
|
|
|
3,
|
|
|
|
// width score + ratio score + position score
|
|
|
|
103
|
|
|
|
],
|
|
|
|
[
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'filename' => 'blacklisted.jpg', 'fullwidth' => 100 ],
|
2016-11-16 21:29:03 +00:00
|
|
|
50,
|
|
|
|
3,
|
|
|
|
// blacklist score
|
2017-08-11 04:15:33 +00:00
|
|
|
- 1000
|
2016-11-16 21:29:03 +00:00
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider provideScoreFromTable
|
2017-12-27 19:25:59 +00:00
|
|
|
* @covers \PageImages\Hooks\LinksUpdateHookHandler::scoreFromTable
|
2016-11-16 21:29:03 +00:00
|
|
|
*/
|
|
|
|
public function testScoreFromTable( $type, $value, $expected ) {
|
|
|
|
global $wgPageImagesScores;
|
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
$handlerWrapper = TestingAccessWrapper::newFromObject( new LinksUpdateHookHandler );
|
2016-11-16 21:29:03 +00:00
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
$score = $handlerWrapper->scoreFromTable( $value, $wgPageImagesScores[$type] );
|
2016-11-16 21:29:03 +00:00
|
|
|
$this->assertEquals( $expected, $score );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function provideScoreFromTable() {
|
|
|
|
return [
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'width', 100, -100 ],
|
|
|
|
[ 'width', 119, -100 ],
|
|
|
|
[ 'width', 300, 10 ],
|
|
|
|
[ 'width', 400, 10 ],
|
|
|
|
[ 'width', 500, 5 ],
|
|
|
|
[ 'width', 600, 5 ],
|
|
|
|
[ 'width', 601, 0 ],
|
|
|
|
[ 'width', 999, 0 ],
|
|
|
|
[ 'galleryImageWidth', 99, -100 ],
|
|
|
|
[ 'galleryImageWidth', 100, 0 ],
|
|
|
|
[ 'galleryImageWidth', 500, 0 ],
|
|
|
|
[ 'ratio', 1, -100 ],
|
|
|
|
[ 'ratio', 3, -100 ],
|
|
|
|
[ 'ratio', 4, 0 ],
|
|
|
|
[ 'ratio', 5, 0 ],
|
|
|
|
[ 'ratio', 10, 5 ],
|
|
|
|
[ 'ratio', 20, 5 ],
|
|
|
|
[ 'ratio', 25, 0 ],
|
|
|
|
[ 'ratio', 30, 0 ],
|
|
|
|
[ 'ratio', 31, -100 ],
|
|
|
|
[ 'ratio', 40, -100 ],
|
2016-11-16 21:29:03 +00:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
/**
|
|
|
|
* @dataProvider provideIsFreeImage
|
2017-12-27 19:25:59 +00:00
|
|
|
* @covers \PageImages\Hooks\LinksUpdateHookHandler::isImageFree
|
2016-11-10 00:02:00 +00:00
|
|
|
*/
|
|
|
|
public function testIsFreeImage( $fileName, $metadata, $expected ) {
|
2016-03-10 15:27:40 +00:00
|
|
|
RepoGroup::setSingleton( $this->getRepoGroup() );
|
2016-11-10 00:02:00 +00:00
|
|
|
$mock = TestingAccessWrapper::newFromObject(
|
|
|
|
$this->getMockBuilder( LinksUpdateHookHandler::class )
|
2016-12-02 00:49:13 +00:00
|
|
|
->setMethods( [ 'fetchFileMetadata' ] )
|
2016-11-10 00:02:00 +00:00
|
|
|
->getMock()
|
|
|
|
);
|
|
|
|
$mock->expects( $this->any() )
|
|
|
|
->method( 'fetchFileMetadata' )
|
|
|
|
->will( $this->returnValue( $metadata ) );
|
2016-12-02 00:49:13 +00:00
|
|
|
$this->assertEquals( $expected, $mock->isImageFree( $fileName ) );
|
2016-03-07 22:48:15 +00:00
|
|
|
}
|
2016-03-10 15:27:40 +00:00
|
|
|
|
2016-11-10 00:02:00 +00:00
|
|
|
public function provideIsFreeImage() {
|
|
|
|
return [
|
2016-12-02 00:49:13 +00:00
|
|
|
[ 'A.jpg', [], true ],
|
|
|
|
[ 'A.jpg', [ 'NonFree' => [ 'value' => '0' ] ], true ],
|
|
|
|
[ 'A.jpg', [ 'NonFree' => [ 'value' => 0 ] ], true ],
|
|
|
|
[ 'A.jpg', [ 'NonFree' => [ 'value' => false ] ], true ],
|
|
|
|
[ 'A.jpg', [ 'NonFree' => [ 'value' => 'something' ] ], false ],
|
|
|
|
[ 'A.jpg', [ 'something' => [ 'value' => 'something' ] ], true ],
|
2016-11-10 00:02:00 +00:00
|
|
|
];
|
|
|
|
}
|
2015-11-16 15:40:07 +00:00
|
|
|
}
|