1<?php 2 3use MediaWiki\MediaWikiServices; 4 5/** 6 * Import failure test. 7 * 8 * @group Database 9 * @covers WikiImporter 10 */ 11class ImportFailureTest extends MediaWikiLangTestCase { 12 13 public function setUp(): void { 14 parent::setUp(); 15 16 $slotRoleRegistry = MediaWikiServices::getInstance()->getSlotRoleRegistry(); 17 18 if ( !$slotRoleRegistry->isDefinedRole( 'ImportFailureTest' ) ) { 19 $slotRoleRegistry->defineRoleWithModel( 'ImportFailureTest', CONTENT_MODEL_WIKITEXT ); 20 } 21 } 22 23 /** 24 * @param ImportSource $source 25 * 26 * @return WikiImporter 27 */ 28 private function getImporter( ImportSource $source ) { 29 $config = new HashConfig( [ 30 'CommandLineMode' => true, 31 ] ); 32 $importer = new WikiImporter( $source, $config ); 33 return $importer; 34 } 35 36 /** 37 * @param string $testName 38 * 39 * @return string[] 40 */ 41 private function getFileToImport( string $testName ) { 42 return __DIR__ . "/../../data/import/$testName.xml"; 43 } 44 45 /** 46 * @param string $prefix 47 * 48 * @return string[] 49 */ 50 private function getUniqueNames( string $prefix, array $keys ) { 51 $names = []; 52 53 foreach ( $keys as $k ) { 54 $names[$k] = "$prefix-$k-" . wfRandomString( 6 ); 55 } 56 57 return $names; 58 } 59 60 /** 61 * @param string $xmlData 62 * @param string[] pageTitles 63 * 64 * @return string 65 */ 66 private function injectPageTitles( string $xmlData, array $pageTitles ) { 67 $keys = array_map( function ( $name ) { 68 return "{{{$name}_title}}"; 69 }, array_keys( $pageTitles ) ); 70 71 return str_replace( 72 $keys, 73 array_values( $pageTitles ), 74 $xmlData 75 ); 76 } 77 78 public function provideImportFailure() { 79 yield [ 'BadXML', 'PHPUnit\Framework\Error\Warning', '/^XMLReader::read\(\): .*$/' ]; 80 yield [ 'MissingMediaWikiTag', 'MWException', '/^Expected <mediawiki> tag, got .*$/' ]; 81 yield [ 'MissingMainTextField', 'MWException', '/^Missing text field in import.$/' ]; 82 yield [ 'MissingSlotTextField', 'MWException', '/^Missing text field in import.$/' ]; 83 yield [ 'MissingSlotRole', 'MWException', '/^Missing role for imported slot.$/' ]; 84 yield [ 'UndefinedSlotRole', 'MWException', '/^Undefined slot role .*$/' ]; 85 yield [ 'UndefinedContentModel', 'MWException', '/not registered on this wiki/' ]; 86 } 87 88 /** 89 * @dataProvider provideImportFailure 90 */ 91 public function testImportFailure( $testName, $exceptionName, $exceptionMessage ) { 92 $fileName = $this->getFileToImport( $testName ); 93 94 $pageKeys = [ 'page1', 'page2', 'page3', 'page4', ]; 95 $pageTitles = $this->getUniqueNames( $testName, $pageKeys ); 96 97 $xmlData = file_get_contents( $fileName ); 98 $xmlData = $this->injectPageTitles( $xmlData, $pageTitles ); 99 100 $source = new ImportStringSource( $xmlData ); 101 $importer = $this->getImporter( $source ); 102 $this->expectException( $exceptionName ); 103 $this->expectExceptionMessageMatches( $exceptionMessage ); 104 $importer->doImport(); 105 } 106} 107