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