Merge "Support tighter rate limiting for "non-standard" thumbnails"
[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
597 $editInfo = $page->prepareContentForEdit( $page->getContent() );
598
599 $v = $page->isCountable();
600 $w = $page->isCountable( $editInfo );
601
602 $this->assertEquals( $expected, $v, "isCountable( null ) returned unexpected value " . var_export( $v, true )
603 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
604
605 $this->assertEquals( $expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export( $v, true )
606 . " instead of " . var_export( $expected, true ) . " in mode `$mode` for text \"$text\"" );
607 }
608
609 public static function provideGetParserOutput() {
610 return array(
611 array( CONTENT_MODEL_WIKITEXT, "hello ''world''\n", "<p>hello <i>world</i></p>" ),
612 // @todo more...?
613 );
614 }
615
616 /**
617 * @dataProvider provideGetParserOutput
618 * @covers WikiPage::getParserOutput
619 */
620 public function testGetParserOutput( $model, $text, $expectedHtml ) {
621 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', $text, $model );
622
623 $opt = $page->makeParserOptions( 'canonical' );
624 $po = $page->getParserOutput( $opt );
625 $text = $po->getText();
626
627 $text = trim( preg_replace( '/<!--.*?-->/sm', '', $text ) ); # strip injected comments
628 $text = preg_replace( '!\s*(</p>)!sm', '\1', $text ); # don't let tidy confuse us
629
630 $this->assertEquals( $expectedHtml, $text );
631
632 return $po;
633 }
634
635 /**
636 * @covers WikiPage::getParserOutput
637 */
638 public function testGetParserOutput_nonexisting() {
639 static $count = 0;
640 $count++;
641
642 $page = new WikiPage( new Title( "WikiPageTest_testGetParserOutput_nonexisting_$count" ) );
643
644 $opt = new ParserOptions();
645 $po = $page->getParserOutput( $opt );
646
647 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing pages." );
648 }
649
650 /**
651 * @covers WikiPage::getParserOutput
652 */
653 public function testGetParserOutput_badrev() {
654 $page = $this->createPage( 'WikiPageTest_testGetParserOutput', "dummy", CONTENT_MODEL_WIKITEXT );
655
656 $opt = new ParserOptions();
657 $po = $page->getParserOutput( $opt, $page->getLatest() + 1234 );
658
659 // @todo would be neat to also test deleted revision
660
661 $this->assertFalse( $po, "getParserOutput() shall return false for non-existing revisions." );
662 }
663
664 static $sections =
665
666 "Intro
667
668 == stuff ==
669 hello world
670
671 == test ==
672 just a test
673
674 == foo ==
675 more stuff
676 ";
677
678 public function dataReplaceSection() {
679 //NOTE: assume the Help namespace to contain wikitext
680 return array(
681 array( 'Help:WikiPageTest_testReplaceSection',
682 CONTENT_MODEL_WIKITEXT,
683 WikiPageTest::$sections,
684 "0",
685 "No more",
686 null,
687 trim( preg_replace( '/^Intro/sm', 'No more', WikiPageTest::$sections ) )
688 ),
689 array( 'Help:WikiPageTest_testReplaceSection',
690 CONTENT_MODEL_WIKITEXT,
691 WikiPageTest::$sections,
692 "",
693 "No more",
694 null,
695 "No more"
696 ),
697 array( 'Help:WikiPageTest_testReplaceSection',
698 CONTENT_MODEL_WIKITEXT,
699 WikiPageTest::$sections,
700 "2",
701 "== TEST ==\nmore fun",
702 null,
703 trim( preg_replace( '/^== test ==.*== foo ==/sm',
704 "== TEST ==\nmore fun\n\n== foo ==",
705 WikiPageTest::$sections ) )
706 ),
707 array( 'Help:WikiPageTest_testReplaceSection',
708 CONTENT_MODEL_WIKITEXT,
709 WikiPageTest::$sections,
710 "8",
711 "No more",
712 null,
713 trim( WikiPageTest::$sections )
714 ),
715 array( 'Help:WikiPageTest_testReplaceSection',
716 CONTENT_MODEL_WIKITEXT,
717 WikiPageTest::$sections,
718 "new",
719 "No more",
720 "New",
721 trim( WikiPageTest::$sections ) . "\n\n== New ==\n\nNo more"
722 ),
723 );
724 }
725
726 /**
727 * @dataProvider dataReplaceSection
728 * @covers WikiPage::replaceSection
729 */
730 public function testReplaceSection( $title, $model, $text, $section, $with, $sectionTitle, $expected ) {
731 $this->hideDeprecated( "WikiPage::replaceSection" );
732
733 $page = $this->createPage( $title, $text, $model );
734 $text = $page->replaceSection( $section, $with, $sectionTitle );
735 $text = trim( $text );
736
737 $this->assertEquals( $expected, $text );
738 }
739
740 /**
741 * @dataProvider dataReplaceSection
742 * @covers WikiPage::replaceSectionContent
743 */
744 public function testReplaceSectionContent( $title, $model, $text, $section, $with, $sectionTitle, $expected ) {
745 $page = $this->createPage( $title, $text, $model );
746
747 $content = ContentHandler::makeContent( $with, $page->getTitle(), $page->getContentModel() );
748 $c = $page->replaceSectionContent( $section, $content, $sectionTitle );
749
750 $this->assertEquals( $expected, is_null( $c ) ? null : trim( $c->getNativeData() ) );
751 }
752
753 /* @todo FIXME: fix this!
754 public function testGetUndoText() {
755 $this->checkHasDiff3();
756
757 $text = "one";
758 $page = $this->createPage( "WikiPageTest_testGetUndoText", $text );
759 $rev1 = $page->getRevision();
760
761 $text .= "\n\ntwo";
762 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section two");
763 $rev2 = $page->getRevision();
764
765 $text .= "\n\nthree";
766 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section three");
767 $rev3 = $page->getRevision();
768
769 $text .= "\n\nfour";
770 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section four");
771 $rev4 = $page->getRevision();
772
773 $text .= "\n\nfive";
774 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section five");
775 $rev5 = $page->getRevision();
776
777 $text .= "\n\nsix";
778 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ), "adding section six");
779 $rev6 = $page->getRevision();
780
781 $undo6 = $page->getUndoText( $rev6 );
782 if ( $undo6 === false ) $this->fail( "getUndoText failed for rev6" );
783 $this->assertEquals( "one\n\ntwo\n\nthree\n\nfour\n\nfive", $undo6 );
784
785 $undo3 = $page->getUndoText( $rev4, $rev2 );
786 if ( $undo3 === false ) $this->fail( "getUndoText failed for rev4..rev2" );
787 $this->assertEquals( "one\n\ntwo\n\nfive", $undo3 );
788
789 $undo2 = $page->getUndoText( $rev2 );
790 if ( $undo2 === false ) $this->fail( "getUndoText failed for rev2" );
791 $this->assertEquals( "one\n\nfive", $undo2 );
792 }
793 */
794
795 /**
796 * @todo FIXME: this is a better rollback test than the one below, but it keeps failing in jenkins for some reason.
797 */
798 public function broken_testDoRollback() {
799 $admin = new User();
800 $admin->setName( "Admin" );
801
802 $text = "one";
803 $page = $this->newPage( "WikiPageTest_testDoRollback" );
804 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
805 "section one", EDIT_NEW, false, $admin );
806
807 $user1 = new User();
808 $user1->setName( "127.0.1.11" );
809 $text .= "\n\ntwo";
810 $page = new WikiPage( $page->getTitle() );
811 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
812 "adding section two", 0, false, $user1 );
813
814 $user2 = new User();
815 $user2->setName( "127.0.2.13" );
816 $text .= "\n\nthree";
817 $page = new WikiPage( $page->getTitle() );
818 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle() ),
819 "adding section three", 0, false, $user2 );
820
821 # we are having issues with doRollback spuriously failing. apparently the last revision somehow goes missing
822 # or not committed under some circumstances. so, make sure the last revision has the right user name.
823 $dbr = wfGetDB( DB_SLAVE );
824 $this->assertEquals( 3, Revision::countByPageId( $dbr, $page->getId() ) );
825
826 $page = new WikiPage( $page->getTitle() );
827 $rev3 = $page->getRevision();
828 $this->assertEquals( '127.0.2.13', $rev3->getUserText() );
829
830 $rev2 = $rev3->getPrevious();
831 $this->assertEquals( '127.0.1.11', $rev2->getUserText() );
832
833 $rev1 = $rev2->getPrevious();
834 $this->assertEquals( 'Admin', $rev1->getUserText() );
835
836 # now, try the actual rollback
837 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
838 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user2->getName() ), null );
839 $errors = $page->doRollback( $user2->getName(), "testing revert", $token, false, $details, $admin );
840
841 if ( $errors ) {
842 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
843 }
844
845 $page = new WikiPage( $page->getTitle() );
846 $this->assertEquals( $rev2->getSha1(), $page->getRevision()->getSha1(),
847 "rollback did not revert to the correct revision" );
848 $this->assertEquals( "one\n\ntwo", $page->getContent()->getNativeData() );
849 }
850
851 /**
852 * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
853 * @covers WikiPage::doRollback
854 */
855 public function testDoRollback() {
856 $admin = new User();
857 $admin->setName( "Admin" );
858
859 $text = "one";
860 $page = $this->newPage( "WikiPageTest_testDoRollback" );
861 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
862 "section one", EDIT_NEW, false, $admin );
863 $rev1 = $page->getRevision();
864
865 $user1 = new User();
866 $user1->setName( "127.0.1.11" );
867 $text .= "\n\ntwo";
868 $page = new WikiPage( $page->getTitle() );
869 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
870 "adding section two", 0, false, $user1 );
871
872 # now, try the rollback
873 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
874 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
875 $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $details, $admin );
876
877 if ( $errors ) {
878 $this->fail( "Rollback failed:\n" . print_r( $errors, true ) . ";\n" . print_r( $details, true ) );
879 }
880
881 $page = new WikiPage( $page->getTitle() );
882 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
883 "rollback did not revert to the correct revision" );
884 $this->assertEquals( "one", $page->getContent()->getNativeData() );
885 }
886
887 /**
888 * @covers WikiPage::doRollback
889 */
890 public function testDoRollbackFailureSameContent() {
891 $admin = new User();
892 $admin->setName( "Admin" );
893 $admin->addGroup( "sysop" ); #XXX: make the test user a sysop...
894
895 $text = "one";
896 $page = $this->newPage( "WikiPageTest_testDoRollback" );
897 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
898 "section one", EDIT_NEW, false, $admin );
899 $rev1 = $page->getRevision();
900
901 $user1 = new User();
902 $user1->setName( "127.0.1.11" );
903 $user1->addGroup( "sysop" ); #XXX: make the test user a sysop...
904 $text .= "\n\ntwo";
905 $page = new WikiPage( $page->getTitle() );
906 $page->doEditContent( ContentHandler::makeContent( $text, $page->getTitle(), CONTENT_MODEL_WIKITEXT ),
907 "adding section two", 0, false, $user1 );
908
909 # now, do a the rollback from the same user was doing the edit before
910 $resultDetails = array();
911 $token = $user1->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
912 $errors = $page->doRollback( $user1->getName(), "testing revert same user", $token, false, $resultDetails, $admin );
913
914 $this->assertEquals( array(), $errors, "Rollback failed same user" );
915
916 # now, try the rollback
917 $resultDetails = array();
918 $token = $admin->getEditToken( array( $page->getTitle()->getPrefixedText(), $user1->getName() ), null );
919 $errors = $page->doRollback( $user1->getName(), "testing revert", $token, false, $resultDetails, $admin );
920
921 $this->assertEquals( array( array( 'alreadyrolled', 'WikiPageTest testDoRollback',
922 '127.0.1.11', 'Admin' ) ), $errors, "Rollback not failed" );
923
924 $page = new WikiPage( $page->getTitle() );
925 $this->assertEquals( $rev1->getSha1(), $page->getRevision()->getSha1(),
926 "rollback did not revert to the correct revision" );
927 $this->assertEquals( "one", $page->getContent()->getNativeData() );
928 }
929
930 public static function provideGetAutosummary() {
931 return array(
932 array(
933 'Hello there, world!',
934 '#REDIRECT [[Foo]]',
935 0,
936 '/^Redirected page .*Foo/'
937 ),
938
939 array(
940 null,
941 'Hello world!',
942 EDIT_NEW,
943 '/^Created page .*Hello/'
944 ),
945
946 array(
947 'Hello there, world!',
948 '',
949 0,
950 '/^Blanked/'
951 ),
952
953 array(
954 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut
955 labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et
956 ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
957 'Hello world!',
958 0,
959 '/^Replaced .*Hello/'
960 ),
961
962 array(
963 'foo',
964 'bar',
965 0,
966 '/^$/'
967 ),
968 );
969 }
970
971 /**
972 * @dataProvider provideGetAutoSummary
973 * @covers WikiPage::getAutosummary
974 */
975 public function testGetAutosummary( $old, $new, $flags, $expected ) {
976 $this->hideDeprecated( "WikiPage::getAutosummary" );
977
978 $page = $this->newPage( "WikiPageTest_testGetAutosummary" );
979
980 $summary = $page->getAutosummary( $old, $new, $flags );
981
982 $this->assertTrue( (bool)preg_match( $expected, $summary ),
983 "Autosummary didn't match expected pattern $expected: $summary" );
984 }
985
986 public static function provideGetAutoDeleteReason() {
987 return array(
988 array(
989 array(),
990 false,
991 false
992 ),
993
994 array(
995 array(
996 array( "first edit", null ),
997 ),
998 "/first edit.*only contributor/",
999 false
1000 ),
1001
1002 array(
1003 array(
1004 array( "first edit", null ),
1005 array( "second edit", null ),
1006 ),
1007 "/second edit.*only contributor/",
1008 true
1009 ),
1010
1011 array(
1012 array(
1013 array( "first edit", "127.0.2.22" ),
1014 array( "second edit", "127.0.3.33" ),
1015 ),
1016 "/second edit/",
1017 true
1018 ),
1019
1020 array(
1021 array(
1022 array( "first edit: "
1023 . "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam "
1024 . " nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. "
1025 . "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea "
1026 . "takimata sanctus est Lorem ipsum dolor sit amet.'", null ),
1027 ),
1028 '/first edit:.*\.\.\."/',
1029 false
1030 ),
1031
1032 array(
1033 array(
1034 array( "first edit", "127.0.2.22" ),
1035 array( "", "127.0.3.33" ),
1036 ),
1037 "/before blanking.*first edit/",
1038 true
1039 ),
1040
1041 );
1042 }
1043
1044 /**
1045 * @dataProvider provideGetAutoDeleteReason
1046 * @covers WikiPage::getAutoDeleteReason
1047 */
1048 public function testGetAutoDeleteReason( $edits, $expectedResult, $expectedHistory ) {
1049 global $wgUser;
1050
1051 //NOTE: assume Help namespace to contain wikitext
1052 $page = $this->newPage( "Help:WikiPageTest_testGetAutoDeleteReason" );
1053
1054 $c = 1;
1055
1056 foreach ( $edits as $edit ) {
1057 $user = new User();
1058
1059 if ( !empty( $edit[1] ) ) {
1060 $user->setName( $edit[1] );
1061 } else {
1062 $user = $wgUser;
1063 }
1064
1065 $content = ContentHandler::makeContent( $edit[0], $page->getTitle(), $page->getContentModel() );
1066
1067 $page->doEditContent( $content, "test edit $c", $c < 2 ? EDIT_NEW : 0, false, $user );
1068
1069 $c += 1;
1070 }
1071
1072 $reason = $page->getAutoDeleteReason( $hasHistory );
1073
1074 if ( is_bool( $expectedResult ) || is_null( $expectedResult ) ) {
1075 $this->assertEquals( $expectedResult, $reason );
1076 } else {
1077 $this->assertTrue( (bool)preg_match( $expectedResult, $reason ),
1078 "Autosummary didn't match expected pattern $expectedResult: $reason" );
1079 }
1080
1081 $this->assertEquals( $expectedHistory, $hasHistory,
1082 "expected \$hasHistory to be " . var_export( $expectedHistory, true ) );
1083
1084 $page->doDeleteArticle( "done" );
1085 }
1086
1087 public static function providePreSaveTransform() {
1088 return array(
1089 array( 'hello this is ~~~',
1090 "hello this is [[Special:Contributions/127.0.0.1|127.0.0.1]]",
1091 ),
1092 array( 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1093 'hello \'\'this\'\' is <nowiki>~~~</nowiki>',
1094 ),
1095 );
1096 }
1097
1098 /**
1099 * @dataProvider providePreSaveTransform
1100 * @covers WikiPage::preSaveTransform
1101 */
1102 public function testPreSaveTransform( $text, $expected ) {
1103 $this->hideDeprecated( 'WikiPage::preSaveTransform' );
1104 $user = new User();
1105 $user->setName( "127.0.0.1" );
1106
1107 //NOTE: assume Help namespace to contain wikitext
1108 $page = $this->newPage( "Help:WikiPageTest_testPreloadTransform" );
1109 $text = $page->preSaveTransform( $text, $user );
1110
1111 $this->assertEquals( $expected, $text );
1112 }
1113
1114 /**
1115 * @covers WikiPage::factory
1116 */
1117 public function testWikiPageFactory() {
1118 $title = Title::makeTitle( NS_FILE, 'Someimage.png' );
1119 $page = WikiPage::factory( $title );
1120 $this->assertEquals( 'WikiFilePage', get_class( $page ) );
1121
1122 $title = Title::makeTitle( NS_CATEGORY, 'SomeCategory' );
1123 $page = WikiPage::factory( $title );
1124 $this->assertEquals( 'WikiCategoryPage', get_class( $page ) );
1125
1126 $title = Title::makeTitle( NS_MAIN, 'SomePage' );
1127 $page = WikiPage::factory( $title );
1128 $this->assertEquals( 'WikiPage', get_class( $page ) );
1129 }
1130 }