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