Implement static public Parser::getExternalLinkRel
[lhc/web/wiklou.git] / tests / phpunit / includes / WikiPageTest.php
1 <?php
2 /**
3 * @group ContentHandler
4 * @group Database
5 * ^--- important, causes temporary tables to be used instead of the real database
6 * @group medium
7 **/
8
9 class WikiPageTest extends MediaWikiLangTestCase {
10
11 var $pages_to_delete;
12
13 function __construct( $name = null, array $data = array(), $dataName = '' ) {
14 parent::__construct( $name, $data, $dataName );
15
16 $this->tablesUsed = array_merge (
17 $this->tablesUsed,
18 array( 'page',
19 'revision',
20 'text',
21
22 'recentchanges',
23 'logging',
24
25 'page_props',
26 'pagelinks',
27 'categorylinks',
28 'langlinks',
29 'externallinks',
30 'imagelinks',
31 'templatelinks',
32 'iwlinks' ) );
33 }
34
35 protected function setUp() {
36 parent::setUp();
37 $this->pages_to_delete = array();
38
39 LinkCache::singleton()->clear(); # avoid cached redirect status, etc
40 }
41
42 protected function tearDown() {
43 foreach ( $this->pages_to_delete as $p ) {
44 /* @var $p WikiPage */
45
46 try {
47 if ( $p->exists() ) {
48 $p->doDeleteArticle( "testing done." );
49 }
50 } catch ( MWException $ex ) {
51 // fail silently
52 }
53 }
54 parent::tearDown();
55 }
56
57 /**
58 * @param Title $title
59 * @param String $model
60 * @return WikiPage
61 */
62 protected function newPage( $title, $model = null ) {
63 if ( is_string( $title ) ) {
64 $ns = $this->getDefaultWikitextNS();
65 $title = Title::newFromText( $title, $ns );
66 }
67
68 $p = new WikiPage( $title );
69
70 $this->pages_to_delete[] = $p;
71
72 return $p;
73 }
74
75
76 /**
77 * @param String|Title|WikiPage $page
78 * @param String $text
79 * @param int $model
80 *
81 * @return WikiPage
82 */
83 protected function createPage( $page, $text, $model = null ) {
84 if ( is_string( $page ) || $page instanceof Title ) {
85 $page = $this->newPage( $page, $model );
86 }
87
88 $content = ContentHandler::makeContent( $text, $page->getTitle(), $model );
89 $page->doEditContent( $content, "testing", EDIT_NEW );
90
91 return $page;
92 }
93
94 public function testDoEditContent() {
95 $page = $this->newPage( "WikiPageTest_testDoEditContent" );
96 $title = $page->getTitle();
97
98 $content = ContentHandler::makeContent( "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
99 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
100 $title, CONTENT_MODEL_WIKITEXT );
101
102 $page->doEditContent( $content, "[[testing]] 1" );
103
104 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
105 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
106 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
107 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
108
109 $id = $page->getId();
110
111 # ------------------------
112 $dbr = wfGetDB( DB_SLAVE );
113 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
114 $n = $res->numRows();
115 $res->free();
116
117 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
118
119 # ------------------------
120 $page = new WikiPage( $title );
121
122 $retrieved = $page->getContent();
123 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
124
125 # ------------------------
126 $content = ContentHandler::makeContent( "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
127 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.",
128 $title, CONTENT_MODEL_WIKITEXT );
129
130 $page->doEditContent( $content, "testing 2" );
131
132 # ------------------------
133 $page = new WikiPage( $title );
134
135 $retrieved = $page->getContent();
136 $this->assertTrue( $content->equals( $retrieved ), 'retrieved content doesn\'t equal original' );
137
138 # ------------------------
139 $dbr = wfGetDB( DB_SLAVE );
140 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
141 $n = $res->numRows();
142 $res->free();
143
144 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
145 }
146
147 public function testDoEdit() {
148 $this->hideDeprecated( "WikiPage::doEdit" );
149 $this->hideDeprecated( "WikiPage::getText" );
150 $this->hideDeprecated( "Revision::getText" );
151
152 //NOTE: assume help namespace will default to wikitext
153 $title = Title::newFromText( "Help:WikiPageTest_testDoEdit" );
154
155 $page = $this->newPage( $title );
156
157 $text = "[[Lorem ipsum]] dolor sit amet, consetetur sadipscing elitr, sed diam "
158 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.";
159
160 $page->doEdit( $text, "[[testing]] 1" );
161
162 $this->assertTrue( $title->getArticleID() > 0, "Title object should have new page id" );
163 $this->assertTrue( $page->getId() > 0, "WikiPage should have new page id" );
164 $this->assertTrue( $title->exists(), "Title object should indicate that the page now exists" );
165 $this->assertTrue( $page->exists(), "WikiPage object should indicate that the page now exists" );
166
167 $id = $page->getId();
168
169 # ------------------------
170 $dbr = wfGetDB( DB_SLAVE );
171 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
172 $n = $res->numRows();
173 $res->free();
174
175 $this->assertEquals( 1, $n, 'pagelinks should contain one link from the page' );
176
177 # ------------------------
178 $page = new WikiPage( $title );
179
180 $retrieved = $page->getText();
181 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
182
183 # ------------------------
184 $text = "At vero eos et accusam et justo duo [[dolores]] et ea rebum. "
185 . "Stet clita kasd [[gubergren]], no sea takimata sanctus est.";
186
187 $page->doEdit( $text, "testing 2" );
188
189 # ------------------------
190 $page = new WikiPage( $title );
191
192 $retrieved = $page->getText();
193 $this->assertEquals( $text, $retrieved, 'retrieved text doesn\'t equal original' );
194
195 # ------------------------
196 $dbr = wfGetDB( DB_SLAVE );
197 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
198 $n = $res->numRows();
199 $res->free();
200
201 $this->assertEquals( 2, $n, 'pagelinks should contain two links from the page' );
202 }
203
204 public function testDoQuickEdit() {
205 global $wgUser;
206
207 $this->hideDeprecated( "WikiPage::doQuickEdit" );
208
209 //NOTE: assume help namespace will default to wikitext
210 $page = $this->createPage( "Help:WikiPageTest_testDoQuickEdit", "original text" );
211
212 $text = "quick text";
213 $page->doQuickEdit( $text, $wgUser, "testing q" );
214
215 # ---------------------
216 $page = new WikiPage( $page->getTitle() );
217 $this->assertEquals( $text, $page->getText() );
218 }
219
220 public function testDoQuickEditContent() {
221 global $wgUser;
222
223 $page = $this->createPage( "WikiPageTest_testDoQuickEditContent", "original text", CONTENT_MODEL_WIKITEXT );
224
225 $content = ContentHandler::makeContent( "quick text", $page->getTitle(), CONTENT_MODEL_WIKITEXT );
226 $page->doQuickEditContent( $content, $wgUser, "testing q" );
227
228 # ---------------------
229 $page = new WikiPage( $page->getTitle() );
230 $this->assertTrue( $content->equals( $page->getContent() ) );
231 }
232
233 public function testDoDeleteArticle() {
234 $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT );
235 $id = $page->getId();
236
237 $page->doDeleteArticle( "testing deletion" );
238
239 $this->assertFalse( $page->getTitle()->getArticleID() > 0, "Title object should now have page id 0" );
240 $this->assertFalse( $page->getId() > 0, "WikiPage should now have page id 0" );
241 $this->assertFalse( $page->exists(), "WikiPage::exists should return false after page was deleted" );
242 $this->assertNull( $page->getContent(), "WikiPage::getContent should return null after page was deleted" );
243 $this->assertFalse( $page->getText(), "WikiPage::getText should return false after page was deleted" );
244
245 $t = Title::newFromText( $page->getTitle()->getPrefixedText() );
246 $this->assertFalse( $t->exists(), "Title::exists should return false after page was deleted" );
247
248 # ------------------------
249 $dbr = wfGetDB( DB_SLAVE );
250 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
251 $n = $res->numRows();
252 $res->free();
253
254 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
255 }
256
257 public function testDoDeleteUpdates() {
258 $page = $this->createPage( "WikiPageTest_testDoDeleteArticle", "[[original text]] foo", CONTENT_MODEL_WIKITEXT );
259 $id = $page->getId();
260
261 $page->doDeleteUpdates( $id );
262
263 # ------------------------
264 $dbr = wfGetDB( DB_SLAVE );
265 $res = $dbr->select( 'pagelinks', '*', array( 'pl_from' => $id ) );
266 $n = $res->numRows();
267 $res->free();
268
269 $this->assertEquals( 0, $n, 'pagelinks should contain no more links from the page' );
270 }
271
272 public function testGetRevision() {
273 $page = $this->newPage( "WikiPageTest_testGetRevision" );
274
275 $rev = $page->getRevision();
276 $this->assertNull( $rev );
277
278 # -----------------
279 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
280
281 $rev = $page->getRevision();
282
283 $this->assertEquals( $page->getLatest(), $rev->getId() );
284 $this->assertEquals( "some text", $rev->getContent()->getNativeData() );
285 }
286
287 public function testGetContent() {
288 $page = $this->newPage( "WikiPageTest_testGetContent" );
289
290 $content = $page->getContent();
291 $this->assertNull( $content );
292
293 # -----------------
294 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
295
296 $content = $page->getContent();
297 $this->assertEquals( "some text", $content->getNativeData() );
298 }
299
300 public function testGetText() {
301 $this->hideDeprecated( "WikiPage::getText" );
302
303 $page = $this->newPage( "WikiPageTest_testGetText" );
304
305 $text = $page->getText();
306 $this->assertFalse( $text );
307
308 # -----------------
309 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
310
311 $text = $page->getText();
312 $this->assertEquals( "some text", $text );
313 }
314
315 public function testGetRawText() {
316 $this->hideDeprecated( "WikiPage::getRawText" );
317
318 $page = $this->newPage( "WikiPageTest_testGetRawText" );
319
320 $text = $page->getRawText();
321 $this->assertFalse( $text );
322
323 # -----------------
324 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
325
326 $text = $page->getRawText();
327 $this->assertEquals( "some text", $text );
328 }
329
330 public function testGetContentModel() {
331 global $wgContentHandlerUseDB;
332
333 if ( !$wgContentHandlerUseDB ) {
334 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
335 }
336
337 $page = $this->createPage( "WikiPageTest_testGetContentModel", "some text", CONTENT_MODEL_JAVASCRIPT );
338
339 $page = new WikiPage( $page->getTitle() );
340 $this->assertEquals( CONTENT_MODEL_JAVASCRIPT, $page->getContentModel() );
341 }
342
343 public function testGetContentHandler() {
344 global $wgContentHandlerUseDB;
345
346 if ( !$wgContentHandlerUseDB ) {
347 $this->markTestSkipped( '$wgContentHandlerUseDB is disabled' );
348 }
349
350 $page = $this->createPage( "WikiPageTest_testGetContentHandler", "some text", CONTENT_MODEL_JAVASCRIPT );
351
352 $page = new WikiPage( $page->getTitle() );
353 $this->assertEquals( 'JavaScriptContentHandler', get_class( $page->getContentHandler() ) );
354 }
355
356 public function testExists() {
357 $page = $this->newPage( "WikiPageTest_testExists" );
358 $this->assertFalse( $page->exists() );
359
360 # -----------------
361 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
362 $this->assertTrue( $page->exists() );
363
364 $page = new WikiPage( $page->getTitle() );
365 $this->assertTrue( $page->exists() );
366
367 # -----------------
368 $page->doDeleteArticle( "done testing" );
369 $this->assertFalse( $page->exists() );
370
371 $page = new WikiPage( $page->getTitle() );
372 $this->assertFalse( $page->exists() );
373 }
374
375 public static function provideHasViewableContent() {
376 return array(
377 array( 'WikiPageTest_testHasViewableContent', false, true ),
378 array( 'Special:WikiPageTest_testHasViewableContent', false ),
379 array( 'MediaWiki:WikiPageTest_testHasViewableContent', false ),
380 array( 'Special:Userlogin', true ),
381 array( 'MediaWiki:help', true ),
382 );
383 }
384
385 /**
386 * @dataProvider provideHasViewableContent
387 */
388 public function testHasViewableContent( $title, $viewable, $create = false ) {
389 $page = $this->newPage( $title );
390 $this->assertEquals( $viewable, $page->hasViewableContent() );
391
392 if ( $create ) {
393 $this->createPage( $page, "some text", CONTENT_MODEL_WIKITEXT );
394 $this->assertTrue( $page->hasViewableContent() );
395
396 $page = new WikiPage( $page->getTitle() );
397 $this->assertTrue( $page->hasViewableContent() );
398 }
399 }
400
401 public static function provideGetRedirectTarget() {
402 return array(
403 array( 'WikiPageTest_testGetRedirectTarget_1', CONTENT_MODEL_WIKITEXT, "hello world", null ),
404 array( 'WikiPageTest_testGetRedirectTarget_2', CONTENT_MODEL_WIKITEXT, "#REDIRECT [[hello world]]", "Hello world" ),
405 );
406 }
407
408 /**
409 * @dataProvider provideGetRedirectTarget
410 */
411 public function testGetRedirectTarget( $title, $model, $text, $target ) {
412 $page = $this->createPage( $title, $text, $model );
413
414 # sanity check, because this test seems to fail for no reason for some people.
415 $c = $page->getContent();
416 $this->assertEquals( 'WikitextContent', get_class( $c ) );
417
418 # now, test the actual redirect
419 $t = $page->getRedirectTarget();
420 $this->assertEquals( $target, is_null( $t ) ? null : $t->getPrefixedText() );
421 }
422
423 /**
424 * @dataProvider provideGetRedirectTarget
425 */
426 public function testIsRedirect( $title, $model, $text, $target ) {
427 $page = $this->createPage( $title, $text, $model );
428 $this->assertEquals( !is_null( $target ), $page->isRedirect() );
429 }
430
431 public static function provideIsCountable() {
432 return array(
433
434 // any
435 array( 'WikiPageTest_testIsCountable',
436 CONTENT_MODEL_WIKITEXT,
437 '',
438 'any',
439 true
440 ),
441 array( 'WikiPageTest_testIsCountable',
442 CONTENT_MODEL_WIKITEXT,
443 'Foo',
444 'any',
445 true
446 ),
447
448 // comma
449 array( 'WikiPageTest_testIsCountable',
450 CONTENT_MODEL_WIKITEXT,
451 'Foo',
452 'comma',
453 false
454 ),
455 array( 'WikiPageTest_testIsCountable',
456 CONTENT_MODEL_WIKITEXT,
457 'Foo, bar',
458 'comma',
459 true
460 ),
461
462 // link
463 array( 'WikiPageTest_testIsCountable',
464 CONTENT_MODEL_WIKITEXT,
465 'Foo',
466 'link',
467 false
468 ),
469 array( 'WikiPageTest_testIsCountable',
470 CONTENT_MODEL_WIKITEXT,
471 'Foo [[bar]]',
472 'link',
473 true
474 ),
475
476 // redirects
477 array( 'WikiPageTest_testIsCountable',
478 CONTENT_MODEL_WIKITEXT,
479 '#REDIRECT [[bar]]',
480 'any',
481 false
482 ),
483 array( 'WikiPageTest_testIsCountable',
484 CONTENT_MODEL_WIKITEXT,
485 '#REDIRECT [[bar]]',
486 'comma',
487 false
488 ),
489 array( 'WikiPageTest_testIsCountable',
490 CONTENT_MODEL_WIKITEXT,
491 '#REDIRECT [[bar]]',
492 'link',
493 false
494 ),
495
496 // not a content namespace
497 array( 'Talk:WikiPageTest_testIsCountable',
498 CONTENT_MODEL_WIKITEXT,
499 'Foo',
500 'any',
501 false
502 ),
503 array( 'Talk:WikiPageTest_testIsCountable',
504 CONTENT_MODEL_WIKITEXT,
505 'Foo, bar',
506 'comma',
507 false
508 ),
509 array( 'Talk:WikiPageTest_testIsCountable',
510 CONTENT_MODEL_WIKITEXT,
511 'Foo [[bar]]',
512 'link',
513 false
514 ),
515
516 // not a content namespace, different model
517 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
518 null,
519 'Foo',
520 'any',
521 false
522 ),
523 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
524 null,
525 'Foo, bar',
526 'comma',
527 false
528 ),
529 array( 'MediaWiki:WikiPageTest_testIsCountable.js',
530 null,
531 'Foo [[bar]]',
532 'link',
533 false
534 ),
535 );
536 }
537
538
539 /**
540 * @dataProvider provideIsCountable
541 */
542 public function testIsCountable( $title, $model, $text, $mode, $expected ) {
543 global $wgContentHandlerUseDB;
544
545 $this->setMwGlobals( 'wgArticleCountMethod', $mode );
546
547 $title = Title::newFromText( $title );
548
549 if ( !$wgContentHandlerUseDB && ContentHandler::getDefaultModelFor( $title ) != $model ) {
550 $this->markTestSkipped( "Can not use non-default content model $model for "
551 . $title->getPrefixedDBkey() . " with \wgArticleCountMethod disabled." );
552 }
553
554 $page = $this->createPage( $title, $text, $model );
555 $hasLinks = wfGetDB( DB_SLAVE )->selectField( 'pagelinks', 1,
556 array( 'pl_from' => $page->getId() ), __METHOD__ );
557
558 $editInfo = $page->prepareContentForEdit( $page->getContent() );
559
560 $v = $page->isCountable();
561 $w = $page->isCountable( $editInfo );
562
563 $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
564 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
565
566 $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
567 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
568 }
569
570 public static function provideGetParserOutput() {
571 return array(
572 array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>"),
573 // @todo: more...?
574 );
575 }
576
577 /**
578 * @dataProvider provideGetParserOutput
579 */
580 public function testGetParserOutput( $model, $text, $expectedHtml ) {
581 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model );
582
583 $opt = $page->makeParserOptions( 'canonical' );
584 $po = $page->getParserOutput( $opt );
585 $text = $po->getText();
586
587 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
588 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
589
590 $this->assertEquals( $expectedHtml, $text );
591 return $po;
592 }
593
594 public function testGetParserOutput_nonexisting( ) {
595 static $count = 0;
596 $count ++;
597
598 $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
599
600 $opt = new ParserOptions();
601 $po = $page->getParserOutput( $opt );
602
603 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
604 }
605
606 public function testGetParserOutput_badrev( ) {
607 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
608
609 $opt = new ParserOptions();
610 $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 );
611
612 //@todo: would be neat to also test deleted revision
613
614 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." );
615 }
616
617 static $sections =
618
619 "Intro
620
621 == stuff ==
622 hello world
623
624 == test ==
625 just a test
626
627 == foo ==
628 more stuff
629 ";
630
631
632 public function dataReplaceSection() {
633 //NOTE: assume the Help namespace to contain wikitext
634 return array(
635 array( 'Help:WikiPageTest_testReplaceSection',
636 CONTENT_MODEL_WIKITEXT,
637 WikiPageTest::$sections,
638 "0",
639 "No more",
640 null,
641 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
642 ),
643 array( 'Help:WikiPageTest_testReplaceSection',
644 CONTENT_MODEL_WIKITEXT,
645 WikiPageTest::$sections,
646 "",
647 "No more",
648 null,
649 "No more"
650 ),
651 array( 'Help:WikiPageTest_testReplaceSection',
652 CONTENT_MODEL_WIKITEXT,
653 WikiPageTest::$sections,
654 "2",
655 "== TEST ==\nmore fun",
656 null,
657 trim( preg_replace( '/^== test ==.*== foo ==/sm',
658 "== TEST ==\nmore fun\n\n== foo ==",
659 WikiPageTest::$sections ) )
660 ),
661 array( 'Help:WikiPageTest_testReplaceSection',
662 CONTENT_MODEL_WIKITEXT,
663 WikiPageTest::$sections,
664 "8",
665 "No more",
666 null,
667 trim( WikiPageTest::$sections )
668 ),
669 array( 'Help:WikiPageTest_testReplaceSection',
670 CONTENT_MODEL_WIKITEXT,
671 WikiPageTest::$sections,
672 "new",
673 "No more",
674 "New",
675 trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
676 ),
677 );
678 }
679
680 /**
681 * @dataProvider dataReplaceSection
682 */
683 public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) {
684 $this->hideDeprecated( "WikiPage::replaceSection" );
685
686 $page = $this->createPage( $title, $text, $model );
687 $text = $page->replaceSection( $section, $with, $sectionTitle );
688 $text = trim( $text );
689
690 $this->assertEquals( $expected, $text );
691 }
692
693 /**
694 * @dataProvider dataReplaceSection
695 */
696 public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) {
697 $page = $this->createPage( $title, $text, $model );
698
699 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
700 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
701
702 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
703 }
704
705 /* @todo FIXME: fix this!
706 public function testGetUndoText() {
707 global $wgDiff3;
708
709 wfSuppressWarnings();
710 $haveDiff3 = $wgDiff3 && file_exists( $wgDiff3 );
711 wfRestoreWarnings();
712
713 if( !$haveDiff3 ) {
714 $this->markTestSkipped( "diff3 not installed or not found" );
715 return;
716 }
717
718 $text = "one";
719 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
720 $rev1 = $page->getRevision();
721
722 $text .= "\n\ntwo";
723 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
724 $rev2 = $page->getRevision();
725
726 $text .= "\n\nthree";
727 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
728 $rev3 = $page->getRevision();
729
730 $text .= "\n\nfour";
731 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
732 $rev4 = $page->getRevision();
733
734 $text .= "\n\nfive";
735 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
736 $rev5 = $page->getRevision();
737
738 $text .= "\n\nsix";
739 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
740 $rev6 = $page->getRevision();
741
742 $undo6 = $page->getUndoText( $rev6 );
743 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
744 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
745
746 $undo3 = $page->getUndoText( $rev4, $rev2 );
747 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
748 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
749
750 $undo2 = $page->getUndoText( $rev2 );
751 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
752 $this->assertEquals( "one\n\nfive", $undo2 );
753 }
754 */
755
756 /**
757 * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason.
758 */
759 public function broken_testDoRollback() {
760 $admin = new User();
761 $admin->setName("Admin");
762
763 $text = "one";
764 $page = $this->newPage( "WikiPageTest_testDoRollback" );
765 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
766 "section one", EDIT_NEW, false, $admin );
767
768 $user1 = new User();
769 $user1->setName( "127.0.1.11" );
770 $text .= "\n\ntwo";
771 $page = new WikiPage( $page->getTitle() );
772 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
773 "adding section two", 0, false, $user1 );
774
775 $user2 = new User();
776 $user2->setName( "127.0.2.13" );
777 $text .= "\n\nthree";
778 $page = new WikiPage( $page->getTitle() );
779 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
780 "adding section three", 0, false, $user2 );
781
782 # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
783 # or not committed under some circumstances. so, make sure the last revision has the right user name.
784 $dbr = wfGetDB( DB_SLAVE );
785 $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) );
786
787 $page = new WikiPage( $page->getTitle() );
788 $rev3 = $page->getRevision();
789 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
790
791 $rev2 = $rev3->getPrevious();
792 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
793
794 $rev1 = $rev2->getPrevious();
795 $this->assertEquals( 'Admin', $rev1->getUserText() );
796
797 # now, try the actual rollback
798 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
799 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null );
800 $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin );
801
802 if ( $errors ) {
803 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
804 }
805
806 $page = new WikiPage( $page->getTitle() );
807 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
808 "rollback did not revert to the correct revision" );
809 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
810 }
811
812 /**
813 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
814 */
815 public function testDoRollback() {
816 $admin = new User();
817 $admin->setName("Admin");
818
819 $text = "one";
820 $page = $this->newPage( "WikiPageTest_testDoRollback" );
821 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
822 "section one", EDIT_NEW, false, $admin );
823 $rev1 = $page->getRevision();
824
825 $user1 = new User();
826 $user1->setName( "127.0.1.11" );
827 $text .= "\n\ntwo";
828 $page = new WikiPage( $page->getTitle() );
829 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
830 "adding section two", 0, false, $user1 );
831
832 # now, try the rollback
833 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
834 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
835 $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin );
836
837 if ( $errors ) {
838 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
839 }
840
841 $page = new WikiPage( $page->getTitle() );
842 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
843 "rollback did not revert to the correct revision" );
844 $this->assertEquals( "one", $page->getContent()->getNativeData() );
845 }
846
847 public static function provideGetAutosummary( ) {
848 return array(
849 array(
850 'Hello there, world!',
851 '#REDIRECT [[Foo]]',
852 0,
853 '/^Redirected page .*Foo/'
854 ),
855
856 array(
857 null,
858 'Hello world!',
859 EDIT_NEW,
860 '/^Created page .*Hello/'
861 ),
862
863 array(
864 'Hello there, world!',
865 '',
866 0,
867 '/^Blanked/'
868 ),
869
870 array(
871 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
872 labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et
873 ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
874 'Hello world!',
875 0,
876 '/^Replaced .*Hello/'
877 ),
878
879 array(
880 'foo',
881 'bar',
882 0,
883 '/^$/'
884 ),
885 );
886 }
887
888 /**
889 * @dataProvider provideGetAutoSummary
890 */
891 public function testGetAutosummary( $old, $new, $flags, $expected ) {
892 $this->hideDeprecated( "WikiPage::getAutosummary" );
893
894 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
895
896 $summary = $page->getAutosummary( $old, $new, $flags );
897
898 $this->assertTrue( (bool)preg_match( $expected, $summary ),
899 "Autosummary didn't match expected pattern $expected: $summary" );
900 }
901
902 public static function provideGetAutoDeleteReason( ) {
903 return array(
904 array(
905 array(),
906 false,
907 false
908 ),
909
910 array(
911 array(
912 array( "first edit", null ),
913 ),
914 "/first edit.*only contributor/",
915 false
916 ),
917
918 array(
919 array(
920 array( "first edit", null ),
921 array( "second edit", null ),
922 ),
923 "/second edit.*only contributor/",
924 true
925 ),
926
927 array(
928 array(
929 array( "first edit", "127.0.2.22" ),
930 array( "second edit", "127.0.3.33" ),
931 ),
932 "/second edit/",
933 true
934 ),
935
936 array(
937 array(
938 array( "first edit: "
939 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
940 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
941 . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
942 . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
943 ),
944 '/first edit:.*\.\.\."/',
945 false
946 ),
947
948 array(
949 array(
950 array( "first edit", "127.0.2.22" ),
951 array( "", "127.0.3.33" ),
952 ),
953 "/before blanking.*first edit/",
954 true
955 ),
956
957 );
958 }
959
960 /**
961 * @dataProvider provideGetAutoDeleteReason
962 */
963 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
964 global $wgUser;
965
966 //NOTE: assume Help namespace to contain wikitext
967 $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" );
968
969 $c = 1;
970
971 foreach ( $edits as $edit ) {
972 $user = new User();
973
974 if ( !empty( $edit[1] ) ) $user->setName( $edit[1] );
975 else $user = $wgUser;
976
977 $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
978
979 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user );
980
981 $c += 1;
982 }
983
984 $reason = $page->getAutoDeleteReason( $hasHistory );
985
986 if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) $this->assertEquals( $expectedResult, $reason );
987 else $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
988 "Autosummary didn't match expected pattern $expectedResult: $reason" );
989
990 $this->assertEquals( $expectedHistory, $hasHistory,
991 "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
992
993 $page->doDeleteArticle( "done" );
994 }
995
996 public static function providePreSaveTransform() {
997 return array(
998 array( 'hello this is ~~~',
999 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
1000 ),
1001 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1002 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1003 ),
1004 );
1005 }
1006
1007 /**
1008 * @dataProvider providePreSaveTransform
1009 */
1010 public function testPreSaveTransform( $text, $expected ) {
1011 $this->hideDeprecated( 'WikiPage::preSaveTransform' );
1012 $user = new User();
1013 $user->setName("127.0.0.1");
1014
1015 //NOTE: assume Help namespace to contain wikitext
1016 $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" );
1017 $text = $page->preSaveTransform( $text, $user );
1018
1019 $this->assertEquals( $expected, $text );
1020 }
1021
1022 }
1023