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