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