wiki.techinc.nl/tests/phpunit/includes/import/ImportExportTest.php
Alexander Vorwerk 2fbf13812a WikiExporter: inject services
This patch injects services into WikiExporter. It also adds a
WikiExporterFactory service for creating WikiExporter instances.

Change-Id: Ib1547defea54c309865c116bc83d617c21568843
2021-09-06 10:03:37 +00:00

266 lines
6.6 KiB
PHP

<?php
use MediaWiki\MediaWikiServices;
use MediaWiki\Revision\RevisionRecord;
use MediaWiki\Tests\Maintenance\DumpAsserter;
/**
* Import/export round trip test.
*
* @group Database
* @covers WikiExporter
* @covers WikiImporter
*/
class ImportExportTest extends MediaWikiLangTestCase {
public function setUp(): void {
parent::setUp();
$slotRoleRegistry = MediaWikiServices::getInstance()->getSlotRoleRegistry();
if ( !$slotRoleRegistry->isDefinedRole( 'ImportExportTest' ) ) {
$slotRoleRegistry->defineRoleWithModel( 'ImportExportTest', CONTENT_MODEL_WIKITEXT );
}
}
/**
* @param string $schemaVersion
*
* @return WikiExporter
*/
private function getExporter( string $schemaVersion ) {
$exporter = $this->getServiceContainer()
->getWikiExporterFactory()
->getWikiExporter( $this->db, WikiExporter::FULL );
$exporter->setSchemaVersion( $schemaVersion );
return $exporter;
}
/**
* @param ImportSource $source
*
* @return WikiImporter
*/
private function getImporter( ImportSource $source ) {
$config = new HashConfig( [
'CommandLineMode' => true,
] );
$services = $this->getServiceContainer();
$importer = new WikiImporter(
$source,
$config,
$services->getHookContainer(),
$services->getContentLanguage(),
$services->getNamespaceInfo(),
$services->getTitleFactory(),
$services->getWikiPageFactory(),
$services->getWikiRevisionUploadImporter(),
$services->getPermissionManager(),
$services->getContentHandlerFactory(),
$services->getSlotRoleRegistry()
);
return $importer;
}
/**
* @param string $testName
*
* @return string[]
*/
private function getFilesToImport( string $testName ) {
return glob( __DIR__ . "/../../data/import/$testName.import-*.xml" );
}
/**
* @param string $name
* @param string $schemaVersion
*
* @return string path of the dump file
*/
protected function getDumpTemplatePath( $name, $schemaVersion ) {
return __DIR__ . "/../../data/import/$name.$schemaVersion.xml";
}
/**
* @param string $prefix
* @param string[] $keys
*
* @return string[]
*/
private function getUniqueNames( string $prefix, array $keys ) {
$names = [];
foreach ( $keys as $k ) {
$names[$k] = "$prefix-$k-" . wfRandomString( 6 );
}
return $names;
}
/**
* @param string $xmlData
* @param string[] $pageTitles
*
* @return string
*/
private function injectPageTitles( string $xmlData, array $pageTitles ) {
$keys = array_map( static function ( $name ) {
return "{{{$name}_title}}";
}, array_keys( $pageTitles ) );
return str_replace(
$keys,
array_values( $pageTitles ),
$xmlData
);
}
/**
* @param Title $title
*
* @return RevisionRecord[]
*/
private function getRevisions( Title $title ) {
$store = MediaWikiServices::getInstance()->getRevisionStore();
$qi = $store->getQueryInfo();
$conds = [ 'rev_page' => $title->getArticleID() ];
$opt = [ 'ORDER BY' => 'rev_id ASC' ];
$rows = $this->db->select(
$qi['tables'],
$qi['fields'],
$conds,
__METHOD__,
$opt,
$qi['joins']
);
$status = $store->newRevisionsFromBatch( $rows );
return $status->getValue();
}
/**
* @param string[] $pageTitles
*
* @return string[]
*/
private function getPageInfoVars( array $pageTitles ) {
$vars = [];
foreach ( $pageTitles as $name => $page ) {
$title = Title::newFromText( $page );
if ( !$title->exists( Title::READ_LATEST ) ) {
// map only existing pages, since only they can appear in a dump
continue;
}
$vars[ $name . '_pageid' ] = $title->getArticleID();
$vars[ $name . '_title' ] = $title->getPrefixedDBkey();
$vars[ $name . '_namespace' ] = $title->getNamespace();
$n = 1;
$revisions = $this->getRevisions( $title );
foreach ( $revisions as $i => $rev ) {
$revkey = "{$name}_rev" . $n++;
$vars[ $revkey . '_id' ] = $rev->getId();
$vars[ $revkey . '_userid' ] = $rev->getUser()->getId();
}
}
return $vars;
}
/**
* @param string $schemaVersion
* @return string[]
*/
private function getSiteVars( $schemaVersion ) {
global $wgSitename, $wgDBname, $wgVersion, $wgCapitalLinks;
$vars = [];
$vars['mw_version'] = $wgVersion;
$vars['schema_version'] = $schemaVersion;
$vars['site_name'] = $wgSitename;
$vars['project_namespace'] =
MediaWikiServices::getInstance()->getTitleFormatter()->getNamespaceName(
NS_PROJECT,
'Dummy'
);
$vars['site_db'] = $wgDBname;
$vars['site_case'] = $wgCapitalLinks ? 'first-letter' : 'case-sensitive';
$vars['site_base'] = Title::newMainPage()->getCanonicalURL();
$vars['site_language'] = MediaWikiServices::getInstance()->getContentLanguage()->getHtmlCode();
return $vars;
}
public function provideImportExport() {
foreach ( XmlDumpWriter::$supportedSchemas as $schemaVersion ) {
yield [ 'Basic', $schemaVersion ];
yield [ 'Dupes', $schemaVersion ];
yield [ 'Slots', $schemaVersion ];
yield [ 'Interleaved', $schemaVersion ];
yield [ 'InterleavedMulti', $schemaVersion ];
yield [ 'MissingMainContentModel', $schemaVersion ];
yield [ 'MissingSlotContentModel', $schemaVersion ];
}
}
/**
* @dataProvider provideImportExport
*/
public function testImportExport( $testName, $schemaVersion ) {
$asserter = new DumpAsserter( $schemaVersion );
$filesToImport = $this->getFilesToImport( $testName );
$fileToExpect = $this->getDumpTemplatePath( "$testName.expected", $schemaVersion );
$siteInfoExpect = $this->getDumpTemplatePath( 'SiteInfo', $schemaVersion );
$pageKeys = [ 'page1', 'page2', 'page3', 'page4', ];
$pageTitles = $this->getUniqueNames( $testName, $pageKeys );
// import each file
foreach ( $filesToImport as $fileName ) {
$xmlData = file_get_contents( $fileName );
$xmlData = $this->injectPageTitles( $xmlData, $pageTitles );
$source = new ImportStringSource( $xmlData );
$importer = $this->getImporter( $source );
$importer->doImport();
}
// write dump
$exporter = $this->getExporter( $schemaVersion );
$tmpFile = $this->getNewTempFile();
$buffer = new DumpFileOutput( $tmpFile );
$exporter->setOutputSink( $buffer );
$exporter->openStream();
$exporter->pagesByName( $pageTitles );
$exporter->closeStream();
// determine expected variable values
$vars = array_merge(
$this->getSiteVars( $schemaVersion ),
$this->getPageInfoVars( $pageTitles )
);
foreach ( $vars as $key => $value ) {
$asserter->setVarMapping( $key, $value );
}
// sanity check
$dumpData = file_get_contents( $tmpFile );
$this->assertNotEmpty( $dumpData, 'Dump XML' );
// check dump content
$asserter->assertDumpStart( $tmpFile, $siteInfoExpect );
$asserter->assertDOM( $fileToExpect );
$asserter->assertDumpEnd();
}
}