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