Merge "Add config for serving main Page from the domain root"
[lhc/web/wiklou.git] / tests / phpunit / includes / content / WikitextContentHandlerTest.php
1 <?php
2
3 use MediaWiki\MediaWikiServices;
4 use MediaWiki\Revision\SlotRecord;
5 use MediaWiki\Revision\SlotRenderingProvider;
6
7 /**
8 * @group ContentHandler
9 */
10 class WikitextContentHandlerTest extends MediaWikiLangTestCase {
11 /**
12 * @var ContentHandler
13 */
14 private $handler;
15
16 protected function setUp() {
17 parent::setUp();
18
19 $this->handler = ContentHandler::getForModelID( CONTENT_MODEL_WIKITEXT );
20 }
21
22 /**
23 * @covers WikitextContentHandler::serializeContent
24 */
25 public function testSerializeContent() {
26 $content = new WikitextContent( 'hello world' );
27
28 $this->assertEquals( 'hello world', $this->handler->serializeContent( $content ) );
29 $this->assertEquals(
30 'hello world',
31 $this->handler->serializeContent( $content, CONTENT_FORMAT_WIKITEXT )
32 );
33
34 try {
35 $this->handler->serializeContent( $content, 'dummy/foo' );
36 $this->fail( "serializeContent() should have failed on unknown format" );
37 } catch ( MWException $e ) {
38 // ok, as expected
39 }
40 }
41
42 /**
43 * @covers WikitextContentHandler::unserializeContent
44 */
45 public function testUnserializeContent() {
46 $content = $this->handler->unserializeContent( 'hello world' );
47 $this->assertEquals( 'hello world', $content->getText() );
48
49 $content = $this->handler->unserializeContent( 'hello world', CONTENT_FORMAT_WIKITEXT );
50 $this->assertEquals( 'hello world', $content->getText() );
51
52 try {
53 $this->handler->unserializeContent( 'hello world', 'dummy/foo' );
54 $this->fail( "unserializeContent() should have failed on unknown format" );
55 } catch ( MWException $e ) {
56 // ok, as expected
57 }
58 }
59
60 /**
61 * @covers WikitextContentHandler::makeEmptyContent
62 */
63 public function testMakeEmptyContent() {
64 $content = $this->handler->makeEmptyContent();
65
66 $this->assertTrue( $content->isEmpty() );
67 $this->assertSame( '', $content->getText() );
68 }
69
70 public static function dataIsSupportedFormat() {
71 return [
72 [ null, true ],
73 [ CONTENT_FORMAT_WIKITEXT, true ],
74 [ 99887766, false ],
75 ];
76 }
77
78 /**
79 * @dataProvider provideMakeRedirectContent
80 * @param Title|string $title Title object or string for Title::newFromText()
81 * @param string $expected Serialized form of the content object built
82 * @covers WikitextContentHandler::makeRedirectContent
83 */
84 public function testMakeRedirectContent( $title, $expected ) {
85 MediaWikiServices::getInstance()->getContentLanguage()->resetNamespaces();
86
87 MediaWikiServices::getInstance()->resetServiceForTesting( 'MagicWordFactory' );
88
89 if ( is_string( $title ) ) {
90 $title = Title::newFromText( $title );
91 }
92 $content = $this->handler->makeRedirectContent( $title );
93 $this->assertEquals( $expected, $content->serialize() );
94 }
95
96 public static function provideMakeRedirectContent() {
97 return [
98 [ 'Hello', '#REDIRECT [[Hello]]' ],
99 [ 'Template:Hello', '#REDIRECT [[Template:Hello]]' ],
100 [ 'Hello#section', '#REDIRECT [[Hello#section]]' ],
101 [ 'user:john_doe#section', '#REDIRECT [[User:John doe#section]]' ],
102 [ 'MEDIAWIKI:FOOBAR', '#REDIRECT [[MediaWiki:FOOBAR]]' ],
103 [ 'Category:Foo', '#REDIRECT [[:Category:Foo]]' ],
104 [ Title::makeTitle( NS_MAIN, 'en:Foo' ), '#REDIRECT [[en:Foo]]' ],
105 [ Title::makeTitle( NS_MAIN, 'Foo', '', 'en' ), '#REDIRECT [[:en:Foo]]' ],
106 [
107 Title::makeTitle( NS_MAIN, 'Bar', 'fragment', 'google' ),
108 '#REDIRECT [[google:Bar#fragment]]'
109 ],
110 ];
111 }
112
113 /**
114 * @dataProvider dataIsSupportedFormat
115 * @covers WikitextContentHandler::isSupportedFormat
116 */
117 public function testIsSupportedFormat( $format, $supported ) {
118 $this->assertEquals( $supported, $this->handler->isSupportedFormat( $format ) );
119 }
120
121 /**
122 * @covers WikitextContentHandler::supportsDirectEditing
123 */
124 public function testSupportsDirectEditing() {
125 $handler = new WikiTextContentHandler();
126 $this->assertTrue( $handler->supportsDirectEditing(), 'direct editing is supported' );
127 }
128
129 public static function dataMerge3() {
130 return [
131 [
132 "first paragraph
133
134 second paragraph\n",
135
136 "FIRST paragraph
137
138 second paragraph\n",
139
140 "first paragraph
141
142 SECOND paragraph\n",
143
144 "FIRST paragraph
145
146 SECOND paragraph\n",
147 ],
148
149 [ "first paragraph
150 second paragraph\n",
151
152 "Bla bla\n",
153
154 "Blubberdibla\n",
155
156 false,
157 ],
158 ];
159 }
160
161 /**
162 * @dataProvider dataMerge3
163 * @covers WikitextContentHandler::merge3
164 */
165 public function testMerge3( $old, $mine, $yours, $expected ) {
166 $this->markTestSkippedIfNoDiff3();
167
168 // test merge
169 $oldContent = new WikitextContent( $old );
170 $myContent = new WikitextContent( $mine );
171 $yourContent = new WikitextContent( $yours );
172
173 $merged = $this->handler->merge3( $oldContent, $myContent, $yourContent );
174
175 $this->assertEquals( $expected, $merged ? $merged->getText() : $merged );
176 }
177
178 public static function dataGetAutosummary() {
179 return [
180 [
181 'Hello there, world!',
182 '#REDIRECT [[Foo]]',
183 0,
184 '/^Redirected page .*Foo/'
185 ],
186
187 [
188 null,
189 'Hello world!',
190 EDIT_NEW,
191 '/^Created page .*Hello/'
192 ],
193
194 [
195 null,
196 '',
197 EDIT_NEW,
198 '/^Created blank page$/'
199 ],
200
201 [
202 'Hello there, world!',
203 '',
204 0,
205 '/^Blanked/'
206 ],
207
208 [
209 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
210 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
211 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
212 clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
213 'Hello world!',
214 0,
215 '/^Replaced .*Hello/'
216 ],
217
218 [
219 'foo',
220 'bar',
221 0,
222 '/^$/'
223 ],
224 ];
225 }
226
227 /**
228 * @dataProvider dataGetAutosummary
229 * @covers WikitextContentHandler::getAutosummary
230 */
231 public function testGetAutosummary( $old, $new, $flags, $expected ) {
232 $oldContent = is_null( $old ) ? null : new WikitextContent( $old );
233 $newContent = is_null( $new ) ? null : new WikitextContent( $new );
234
235 $summary = $this->handler->getAutosummary( $oldContent, $newContent, $flags );
236
237 $this->assertTrue(
238 (bool)preg_match( $expected, $summary ),
239 "Autosummary didn't match expected pattern $expected: $summary"
240 );
241 }
242
243 public static function dataGetChangeTag() {
244 return [
245 [
246 null,
247 '#REDIRECT [[Foo]]',
248 0,
249 'mw-new-redirect'
250 ],
251
252 [
253 'Lorem ipsum dolor',
254 '#REDIRECT [[Foo]]',
255 0,
256 'mw-new-redirect'
257 ],
258
259 [
260 '#REDIRECT [[Foo]]',
261 'Lorem ipsum dolor',
262 0,
263 'mw-removed-redirect'
264 ],
265
266 [
267 '#REDIRECT [[Foo]]',
268 '#REDIRECT [[Bar]]',
269 0,
270 'mw-changed-redirect-target'
271 ],
272
273 [
274 null,
275 'Lorem ipsum dolor',
276 EDIT_NEW,
277 null // mw-newpage is not defined as a tag
278 ],
279
280 [
281 null,
282 '',
283 EDIT_NEW,
284 null // mw-newblank is not defined as a tag
285 ],
286
287 [
288 'Lorem ipsum dolor',
289 '',
290 0,
291 'mw-blank'
292 ],
293
294 [
295 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
296 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
297 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
298 clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
299 'Ipsum',
300 0,
301 'mw-replace'
302 ],
303
304 [
305 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
306 eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam
307 voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet
308 clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
309 'Duis purus odio, rhoncus et finibus dapibus, facilisis ac urna. Pellentesque
310 arcu, tristique nec tempus nec, suscipit vel arcu. Sed non dolor nec ligula
311 congue tempor. Quisque pellentesque finibus orci a molestie. Nam maximus, purus
312 euismod finibus mollis, dui ante malesuada felis, dignissim rutrum diam sapien.',
313 0,
314 null
315 ],
316 ];
317 }
318
319 /**
320 * @dataProvider dataGetChangeTag
321 * @covers WikitextContentHandler::getChangeTag
322 */
323 public function testGetChangeTag( $old, $new, $flags, $expected ) {
324 $this->setMwGlobals( 'wgSoftwareTags', [
325 'mw-new-redirect' => true,
326 'mw-removed-redirect' => true,
327 'mw-changed-redirect-target' => true,
328 'mw-newpage' => true,
329 'mw-newblank' => true,
330 'mw-blank' => true,
331 'mw-replace' => true,
332 ] );
333 $oldContent = is_null( $old ) ? null : new WikitextContent( $old );
334 $newContent = is_null( $new ) ? null : new WikitextContent( $new );
335
336 $tag = $this->handler->getChangeTag( $oldContent, $newContent, $flags );
337
338 $this->assertSame( $expected, $tag );
339 }
340
341 /**
342 * @covers WikitextContentHandler::getDataForSearchIndex
343 */
344 public function testDataIndexFieldsFile() {
345 $mockEngine = $this->createMock( SearchEngine::class );
346 $title = Title::newFromText( 'Somefile.jpg', NS_FILE );
347 $page = new WikiPage( $title );
348
349 $fileHandler = $this->getMockBuilder( FileContentHandler::class )
350 ->disableOriginalConstructor()
351 ->setMethods( [ 'getDataForSearchIndex' ] )
352 ->getMock();
353
354 $handler = $this->getMockBuilder( WikitextContentHandler::class )
355 ->disableOriginalConstructor()
356 ->setMethods( [ 'getFileHandler' ] )
357 ->getMock();
358
359 $handler->method( 'getFileHandler' )->will( $this->returnValue( $fileHandler ) );
360 $fileHandler->expects( $this->once() )
361 ->method( 'getDataForSearchIndex' )
362 ->will( $this->returnValue( [ 'file_text' => 'This is file content' ] ) );
363
364 $data = $handler->getDataForSearchIndex( $page, new ParserOutput(), $mockEngine );
365 $this->assertArrayHasKey( 'file_text', $data );
366 $this->assertEquals( 'This is file content', $data['file_text'] );
367 }
368
369 /**
370 * @covers ContentHandler::getSecondaryDataUpdates
371 */
372 public function testGetSecondaryDataUpdates() {
373 $title = Title::newFromText( 'Somefile.jpg', NS_FILE );
374 $content = new WikitextContent( '' );
375
376 /** @var SlotRenderingProvider $srp */
377 $srp = $this->getMock( SlotRenderingProvider::class );
378
379 $handler = new WikitextContentHandler();
380 $updates = $handler->getSecondaryDataUpdates( $title, $content, SlotRecord::MAIN, $srp );
381
382 $this->assertEquals( [], $updates );
383 }
384
385 /**
386 * @covers ContentHandler::getDeletionUpdates
387 */
388 public function testGetDeletionUpdates() {
389 $title = Title::newFromText( 'Somefile.jpg', NS_FILE );
390 $content = new WikitextContent( '' );
391
392 $srp = $this->getMock( SlotRenderingProvider::class );
393
394 $handler = new WikitextContentHandler();
395 $updates = $handler->getDeletionUpdates( $title, SlotRecord::MAIN );
396
397 $this->assertEquals( [], $updates );
398 }
399
400 }