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