gplx/mediawiki/extensions/SemanticMediaWiki/tests/phpunit/Updater/DataUpdaterTest.php

543 lines
13 KiB
PHP

<?php
namespace SMW\Tests\Updater;
use SMW\DataUpdater;
use SMW\DIProperty;
use SMW\DIWikiPage;
use SMW\Property\SpecificationLookup;
use SMW\SemanticData;
use SMW\Tests\PHPUnitCompat;
use SMW\Tests\TestEnvironment;
/**
* @covers \SMW\DataUpdater
* @group semantic-mediawiki
* @group Database
*
* @license GPL-2.0-or-later
* @since 1.9
*
* @author mwjames
*/
class DataUpdaterTest extends \PHPUnit\Framework\TestCase {
use PHPUnitCompat;
private $testEnvironment;
private $transactionalCallableUpdate;
private $semanticDataFactory;
private $spyLogger;
private $store;
private $changePropagationNotifier;
private $eventDispatcher;
private $revisionGuard;
private SpecificationLookup $propertySpecificationLookup;
private $revision;
protected function setUp(): void {
parent::setUp();
$this->testEnvironment = new TestEnvironment( [
'smwgPageSpecialProperties' => [],
'smwgEnableUpdateJobs' => false,
'smwgNamespacesWithSemanticLinks' => [ NS_MAIN => true, SMW_NS_SCHEMA => true ]
] );
$this->spyLogger = $this->testEnvironment->newSpyLogger();
$this->revision = $this->getMockBuilder( '\MediaWiki\Revision\RevisionRecord' )
->disableOriginalConstructor()
->getMock();
$this->eventDispatcher = $this->getMockBuilder( '\Onoi\EventDispatcher\EventDispatcher' )
->disableOriginalConstructor()
->getMock();
$this->revisionGuard = $this->getMockBuilder( '\SMW\MediaWiki\RevisionGuard' )
->disableOriginalConstructor()
->getMock();
$this->propertySpecificationLookup = $this->getMockBuilder( '\SMW\Property\SpecificationLookup' )
->disableOriginalConstructor()
->getMock();
$this->changePropagationNotifier = $this->getMockBuilder( '\SMW\Property\ChangePropagationNotifier' )
->disableOriginalConstructor()
->getMock();
$idTable = $this->getMockBuilder( '\stdClass' )
->setMethods( [ 'exists' ] )
->getMock();
$connection = $this->getMockBuilder( '\SMW\MediaWiki\Connection\Database' )
->disableOriginalConstructor()
->getMock();
$this->store = $this->getMockBuilder( '\SMW\SQLStore\SQLStore' )
->disableOriginalConstructor()
->setMethods( [ 'getObjectIds', 'getConnection', 'getPropertyValues', 'updateData' ] )
->getMock();
$this->store->expects( $this->any() )
->method( 'getObjectIds' )
->willReturn( $idTable );
$this->store->expects( $this->any() )
->method( 'getConnection' )
->willReturn( $connection );
$this->store->setLogger( $this->spyLogger );
$jobQueue = $this->getMockBuilder( '\SMW\MediaWiki\JobQueue' )
->disableOriginalConstructor()
->getMock();
$this->testEnvironment->registerObject( 'JobQueue', $jobQueue );
$this->testEnvironment->registerObject( 'Store', $this->store );
$this->testEnvironment->registerObject( 'RevisionGuard', $this->revisionGuard );
$this->testEnvironment->registerObject( 'PropertySpecificationLookup', $this->propertySpecificationLookup );
$this->semanticDataFactory = $this->testEnvironment->getUtilityFactory()->newSemanticDataFactory();
}
protected function tearDown(): void {
$this->testEnvironment->tearDown();
parent::tearDown();
}
public function testCanConstruct() {
$semanticData = $this->getMockBuilder( '\SMW\SemanticData' )
->disableOriginalConstructor()
->getMock();
$this->assertInstanceOf(
DataUpdater::class,
new DataUpdater( $this->store, $semanticData, $this->changePropagationNotifier )
);
}
public function testDoUpdateForDefaultSettings() {
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( $this->revision );
$this->eventDispatcher->expects( $this->once() )
->method( 'dispatch' )
->with( \SMW\Listener\EventListener\EventListeners\InvalidatePropertySpecificationLookupCacheEventListener::EVENT_ID );
$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
$instance = new DataUpdater(
$this->store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$this->assertTrue(
$instance->doUpdate()
);
}
public function testDeferredUpdate() {
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( $this->revision );
$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
$instance = new DataUpdater(
$this->store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$instance->setLogger( $this->spyLogger );
$instance->isDeferrableUpdate( true );
$instance->doUpdate();
$this->assertContains(
'DeferrableUpdate',
$this->spyLogger->getMessagesAsString()
);
}
/**
* @dataProvider updateJobStatusProvider
*/
public function testDoUpdateForValidRevision( $updateJobStatus ) {
$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
$store = $this->getMockBuilder( '\SMW\Store' )
->disableOriginalConstructor()
->setMethods( [ 'updateData' ] )
->getMockForAbstractClass();
$store->expects( $this->once() )
->method( 'updateData' );
$revision = $this->getMockBuilder( '\MediaWiki\Revision\RevisionRecord' )
->disableOriginalConstructor()
->getMock();
$content = $this->getMockBuilder( '\MediaWiki\Content\Content' )
->disableOriginalConstructor()
->getMock();
$wikiPage = $this->getMockBuilder( '\WikiPage' )
->disableOriginalConstructor()
->getMock();
$wikiPage->expects( $this->atLeastOnce() )
->method( 'getContent' )
->willReturn( $content );
$pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' )
->disableOriginalConstructor()
->getMock();
$pageCreator->expects( $this->atLeastOnce() )
->method( 'createPage' )
->willReturn( $wikiPage );
$this->testEnvironment->registerObject( 'PageCreator', $pageCreator );
$this->revisionGuard->expects( $this->any() )
->method( 'newRevisionFromPage' )
->willReturn( $revision );
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( $revision );
$instance = new DataUpdater(
$store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$instance->canCreateUpdateJob(
$updateJobStatus
);
$this->assertTrue(
$instance->doUpdate()
);
}
/**
* @dataProvider updateJobStatusProvider
*/
public function testDoUpdateForNullRevision( $updateJobStatus ) {
$semanticData = $this->semanticDataFactory->newEmptySemanticData( __METHOD__ );
$idTable = $this->getMockBuilder( '\stdClass' )
->setMethods( [ 'exists' ] )
->getMock();
$idTable->expects( $this->atLeastOnce() )
->method( 'exists' )
->willReturn( true );
$store = $this->getMockBuilder( '\SMW\SQLStore\SQLStore' )
->disableOriginalConstructor()
->setMethods( [ 'clearData', 'getObjectIds' ] )
->getMock();
$store->expects( $this->any() )
->method( 'getObjectIds' )
->willReturn( $idTable );
$store->expects( $this->once() )
->method( 'clearData' )
->with( $semanticData->getSubject() );
$wikiPage = $this->getMockBuilder( '\WikiPage' )
->disableOriginalConstructor()
->getMock();
$pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' )
->disableOriginalConstructor()
->getMock();
$pageCreator->expects( $this->atLeastOnce() )
->method( 'createPage' )
->willReturn( $wikiPage );
$this->testEnvironment->registerObject( 'PageCreator', $pageCreator );
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( null );
$instance = new DataUpdater(
$store,
$semanticData,
$this->changePropagationNotifier
);
$instance->canCreateUpdateJob(
$updateJobStatus
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$this->assertTrue(
$instance->doUpdate()
);
}
public function testDoUpdateForTitleInUnknownNs() {
$wikiPage = new DIWikiPage(
'Foo',
-32768, // This namespace does not exist
''
);
$semanticData = $this->semanticDataFactory->setSubject( $wikiPage )->newEmptySemanticData();
$instance = new DataUpdater(
$this->store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$this->assertIsBool(
$instance->doUpdate()
);
}
public function testDoUpdateForSpecialPage() {
$wikiPage = new DIWikiPage(
'Foo',
NS_SPECIAL,
''
);
$semanticData = $this->semanticDataFactory->setSubject( $wikiPage )->newEmptySemanticData();
$instance = new DataUpdater(
$this->store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$this->assertFalse(
$instance->doUpdate()
);
}
public function testDoUpdateForSchema() {
$wikiPage = new DIWikiPage(
'Foo',
SMW_NS_SCHEMA,
''
);
$semanticData = $this->semanticDataFactory->setSubject( $wikiPage )->newEmptySemanticData();
$idTable = $this->getMockBuilder( '\stdClass' )
->setMethods( [ 'exists' ] )
->getMock();
$store = $this->getMockBuilder( '\SMW\SQLStore\SQLStore' )
->disableOriginalConstructor()
->setMethods( [ 'updateData' ] )
->getMock();
$store->expects( $this->once() )
->method( 'updateData' );
$wikiPage = $this->getMockBuilder( '\WikiPage' )
->disableOriginalConstructor()
->getMock();
$revision = $this->getMockBuilder( '\MediaWiki\Revision\RevisionRecord' )
->disableOriginalConstructor()
->getMock();
$content = $this->getMockBuilder( '\MediaWiki\Content\Content' )
->disableOriginalConstructor()
->getMock();
$wikiPage = $this->getMockBuilder( '\WikiPage' )
->disableOriginalConstructor()
->getMock();
$wikiPage->expects( $this->atLeastOnce() )
->method( 'getContent' )
->willReturn( $content );
$pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' )
->disableOriginalConstructor()
->getMock();
$pageCreator->expects( $this->atLeastOnce() )
->method( 'createPage' )
->willReturn( $wikiPage );
$this->testEnvironment->registerObject( 'PageCreator', $pageCreator );
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( $revision );
$instance = new DataUpdater(
$store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$instance->canCreateUpdateJob(
true
);
$this->assertTrue(
$instance->doUpdate()
);
}
public function testForYetUnknownRedirectTarget() {
$revision = $this->getMockBuilder( '\MediaWiki\Revision\RevisionRecord' )
->disableOriginalConstructor()
->getMock();
$content = $this->getMockBuilder( '\MediaWiki\Content\Content' )
->disableOriginalConstructor()
->getMock();
$wikiPage = $this->getMockBuilder( '\WikiPage' )
->disableOriginalConstructor()
->getMock();
$wikiPage->expects( $this->atLeastOnce() )
->method( 'getContent' )
->willReturn( $content );
$pageCreator = $this->getMockBuilder( '\SMW\MediaWiki\PageCreator' )
->disableOriginalConstructor()
->getMock();
$pageCreator->expects( $this->atLeastOnce() )
->method( 'createPage' )
->willReturn( $wikiPage );
$propertySpecificationLookup = $this->getMockBuilder( '\SMW\Property\SpecificationLookup' )
->disableOriginalConstructor()
->getMock();
$this->testEnvironment->registerObject( 'PageCreator', $pageCreator );
$this->testEnvironment->registerObject( 'PropertySpecificationLookup', $propertySpecificationLookup );
$this->revisionGuard->expects( $this->any() )
->method( 'getRevision' )
->willReturn( $revision );
$source = $this->getMockBuilder( '\SMW\DIWikiPage' )
->disableOriginalConstructor()
->getMock();
$subject = new DIWikiPage(
'Foo',
NS_MAIN
);
$target = new DIWikiPage(
'Bar',
NS_MAIN
);
$store = $this->getMockBuilder( '\SMW\Store' )
->disableOriginalConstructor()
->getMockForAbstractClass();
$store->expects( $this->once() )
->method( 'changeTitle' );
$store->setOption( 'smwgAutoRefreshSubject', true );
$store->setLogger( $this->spyLogger );
$semanticData = new SemanticData( $subject );
$semanticData->addPropertyObjectValue(
new DIProperty( '_REDI' ),
$target
);
$instance = new DataUpdater(
$store,
$semanticData,
$this->changePropagationNotifier
);
$instance->setEventDispatcher(
$this->eventDispatcher
);
$instance->setRevisionGuard(
$this->revisionGuard
);
$instance->canCreateUpdateJob( true );
$instance->doUpdate();
}
public function updateJobStatusProvider() {
$provider = [
[ true ],
[ false ]
];
return $provider;
}
}