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