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