Merge "Type hint against LinkTarget in WatchedItemStore"
[lhc/web/wiklou.git] / tests / phpunit / includes / import / ImportTest.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4
5 /**
6 * Test class for Import methods.
7 *
8 * @group Database
9 *
10 * @author Sebastian Brückner < sebastian.brueckner@student.hpi.uni-potsdam.de >
11 */
12 class ImportTest extends MediaWikiLangTestCase {
13
14 /**
15 * @covers WikiImporter
16 * @dataProvider getUnknownTagsXML
17 * @param string $xml
18 * @param string $text
19 * @param string $title
20 */
21 public function testUnknownXMLTags( $xml, $text, $title ) {
22 $source = new ImportStringSource( $xml );
23
24 $importer = new WikiImporter(
25 $source,
26 MediaWikiServices::getInstance()->getMainConfig()
27 );
28
29 $importer->doImport();
30 $title = Title::newFromText( $title );
31 $this->assertTrue( $title->exists() );
32
33 $this->assertEquals( WikiPage::factory( $title )->getContent()->getText(), $text );
34 }
35
36 public function getUnknownTagsXML() {
37 // phpcs:disable Generic.Files.LineLength
38 return [
39 [
40 <<< EOF
41 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
42 <page unknown="123" dontknow="533">
43 <title>TestImportPage</title>
44 <unknowntag>Should be ignored</unknowntag>
45 <ns>0</ns>
46 <id unknown="123" dontknow="533">14</id>
47 <revision>
48 <id unknown="123" dontknow="533">15</id>
49 <unknowntag>Should be ignored</unknowntag>
50 <timestamp>2016-01-03T11:18:43Z</timestamp>
51 <contributor>
52 <unknowntag>Should be ignored</unknowntag>
53 <username unknown="123" dontknow="533">Admin</username>
54 <id>1</id>
55 </contributor>
56 <model>wikitext</model>
57 <format>text/x-wiki</format>
58 <text xml:space="preserve" bytes="0">noitazinagro tseb eht si ikiWaideM</text>
59 <sha1>phoiac9h4m842xq45sp7s6u21eteeq1</sha1>
60 <unknowntag>Should be ignored</unknowntag>
61 </revision>
62 </page>
63 <unknowntag>Should be ignored</unknowntag>
64 </mediawiki>
65 EOF
66 ,
67 'noitazinagro tseb eht si ikiWaideM',
68 'TestImportPage'
69 ]
70 ];
71 // phpcs:enable
72 }
73
74 /**
75 * @covers WikiImporter::handlePage
76 * @dataProvider getRedirectXML
77 * @param string $xml
78 * @param string|null $redirectTitle
79 */
80 public function testHandlePageContainsRedirect( $xml, $redirectTitle ) {
81 $source = new ImportStringSource( $xml );
82
83 $redirect = null;
84 $callback = function ( Title $title, ForeignTitle $foreignTitle, $revCount,
85 $sRevCount, $pageInfo ) use ( &$redirect ) {
86 if ( array_key_exists( 'redirect', $pageInfo ) ) {
87 $redirect = $pageInfo['redirect'];
88 }
89 };
90
91 $importer = new WikiImporter(
92 $source,
93 MediaWikiServices::getInstance()->getMainConfig()
94 );
95 $importer->setPageOutCallback( $callback );
96 $importer->doImport();
97
98 $this->assertEquals( $redirectTitle, $redirect );
99 }
100
101 public function getRedirectXML() {
102 // phpcs:disable Generic.Files.LineLength
103 return [
104 [
105 <<< EOF
106 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
107 <page>
108 <title>Test</title>
109 <ns>0</ns>
110 <id>21</id>
111 <redirect title="Test22"/>
112 <revision>
113 <id>20</id>
114 <timestamp>2014-05-27T10:00:00Z</timestamp>
115 <contributor>
116 <username>Admin</username>
117 <id>10</id>
118 </contributor>
119 <comment>Admin moved page [[Test]] to [[Test22]]</comment>
120 <model>wikitext</model>
121 <format>text/x-wiki</format>
122 <text xml:space="preserve" bytes="20">#REDIRECT [[Test22]]</text>
123 <sha1>tq456o9x3abm7r9ozi6km8yrbbc56o6</sha1>
124 </revision>
125 </page>
126 </mediawiki>
127 EOF
128 ,
129 'Test22'
130 ],
131 [
132 <<< EOF
133 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.9/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.9/ http://www.mediawiki.org/xml/export-0.9.xsd" version="0.9" xml:lang="en">
134 <page>
135 <title>Test</title>
136 <ns>0</ns>
137 <id>42</id>
138 <revision>
139 <id>421</id>
140 <timestamp>2014-05-27T11:00:00Z</timestamp>
141 <contributor>
142 <username>Admin</username>
143 <id>10</id>
144 </contributor>
145 <text xml:space="preserve" bytes="4">Abcd</text>
146 <sha1>n7uomjq96szt60fy5w3x7ahf7q8m8rh</sha1>
147 <model>wikitext</model>
148 <format>text/x-wiki</format>
149 </revision>
150 </page>
151 </mediawiki>
152 EOF
153 ,
154 null
155 ],
156 ];
157 // phpcs:enable
158 }
159
160 /**
161 * @covers WikiImporter::handleSiteInfo
162 * @dataProvider getSiteInfoXML
163 * @param string $xml
164 * @param array|null $namespaces
165 */
166 public function testSiteInfoContainsNamespaces( $xml, $namespaces ) {
167 $source = new ImportStringSource( $xml );
168
169 $importNamespaces = null;
170 $callback = function ( array $siteinfo, $innerImporter ) use ( &$importNamespaces ) {
171 $importNamespaces = $siteinfo['_namespaces'];
172 };
173
174 $importer = new WikiImporter(
175 $source,
176 MediaWikiServices::getInstance()->getMainConfig()
177 );
178 $importer->setSiteInfoCallback( $callback );
179 $importer->doImport();
180
181 $this->assertEquals( $importNamespaces, $namespaces );
182 }
183
184 public function getSiteInfoXML() {
185 // phpcs:disable Generic.Files.LineLength
186 return [
187 [
188 <<< EOF
189 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
190 <siteinfo>
191 <namespaces>
192 <namespace key="-2" case="first-letter">Media</namespace>
193 <namespace key="-1" case="first-letter">Special</namespace>
194 <namespace key="0" case="first-letter" />
195 <namespace key="1" case="first-letter">Talk</namespace>
196 <namespace key="2" case="first-letter">User</namespace>
197 <namespace key="3" case="first-letter">User talk</namespace>
198 <namespace key="100" case="first-letter">Portal</namespace>
199 <namespace key="101" case="first-letter">Portal talk</namespace>
200 </namespaces>
201 </siteinfo>
202 </mediawiki>
203 EOF
204 ,
205 [
206 '-2' => 'Media',
207 '-1' => 'Special',
208 '0' => '',
209 '1' => 'Talk',
210 '2' => 'User',
211 '3' => 'User talk',
212 '100' => 'Portal',
213 '101' => 'Portal talk',
214 ]
215 ],
216 ];
217 // phpcs:enable
218 }
219
220 /**
221 * @dataProvider provideUnknownUserHandling
222 * @covers WikiImporter::setUsernamePrefix
223 * @covers ExternalUserNames::addPrefix
224 * @covers ExternalUserNames::applyPrefix
225 * @param bool $assign
226 * @param bool $create
227 */
228 public function testUnknownUserHandling( $assign, $create ) {
229 $hookId = -99;
230 $this->setMwGlobals( 'wgHooks', [
231 'ImportHandleUnknownUser' => [ function ( $name ) use ( $assign, $create, &$hookId ) {
232 if ( !$assign ) {
233 $this->fail( 'ImportHandleUnknownUser was called unexpectedly' );
234 }
235
236 $this->assertEquals( 'UserDoesNotExist', $name );
237 if ( $create ) {
238 $user = User::createNew( $name );
239 $this->assertNotNull( $user );
240 $hookId = $user->getId();
241 return false;
242 }
243 return true;
244 } ]
245 ] );
246
247 $user = $this->getTestUser()->getUser();
248
249 $n = ( $assign ? 1 : 0 ) + ( $create ? 2 : 0 );
250
251 // phpcs:disable Generic.Files.LineLength
252 $source = new ImportStringSource( <<<EOF
253 <mediawiki xmlns="http://www.mediawiki.org/xml/export-0.10/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mediawiki.org/xml/export-0.10/ http://www.mediawiki.org/xml/export-0.10.xsd" version="0.10" xml:lang="en">
254 <page>
255 <title>TestImportPage</title>
256 <ns>0</ns>
257 <id>14</id>
258 <revision>
259 <id>15</id>
260 <timestamp>2016-01-01T0$n:00:00Z</timestamp>
261 <contributor>
262 <username>UserDoesNotExist</username>
263 <id>1</id>
264 </contributor>
265 <model>wikitext</model>
266 <format>text/x-wiki</format>
267 <text xml:space="preserve" bytes="3">foo</text>
268 <sha1>1e6gpc3ehk0mu2jqu8cg42g009s796b</sha1>
269 </revision>
270 <revision>
271 <id>16</id>
272 <timestamp>2016-01-01T0$n:00:01Z</timestamp>
273 <contributor>
274 <username>{$user->getName()}</username>
275 <id>{$user->getId()}</id>
276 </contributor>
277 <model>wikitext</model>
278 <format>text/x-wiki</format>
279 <text xml:space="preserve" bytes="3">bar</text>
280 <sha1>bjhlo6dxh5wivnszm93u4b78fheiy4t</sha1>
281 </revision>
282 </page>
283 </mediawiki>
284 EOF
285 );
286 // phpcs:enable
287
288 $importer = new WikiImporter( $source, MediaWikiServices::getInstance()->getMainConfig() );
289 $importer->setUsernamePrefix( 'Xxx', $assign );
290 $importer->doImport();
291
292 $db = wfGetDB( DB_MASTER );
293 $revQuery = Revision::getQueryInfo();
294
295 $row = $db->selectRow(
296 $revQuery['tables'],
297 $revQuery['fields'],
298 [ 'rev_timestamp' => $db->timestamp( "201601010{$n}0000" ) ],
299 __METHOD__,
300 [],
301 $revQuery['joins']
302 );
303 $this->assertSame(
304 $assign && $create ? 'UserDoesNotExist' : 'Xxx>UserDoesNotExist',
305 $row->rev_user_text
306 );
307 $this->assertSame( $assign && $create ? $hookId : 0, (int)$row->rev_user );
308
309 $row = $db->selectRow(
310 $revQuery['tables'],
311 $revQuery['fields'],
312 [ 'rev_timestamp' => $db->timestamp( "201601010{$n}0001" ) ],
313 __METHOD__,
314 [],
315 $revQuery['joins']
316 );
317 $this->assertSame( ( $assign ? '' : 'Xxx>' ) . $user->getName(), $row->rev_user_text );
318 $this->assertSame( $assign ? $user->getId() : 0, (int)$row->rev_user );
319 }
320
321 public static function provideUnknownUserHandling() {
322 return [
323 'no assign' => [ false, false ],
324 'assign, no create' => [ true, false ],
325 'assign, create' => [ true, true ],
326 ];
327 }
328
329 }